понедельник, 31 декабря 2012 г.

Netbeans 7.2.1 change user interface language

I've setup a Netbeans IDE 7.2.1 and by default it's user interface uses your system language. Sometimes it's good, but i prefer to see the IDE in English.

So, let's fix it. Open the <netbeans_install_dir>/etc/netbeans.conf and change the line netbeans_default_options. Append to the end of it "-J-Duser.language=en -J-Duser.region=US". Restart your IDE and you will see english interface.

четверг, 27 декабря 2012 г.

Make friends: Apache CXF client + WSS4J + CryptoPro

Many of you who worked with government webservices know that the information passed to the service should be signed with GOST algorithm. This leads to the use of CryptoPro library. So here is the interesting part. What I have:
  1. jdk 1.6.0.38 + JCP CryptoPro
  2. ready to use keystore
  3. wss4j 1.6.6
  4. apache cxf 2.6.1 
  5. XMLDSigRI.jar
Generate the client to webservice.
Then, configure the crypto.properties file for wss4j: org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=HDImageStore
org.apache.ws.security.crypto.merlin.keystore.password=1234567890
org.apache.ws.security.crypto.merlin.keystore.alias=tester
org.apache.ws.security.crypto.merlin.keystore.file=c:/cert.store

Then, configure your client:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
          http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://cxf.apache.org/jaxws 
          http://cxf.apache.org/schemas/jaxws.xsd">
 <!-- The SOAP client bean -->
  <jaxws:client id="client"
                serviceClass="ru.my.IService"
                address="http://test/IService/IdentificationService.svc">
    <jaxws:inInterceptors>
      <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
    </jaxws:inInterceptors>
     <jaxws:outInterceptors>
         <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
         <ref bean="wss4jOutConfiguration" /> 
     </jaxws:outInterceptors>
   </jaxws:client>
 <bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
  <property name="properties">
  <map>
  <entry key="action" value="Signature"/>
  <entry key="signaturePropFile" value="crypto.properties"/>
  <entry key="signatureKeyIdentifier" value="DirectReference"/>  
  <entry key="user" value="tester"/> 
  <entry key="signatureUser" value="tester"/>
  <entry key="passwordCallbackClass" value="ru.client.KeystorePasswordCallback"></entry> 
     <entry key="signatureDigestAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
        <entry key="signatureAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/>       
      </map>
  </property>
</bean>
</beans>

Everything seems good, but your client won't work.
Here is the example of client:
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});

        ru.IService client = (ru.IService) context.getBean("client");

        ru.CryptoPro.JCPxml.XmlInit.init();

        if(!JCPXMLDSigInit.isInitialized()){
            JCPXMLDSigInit.init();
        }

        Result res = client.callMethod(123);


For this to work I had to patch WSS4j. Download the sources for WSS4j 1.6.6 and edit the file org.apache.ws.security.message.WSSecSignature.java. Find the init method and replace it with this code:
  private void init() {
        Provider xmlDSigProvider = new ru.CryptoPro.JCPxml.dsig.internal.dom.XMLDSigRI();
        signatureFactory = XMLSignatureFactory.getInstance("DOM", xmlDSigProvider);//XMLSignatureFactory.getInstance("DOM");
        keyInfoFactory = KeyInfoFactory.getInstance("DOM", xmlDSigProvider);
    }

       
Compile the file and add the compiled class to the wss4j jar.
After this, I could successfully run the client.

вторник, 25 декабря 2012 г.

Server side browser detection

Recently, I've been faced with the task to detect user's devices browsers and redirect users to the different sites accordingly.
So, I've  made a search and found out this script for HTTP server (http://detectmobilebrowsers.com/). This script detects many mobile browsers, even my old symbian E52 was detected.
IPad devices are not detected. It's up to you to decide weather should your users be redirected to the mobile versions of your site. So, the real problem for me is how to detect iPad mini?
Http user agent for iPad 2 and iPad mini are the same. You can check the blog here (http://www.mobilexweb.com/blog/ipad-mini-detection-for-html5-user-agent). If anybody can find the solution to this problem, please, share your knowledge.

четверг, 25 октября 2012 г.

Mixin multiple JVM languages in the enterprise

It is interesting, has anybody tried to mixin multiple languages in the enterprise java project?

Scala, Closure, jRuby or others? 
Did it really help to speedup the the development and support?

пятница, 12 октября 2012 г.

Tomcat 6. Remove version information from error pages.

When Tomcat 6 encounters error like 404 it displays the error page which also reveals Tomcat version. It is bad in production, because some people can attack vulnerabilities in software. So, to make this task difficult it is better to mimic the version information in error page.

In your CATALINA_BASE\lib directory create dirs org/apache/catalina/util. Then, create the file ServerInfo.properties with the following properties:
server.info=Apache
server.number=1.2.3.4
server.built=18 nov 2012 23:59:59
 
Restart the Tomcat. Now Tomcat error pages won't contain version information.

Question to readers

Hi folks! I need your help. Does anybody of you knows the Java User Group in Moscow? I would like to join in to exchange the experience.

I know Google has video presentations from their java related meetings. Are there any meetings like this are held in Moscow?

вторник, 2 октября 2012 г.

понедельник, 1 октября 2012 г.

Spring и сервлеты. Инъектирование бинов.

Порой очень хочется, чтобы при создании сервлета автоматически инъектировались бины Spring.
Однако стоит отметить важную особенность, что жизненным циклов бинов управляет Spring, а жизненным циклом сервлета управляет контейнер сервлетов.  По этой причине автоматически инъектировать бины в сервлет не получится.



Есть альтернативное решение. Spring содержит интерфейс
org.springframework.web.HttpRequestHandler. В этом интерфейсе есть метод handleRequest(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response). Фактически это один в один метод service сервлета. Мы портируем наш сервлет так, что класс реализует данный интерфейс. Этот класс мы объявляем в spring. Далее в web.xml мы создаём описание сервлета. При этом имя сервлета должно совпадать с именем определённого бина spring, а класс сервлета - org.springframework.web.context.support.HttpRequestHandlerServlet.

Как результат - наш сервлет содержит инъектированные бины spring.

Аналогичное решение есть и для фильтров сервлета. Только в этом случае класс называется org.springframework.web.filter.DelegatingFilterProxy.

суббота, 22 сентября 2012 г.

Установка приложений на Tomcat с помощью ant.

При разработке приложения для работы на Tomcat очень удобной возможностью является установка приложения на Tomcat с помошью скрипта ant.
Удобство заключается в небольшом количестве действий, которое необходимо для установки приложения.
Установку можно выполнить на любой сервер, локальный или удалённый.

Почитать об этом можно в руководстве на Tomcat, но для удобства опишу основные моменты здесь:

1) Необходимо скопировать файл server/lib/catalina-ant.jar из Tomcat в каталог с библиотеками ant ($ANT_HOME/lib).
2) В Tomcat прописать учётную запись для пользователя manager-script.
3) В ant скрипте необходимо объявить задачи tomcat и параметры установки приложения:
<!-- Configure the directory into which the web application is built -->
    <property name="build"    value="dist"/>
    <!-- Configure the context path for this application -->
      <property name="path"     value="/test"/>

      <!-- Configure properties to access the Manager application -->
      <property name="url"      value="http://localhost:8080/manager"/>
      <property name="username" value="duglas"/>
      <property name="password" value="password"/>

      <!-- Configure the custom Ant tasks for the Manager application -->
      <taskdef name="deploy"    classname="org.apache.catalina.ant.DeployTask" />
      <taskdef name="undeploy"  classname="org.apache.catalina.ant.UndeployTask"/>

   
<target name="deploy" description="Install web application"
              depends="war">
        <deploy url="${url}" username="${username}" password="${password}"
                path="${path}" war="file:${build}/springwstest.war"/>
      </target>

  <target name="undeploy" description="Remove web application">
        <undeploy url="${url}" username="${username}" password="${password}"
                path="${path}"/>
      </target>

4) После этого можно вызывать нужную цель, и приложение будет установлено на сервере. Вызов цели undeploy влечёт за собой удаление приложение на сервере.

Spring Web Services. Тестирование клиента к веб-сервису.

Автономное тестирование клиента к веб-сервису без самого сервиса позволяет получить уверенность в том, что клиент работает как в стандартных ситуациях, так и не очень.
К стандартным ситуациям следует отнести ситуацию, когда сервис выдаёт ожидаемый ответ.
К нестандартным ситуациям следуюет отнести ситацию, когда сервис выдает исключение.

В нашем распоряжении есть следующее ПО:
  1. jUnit 4.10
  2. Spring WS 2.1.0 
  3. Eclipse
Рассмотрим следующий пример сервиса. На вход принимается две строки, на выходе выдаётся их склейка. Для тестирования клиента используется класс MockWebServiceServer. Перед вызовом клиента нам необходимо установить последовательность пар вызовов и ответов веб-сервиса.

Это осуществляется в строке: mockServer.expect(RequestMatchers.payload(expectedRequestPayload)).andRespond(ResponseCreators.withPayload(responsePayload)); 

Далее мы осуществляем вызов нашего клиента к веб-сервису, и в конце теста
вызываем метод mockServer.verify(). Этот метод проверяет, что веб-сервис получил все ожидаемые запросы от клиента. Если какие-то запросы не пришли, то unit тест не пройдёт.

За более подробным описанием предлагаю обратиться к описанию класса MockWebServiceServer.
Также можно прогнать пример ниже.

 @RunWith(SpringJUnit4ClassRunner.class)  
 @ContextConfiguration("/context.xml")  
 public class MyWebServiceClientIntegrationTest {  
   @Resource(name="webServiceTemplate")  
   org.springframework.ws.client.core.WebServiceTemplate webServiceTemplate;  
   private MockWebServiceServer mockServer;  
   @Before  
   public void createServer() throws Exception {  
     mockServer = MockWebServiceServer.createServer(webServiceTemplate);  
   }  
   @Test  
   public void testExpected() throws Exception {  
     String request = "<ConcatRequest xmlns=\"http://www.chernykh.ru/myfirst\">"+  
         "<p1>1</p1>"+  
         "<p2>2</p2>"+  
         "</ConcatRequest>";  
     String request2 = "<ConcatRequest xmlns=\"http://www.chernykh.ru/myfirst\">"+  
         "<p1>1</p1>"+  
         "<p2>2</p2>"+  
         "</ConcatRequest>";  
     String response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ConcatResponse xmlns=\"http://www.chernykh.ru/myfirst\"><out>12</out></ConcatResponse>";  
     Source expectedRequestPayload =  
         new StringSource(request);  
     Source responsePayload = new StringSource(response);  
     mockServer.expect(RequestMatchers.payload(expectedRequestPayload)).andRespond(ResponseCreators.withPayload(responsePayload));  
     ByteArrayOutputStream output = new ByteArrayOutputStream();   
     StreamResult result = new StreamResult(output);  
     String uri = "http://localhost:8080/test/service";  
     webServiceTemplate.sendSourceAndReceiveToResult(uri,new StringSource(request2), result);  
     String resultStr = "";   
     resultStr = new String(output.toByteArray(), UTF_8.utf8);  
     mockServer.verify();  
     System.out.println("Finished:"+resultStr);  
   }  
 }  

вторник, 18 сентября 2012 г.

Spring + MongoDB + Eclipse. Проблема с spring-mongo-1.0.xsd.


При использовани Spring + Mongo в Eclipse последний ругается на файл с бинами Spring.

<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mongo="http://www.springframework.org/schema/data/mongo"
          xsi:schemaLocation=
          "http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/data/mongo
          http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

Детальная ошибка говорит: "Cannot resolve the name 'repository:repository' to a(n) 'type definition' component" вspring-mongo-1.0.xsd.

Решение нашёл в замечательной заметке: http://stackoverflow.com/questions/11684673/spring-mongo-1-0-xsd-error.

Нужно изменить   http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd на
  http://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd. После этого eclipse перестанет ругаться на проект.

воскресенье, 9 сентября 2012 г.

Spring + MongoDb. Первое знакомство.

В одном из моих проектов мне понадобилось использовать mongodb в качестве хранилища данных сессии пользователя.

Для работы на java с mongodb можно использовать java драйвер. Это довольно утомительное занятие. Поэтому я нашёл интересный проект spring-data-mongodb, который позволяет упростить работу с mongodb.

суббота, 8 сентября 2012 г.

Spring ws 2.1.0 и Http components 4.2.1. Обработка исключений.

При создании клиентов к веб-сервисам с помощью Spring Web Services и Http components возникает вопрос - как обрабатывать исключения?

Речь идёт об исключениях, которые возникают при установке socket timeout или connection timeout в классе org.apache.http.params.SyncBasicHttpParams. 

При исполнении метода     template.sendSourceAndReceiveToResult(uri, source,result ); может возникнуть исключение, однако сигнатура данного метода не содержит исключений.

Поэтому для корректной работы приложения можно просто обернуть этот метод в try catch конструкцию, таким образом вызов клиента будет выглядить следующим образом:

try{
       template.sendSourceAndReceiveToResult(uri, source,result );
}catch (IOException ex){
     //делаем необходимую обработку исключения
}

Второй вариант, это добавить throws IOException в объявление метода, который использует вызов клиента к веб-сервису.


Кодировки и класс Charset

Иногда приходится работать с кодировками, в частности, преобразовывать бинарные данные в строковые. Для этого можно использовать класс Charset.

Можно было подумать, что в JVM есть удобные константы для кодировки UTF-8, но вместо этого предлагается использовать Charset.forName(). Плохо, что этот метод выкидывает 3 исключения. В java версии 7 нам дают в распоряжение новый класс StandardCharsets. Данный класс предлагает ряд кодировок, которые ГАРАНТИРОВАННО поддерживаются на каждой реализации JVM. Данный класс имеет static Charset UTF_8.  

В принципе никто не мешает написать такой класс самому.
Расстраивает одно, почему такой вспомогательный класс появился только в 7 версии машины? 

воскресенье, 2 сентября 2012 г.

Сравнение Apache CXF и Spring WS

-->
Попробуем сравнить 2 известных фреймворка для написания веб-сервисов и клиентов к ним.
К этим фреймворкам относятся: Spring Web Services, Apache CXF.

Проект Apache CXF активно развивается, в то время как Spring WS представляет собой законченное решение. Архитектура Spring WS довольно простая, что при желании позволит разобраться в её исходном коде и поправить замеченные ошибки.
Я знаком с обоими фреймворками, но испробовал не все их возможности. Сравнение представлено в таблице ниже и представляет собой попытку свести информацию в табличный вид.
По итогам сравнения можно сказать следующее:
  1. Apache CXF обладает большим количеством возможностей по сравнению с Spring WS.
  2. В проекте, когда интерфейс WSDL довольно часто меняется, то проще использовать Spring WS.
  3. Обе библиотеки довольно просты в освоении, однако с CXF много времени можно потратить на настройке.
  4. Следует отметить, что с обоими библиотеками поставляется набор примеров.
  5. Выбор в пользу той или иной библиотеки необходимо делать исходя из требований к проекту, а также исходя из приверженности работы по стандарту JAX-WS.



Spring WS
Apache CXF
Поддержка разработки типов сервисов
сверху-вниз
сверху-вниз, снизу-вверх.
Обработка входящих сообщений
DOM, SAX, StAX, JDOMs, dom4j, XOM, JAXB, Castor, Apache XMLBeans, XStream. Определение обработчика входящего XML запроса на основе запроса, заголовка SOAP Action или Xpath выражения.
DOM, SAX, StAX, InputStream, JAXB 2.x, Aegis, Apache XMLBeans, Service Data Objects (SDO), JiBX.
Поддержка спецификаций
WS-Security, WS-Addressing.
Интеграция с Acegi Security.
JAX-WS, JAX-RS, WS-Basic Profile, WS-Addressing, WS-Policy, WS-Reliable Messaging, WS-Security, WS-SecurityPolicy, WS-SecureConversation, WS-Trust (partial support).
Поддержка транспорта
JMS, Email, XMPP, HTTP, Embedded HTTP.
HTTP, Servlet, JMS, In-VM and many others via the Camel transport for CXF such as SMTP/POP3, TCP and Jabber.
Документация
Неплохая, есть tutorial.
Простота в использовании.
Крайне разрозненная. Трудно понять с чего стоит начинать, и где найти нужную информацию.
Наличие инструментов
Отсутствует.
  • генераторы кода WSDL to Java, WSDL to JavaScript, Java to JavaScript,
  • генераторы WSDL Java to WSDL, XSD to WSDL, IDL to WSDL, WSDL to XML
  • проверка WSDL.
Версионность сервисов
Через XSLT преобразование запроса. Возможность быстрого внесения изменений в интерфейс сервиса, что полезно при изменяющемся контракте.
Написание собственного перехватчика (http://cxf.apache.org/docs/service-routing.html).
Клиенты
Простой синхронный клиент, интеграция с http client.
Возможность создания клиента на javascript, асинхронного клиента.
Отказоустойчивость
Необходимо придумывать самому.
Возможность создания клиентов, использующих возможность работы с другим сервисом в случае отказа сервера.
Управление
Отсутствует
Поддержка JMX.
Тестирование сервисов
Поддержка для тестирования клиентов и сервисов.
Необходимо писать самому. Можно использовать локальный или in-VM транспорт.
Интеграция с IDE
Отсутствует.
Интеграция с Eclipse.


воскресенье, 26 августа 2012 г.

Apache CXF 2.6.1. Mapping xsd:dateTime to java.util.Date

Задумался я, как бы мне сделать отображение xsd:dateTime на класс java.util.Date. С ним просто удобнее работать.

Решение оказалось простым - нужно при генерации классов с помощью wsdl2java указать jaxb binding. В этом файле можно указать свои правила отображения. После небольшого иследования я привёл файл к следующему виду:
<jxb:bindings version="2.0"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <jxb:bindings schemaLocation="file:/home/duglas/workspacejuno/WsTimeService2/wsdl/businessTime_schema.xsd"  node="/xs:schema">
    <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <jxb:javaType name="java.util.Date" xmlType="xs:dateTime"
                    parseMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDateTime"
                    printMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.printDateTime"/>
    </jxb:globalBindings>
  </jxb:bindings>
</jxb:bindings>

С виду ничего необычного. На сайте apache cxf приводится почти такой же файл. Ключевое слово здесь - почти, так как в версии 2.6.1 разработчики переместили класс DataTypeAdapter  в пакет org.apache.cxf.xjc.runtime.

вторник, 21 августа 2012 г.

Apache cxf 2.6.1 и Eclipse (part 2)

В этой части я решил избавиться от зависимости в виде Eclipse и научиться генерировать веб-сервис с помощью CXF.

суббота, 18 августа 2012 г.

понедельник, 13 августа 2012 г.

Ant. Первое знакомство.


Функции Ant:
1) компиляция
2) junit тесты
3) junit отчёты
4) проверка кода на соответствие стилю программирования checkstyle (http://checkstyle.sourceforge.net)
5) создание jar\war файла
6) создания meta-inf файла
7) создание javadoc
8) генерация классов для клиента к веб-сервису с помощью wsdl2java (из пакета apache cxf)
9) выполнение sql скриптов к СУБД
10) установка war файла на сервер приложений, например Tomcat

Можно ли заменить билдер в Eclipse и оставить только ant?
В Eclipse невозможно полностью отключить встроенный builder проекта, поэтому в данном случае исполнение задачи javac не будет иметь смысл.

Состав целей проекта:
default - цель по умолчанию
all - создание дистрибутива и тестирование
clean - удаление всех созданных файлов
dist - создание дистрибутива
docs - создание документации
test - запуск unit тестов
noop - вывод на экран названия проекта
diag - вывод параметров окружения ant.


Управление большими проектами:
С помощью задачи ant можно вызывать цели в других build файлах. Начиная с версии 1.7 появилась задача subant, которая может исполнять build файлы.

суббота, 21 июля 2012 г.

Клиент Spring ws 2.1.0 + http components 4.2.1

В данном заметке я напишу о том, как мне удалось заставить работать связку из Spring ws 2.1.0 и http components 4.2.1.

Итак, начну с конфига:

    <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">  
   <property name="messageSenders"> 
      <list> 
       <ref bean="httpSender" /> 
      </list> 
     </property>
 </bean>

 <!-- http sender configuration -->
 <bean id="httpSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender"> 
    <constructor-arg> 
     <ref bean="httpClient"/> 
    </constructor-arg> 
   </bean>   
  <!-- http client definition -->
   <bean id="httpClient" class="ru.chernykh.MyDefaultHttpClient">
   <constructor-arg>
    <ref bean="connmanager"/>
   </constructor-arg> 
    <property name="params" ref="httpParams" />
   </bean>
 <!-- http params definition -->
   <bean id="httpParams" class="org.apache.http.params.SyncBasicHttpParams"/>

   <!-- setup thread-safe connection manager -->
   <bean id="connmanager" class="org.apache.http.impl.conn.PoolingClientConnectionManager" destroy-method="shutdown">
    <property name="maxTotal" value="100"></property>
    <property name="defaultMaxPerRoute" value="100"></property>
   </bean>  
   <!--  connection manager params  --> 
  <bean id="connParams" class="org.apache.http.params.HttpConnectionParamBean">
   <constructor-arg>
    <ref bean="httpParams"/>
   </constructor-arg>
    <property name="soTimeout" value="10000"></property>
  </bean>
  
Здесь всё стандартно за исключением бина httpClient. По умолчанию, если мы будем использовать DefaultHttpClient, то получим ошибку исполнения:
"Content-Length header already present".  Это означает, что httpclient пытается поставить заголовок в надежде что его нет, но это не так, поэтому получаем исключение.

Класс ru.chernykh.MyDefaultHttpClient выглядит так:
public class MyDefaultHttpClient extends DefaultHttpClient{

    protected BasicHttpProcessor createHttpProcessor() {
        BasicHttpProcessor processor = super.createHttpProcessor();
        processor.addInterceptor(new RemoveHttpHeadersInterceptor(), 0);
        return processor;
    }

    public MyDefaultHttpClient(org.apache.http.impl.conn.PoolingClientConnectionManager connManager){
        super(connManager);
    }
}
А класс RemoveHttpHeadersInterceptor следующим образом:
public class RemoveHttpHeadersInterceptor implements HttpRequestInterceptor{

    public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
        if (request instanceof HttpEntityEnclosingRequest) {
            if (request.containsHeader(HTTP.TRANSFER_ENCODING)) {
                request.removeHeaders(HTTP.TRANSFER_ENCODING);
            }
            if (request.containsHeader(HTTP.CONTENT_LEN)) {
                request.removeHeaders(HTTP.CONTENT_LEN);
            }
        }
    }
}
После этого, клиент заработал, и ошибок не было.

Хочу обратить внимание, что по умолчанию в классе
org.springframework.ws.transport.http.HttpComponentsMessageSender используется deprecated API http components(рекомендую взглянуть в исходниках). Поэтому лучше потратить время на ручную установку параметров httpClient, как это сделал я.

понедельник, 16 июля 2012 г.

Linux mint 13 & медленный wi-fi

Итак, после непродолжительной работы по wi-fi скорость соединения резко падает, хотя очевидных причин к этому нет. В моём случае проблема оказалась решаема не на клиенте, а на маршрутизаторе: в настройках необходимо изменить скорость соединения wi-fi с auto на 54 мбит\с. После этого скорость соединения wi-fi возрасла к прежним значениям.

Клиент Spring WS 2.1.0 и HTTP components

В документации к Spring WS сказано: хотите использовать apache http client, тогда используйте класс CommonsHttpMessageSender и будет вам счастье. При этом вы ограничены использованием только Apache http client 3.1.

Теперь смотрим java doc и видим, что CommonsHttpMessageSender In favor of HttpComponentsMessageSender. При этом последний уже работает с http client 4.

Такое чувство, что меня надули...
С 4 версией я ещё не работал.

четверг, 12 июля 2012 г.

WRT54GL и IPTV

В этой заметке кратко опишу настройку IPTV для корректной работы на на маршрутизаторе LinkSys wrt54gl v1.1.

При написании статьи руководствовался источниками:
  • http://www.tradetelecom.ru/home-office/podrobnaya-nastroyka-routera-linksys-wrt54gl-s-dd-wrt-i-wi-fi.php
  • http://www.dd-wrt.com/wiki/index.php/Switched_Ports
Этот роутер долго стоял с родной прошивкой. Однако недавно мне захотелось поставить у себя IPTV. Для этого я заказал у провайдера телевизионную приставку, подключил её к телевизору и роутеру.
После этих нехитрых действий wi-fi лёг. Проблема оказалась в том, что IPTV вещает по мультикасту. В результате этот трафик вещается на все порты LAN  и WI-FI моего маршрутизатора, что приводит к забиванию WI-FI канала. Какой из этого есть выход?

Можно заставить работать один LAN порт в режиме switcha с WAN. Стандартная прошивка этой возможности не поддерживает. В результате раздумий и поисков в интернете было принято решение поставить прошивку DD-WRT.

Процесс установки этой прошивки описан на сайте http://www.dd-wrt.com. После установки этой прошивки субъективно стал быстрее работать административный интерфейс роутера, а также повысилась скорость работы сети. Это всё мои личные наблюдения.

Теперь начинается самое интересное. Как вывести один порт LAN в режим свитча с WAN?

Подключаемся по telnet роутеру. Далее выполняем команды:
nvram set vlan0ports="1 2 3 5*"

nvram set vlan1ports="0 4 5"

nvram commit

reboot

т.е мы вывели порт 4 в одну сеть с WAN.
Осталось воткнуть кабель приставки в порт 4, и наслаждаться интернетом и телевидением. 



пятница, 6 июля 2012 г.

Пример клиента на Spring Web Service

Итак, вызов веб-сервиса выглядит следующим образом:

 /**  
  * Вызов веб-сервиса       
  * @param request  
  * @return  
  */  
      public String invove(String request){  
            StreamSource source = new StreamSource(new StringReader(request));  
            ByteArrayOutputStream output = new ByteArrayOutputStream();  
            StreamResult result = new StreamResult(output);  
            webServiceTemplate.sendSourceAndReceiveToResult(url, source, result);  
            String resultStr = "";  
            try {  
                resultStr = new String(output.toByteArray(), "UTF-8");  
           } catch (UnsupportMultiThreadedHttpConnectionManageredEncodingException e) {  
                logger.error(e.getMessage(), e);  
           }  
            return resultStr;   
      }  

В данном случае я отсылаю запрос в виде строки и принимаю обратно строку.

Основным классом, выполняющим грязную работу, является WebServiceTemplate.
При этом создание экземпляра этого класса можно сделать так:



Всё просто, не правда ли?

Правда, если мы хотим выставить таймаут на ожидание выполнения запроса, то необходимо в проект добавить библиотеку http commons 3.1.1 и изменить определение бина следующим образом:

 <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">    
   <property name="messageSenders">   
    <list>   
     <ref bean="httpSender" />   
    </list>   
    </property>   
  </bean>   
  <!-- add for thread safety -->   
  <bean id="connmanager" class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">  
       <property name="params" ref="connmanagerParams"/>  
  </bean>  
  <!-- Total to 300 connections -->  
  <bean id="connmanagerParams" class="org.apache.commons.httpclient.params.HttpConnectionManagerParams">  
   <property name="maxTotalConnections" value="300"/>  
 </bean>  
   <bean id="httpParams" class="org.apache.commons.httpclient.params.HttpClientParams">   
   <!-- Timeout in milliseconds: in this case 10 seconds -->   
   <property name="soTimeout" value="10000" />    
   </bean>   
   <bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">   
   <property name="params" ref="httpParams" />  
   <property name="httpConnectionManager" ref="connmanager"/>   
   </bean>   
   <bean id="httpSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSender">   
   <constructor-arg>   
    <ref bean="httpClient"/>   
   </constructor-arg>   
   </bean>    

Счастливой пятницы!

UPD 2012-07-14: Наткнулся на проблему, что по умолчанию
org.apache.commons.httpclient.HttpClient
не безопасен для использования в многопоточной среде. Чтобы это исправить, необходимо HttpClient передатьэкземпляр
MultiThreadedHttpConnectionManager
После этого Commons Http должен работать корректно в заданной конфигурации.

среда, 4 июля 2012 г.

Мысли о фреймворках java

Выдалось время подумать о том, как можно улучшить написание богатых приложений, работающих в браузере. Сразу приходит в голову множество разных фреймворков:
  • jsf/myfaces + facelets
  • struts
  • jsp+servlet+jstl, возможно tiles
  • gwt
  • apache click
  • apache wicket
  • spring mvc
От такого количества библиотек голова идёт кругом.
Первое с чего начинают разработчики это jsp + sertvlet + jstl. Это сравни ассемблеру. Идея хорошая. Реализация простая и надёжная. Однако богатые приложения на такой связке быстро не создашь.

Struts в этом плане лучше. Есть поддержка валидации, описание правил перехода по страницам. Богатые приложения на такой связке быстро не создашь.

JSF. Пожалуй, единственным плюсом данного каркаса является то, что он входит в J2EE с версии 5. Эта библиотека максимум для чего подходит - быстрое прототипирование приложений. Кроме того, если разработчику дали вёрстку и сказали использовать её в JSF приложении, то это будет геморрой. А если потом эту jsf страничку понадобится модифицировать верстальщику, то верстальщик в этих jsf компонентах ничего не поймёт.
Существует большое количество jsf библиотек. Каждая со своими глюками и компонентами. Поэтому, кроме головной боли, эта библиотека в продуктивных системах ничего более не принесёт.

Gwt. Приложения, которые создаются на этой библиотеке поистине богаты.

Apache click. Утверждается, что это отличная библиотека для богатых приложений, не занимающихся работой с хранением состояния.

Apache wicket. Это библиотека ориентирована на создание богатых приложений, которые часто и много имеют дело с хранением состояния приложения. Как утверждается на сайте библиотеки, в ней решена проблема кнопки Back в браузерах. Пожалуй, стоит уделить немного внимания данной библиотеке.

Spring mvc. Эта библиотека сделана разработчиками spring. Сам я дела с ней не имел и отзывов никаких не слышал. Поэтому упомянул её здесь для галочки.

Spring web services. Java doc.

Недавно я начал разбираться с новой для себя библиотекой - Spring Web Services. Скачал версию 2.1.0.

Оказалось, что эта версия не работает со Spring 2.5. Из недостатков дистрибутива можно отметить отсутствие javadoc. Однако после поисков мне удалось найти архив с javadoc по пути: http://repo1.maven.org/maven2/org/springframework/ws/spring-ws-core/2.1.0.RELEASE/spring-ws-core-2.1.0.RELEASE-javadoc.jar.

Также к недостатку можно отнести то, что при определённых условиях spring ws зависит от http client 3.1.1. Хотя http client уже давно имеет более свежую версию. Для меня было открытием, что spring ws не имеет встроенной возможности установить таймаут на ожидание обработки запроса в веб-сервис. Именно поэтому используется http client.

Что касается написания клиента, то здесь  Spring ws  предоставляет гибкие возможности. Например, можно посылать xml запросы в виде строк напрямую в сервис, а можно заставить spring ws самому заниматься преобразованием объектов в запросы и обратно. Мне, к сожалению, пришлось выбрать вариант работы с xml через строки, так как веб-сервис, с которым приходится работать, плохо документирован и определён. Поэтому часто приходится делать доработки клиента.

Подписывание xml также происходит довольно легко и быстро. Не надо тратить время на написание кода - всё можно сделать через файл конфигурации Spring. Пример постараюсь выложить позже.

Несмотря на то, что новичкам будет непросто сходу разобраться в этой библиотеке, я бы рекомендовал потратить время на её освоение.

суббота, 30 июня 2012 г.

Установка tomcat6 на linux mint 13

Установить пакеты:
tomcat6-user
libtomcat6-java
tomcat6-common
tomcat6-admin
tomcat6-docs

Далее вызываем man tomcat6-instance-create и внимательно изучаем то, что нам предлагается.

Эта команда позволяет нам создать свой экземпляр Tomcat. Формат команды tomcat6-instance-create опции имя_каталога.

Каталог не должен существовать. Он будет создан автоматически.

В качестве опций нам предлагаются следующие:
-p HTTPPORT - порт, на котором будет жить наш экземпляр tomcat. По умолчанию 8080.
-c CONTROLPORT - порт, по которому можно будет остановить tomcat. По умолчанию 8005.
-w MAGICWORD - магическое слово, которое необходимо послать на CONTROLPORT для останова сервиса. По умолчанию SHUTDOWN.

Создадим экземпляр с помощью команды tomcat6-instance-create ~/tomcatinst1.

You are about to create a Tomcat instance in directory '/home/duglas/tomcatint1'
* New Tomcat instance created in /home/duglas/tomcatint1
* You might want to edit default configuration in /home/duglas/tomcatint1/conf
* Run /home/duglas/tomcatint1/bin/startup.sh to start your Tomcat instance

Теперь у нас есть свой экземпляр tomcat, с которым можно работать.
Открываем файл cont/tomcat-users.xml и добавляем строчки
<role rolename="manager"/>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
<user username="admin" password="admin" roles="tomcat,manager"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="role1" password="tomcat" roles="role1"/>

Переходим в каталог bin и запускаем tomcat ./startup.sh:
Using CATALINA_BASE:   /home/duglas/tomcatint1
Using CATALINA_HOME:   /usr/share/tomcat6
Using CATALINA_TMPDIR: /home/duglas/tomcatint1/temp
Using JRE_HOME:        /usr/lib/jvm/java-6-openjdk
Using CLASSPATH:       /usr/share/tomcat6/bin/bootstrap.jar
Tomcat started

Набрав в строке браузера http://localhost:8080, откроется пустая страница.

Пакет  с документацией ставится в каталог /usr/share/tomcat6-docs/docs.
Приложение для развёртывания приложений находится в каталоге /usr/share/tomcat6-admin.

Для того, чтобы это приложение заработало, необходимо скопировать каталог tomcat6-admin в каталог webapps нашего экземпляра Tomcat и перезапустить Tomcat. Далее, это приложение будет доступно по адресу http://localhost:8080/manager/html.

среда, 27 июня 2012 г.

Apache CXF. Ошибка Property is already defined. Use to resolve this conflict.

При попытке сгенерировать java клиента с помошью WSDL2JAVA Apache CXF выдал ошибку  Property  is already defined. Use <jaxb:property> to resolve this conflict.

Проблема оказалась в том, что атрибут и элемент имеют одинаковые имена. Вот такой бред выдаёт JAXB. Что с этим делать? Нужно создать файлик xml, в котором необходимо определить, что дубликат имени будет отображаться на другое имя. Например, так:

<jxb:bindings version="2.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="Dummy.xml" node="/xsd:schema">
<jxb:bindings node="//xsd:complexType[@name='complexTypeOne']">
<jxb:bindings node=".//xsd:attribute[@name='value']">
<jxb:property name="ValueToFixError1"/>
</jxb:bindings>
</jxb:bindings>

</jxb:bindings>
</jxb:bindings> 

После этого необходимо WSDL2JAVA с помощью ключа -b указать созданный файлик.

среда, 20 июня 2012 г.

Ubuntu 12.04 LTS и классический Gnome

У кого как, а Unity в Ubuntu вызывает у меня рвотный рефлекс. Он более подходит для планшеток и развлечений чем для работы. Потому  я хочу видеть привычный мне интерфейс Gnome.

Что делать? Открываем Ubuntu Software Center. Ставим пакет gnome shell, далее выходим из сеанса и перед заходом выбираем Gnome. Наконец-таки я в родном окружении.

Кстати, до обновления, у меня стояла версия 10.04. После обновления мне пришлось почистить скрытые каталоги своей домашней директории, чтобы Gnome смог корректно отобразиться.

Что ещё не понравилось, так это то, что пришлось доставлять дрова NVidia. Без них экран входа в систему отображался некорректно.

Теперь сижу и думаю, для чего обновлял машину, если ранее всё работало.

воскресенье, 10 июня 2012 г.

Firefox 13 и страница наиболее посещяемых сайтов

Обновился до Firefox 13.
Теперь при открытии новой вкладки выводится галерея из 9 наиболее посещаемых сайтов!

За мной следят?
Как отключить:
1) во вкладке в правом верхнем углу есть значок матрицы. Щёлкаем на него, и галерея исчезает.
2) в браузере набираем about:config, ищем свойство browser.newtabpage.enabled, меняем его на false и перезагружаем браузер.



Mysql 5.5.22. Проблема с utf8

Установил в Linux Mint 13 Mysql 5.5.22. Из коробки субд настроена на кодировку latin1. Из-за этого работать с русским языком невозможно. Чтобы установить кодировку utf8, необходимо сделать следующее:
1) vim /etc/mysql/my.cnf
[mysqld]
character-set-server = utf8

2) sudo /etc/init.d/mysql restart

3) Если уже до этого создана БД, то необходимо сделать alter database db_name set CHARACTER SET utf8 COLLATE utf8_general_ci;

После описанных выше манипуляций проблема с кодировкой должна исчезнуть.

суббота, 9 июня 2012 г.

Малое время работы ноутбука от батареи на Linux Mint 12

Сначала я хотел написать про то, как же быстро расходуется энергия на моём портативном компьютере в Linux Mint 12, но после того, как я перешёл на Linux Mint 13, моё мнение сильно изменилось в лучшую сторону.

Индикатор батареи стал показывать, что предполагаемое время работы от батареи составляет 5 часов. Это уже хороший показатель. Осталось поставить утилиту powertop и поглядеть, что сажает батарейку.

Linux Mint. Ошибка NO_PUBKEY при попытке выполнить sudo apt-get update.

Иногда, при попытке выполнить в Linux Mint команду sudo apt-get update вылезает ошибка The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 5A9BF3BB4E5E17B5. Что это за ошибка и что с ней делать?

В сети был найден следующий рецепт:
1) sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys
2) sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys имя_открытого_ключа_на_который_ругается_система
3) sudo apt-get update

После этих манипуляций проблем с менеджером пакетов быть не должно.

суббота, 12 мая 2012 г.

FreeMarker. Продолжение.

Сегодня почти весь день убил на то, чтобы справиться с проблемой: на рабочей станции в среде разработки FreeMarker отлично считывает и заполняет шаблон.

Как только я ставлю портлет на сервер, то на выходе я получаю пустой шаблон! В логах никаких ошибок, включение логов в режим DEBUG тоже ничего дало - FreeMarker находит мой шаблон, но на выходе отдаёт пустой текст. Детальное исследование показало, что FreeMarker считывает шаблон пустым. Додумался проверить кодировку текста шаблона - формально файл был закодирован в UTF-8, но видимо при просмотре или редактировании шаблона кодировка слетела. После приведения файла в UTF-8 мой шаблон заработал на сервере!

Жаль потраченного времени, но зато это помогло мне разобраться получше в API FreeMarker.

пятница, 11 мая 2012 г.

FreeMarker

Возникла у меня задача: есть в наличии html шаблон, который надо заполнять данными и отправлять на e-mail. Сначала я подумал, а почему не забить шаблон в код? И как потом поддерживать получившееся Г?

Следующей мыслью было - вынести шаблон в отдельный файл. Это уже лучше. Но возникает следующая проблема - нужно придумывать свой язык для обозначения позиций, где необходимо осуществить подстановку. Поэтому это мысль тоже отпала.

В результате поисков выбор пал на библиотеку FreeMarker (http://freemarker.sourceforge.net/). Библиотека занимает почти 1 мегабайт. Поддерживает java 1.2 и выше. Библиотека является мощным движком для генерации текста по шаблону.

Поддерживает вычисления внутри шаблоне. Надо сказать, что вычисления осуществляются через BigDecimal. Поддерживаются директивы.

Также есть сносная документация, которая описывает все плюшки более подробно.

Конкурентом этой библиотеки является Apache Velocity. Опыта работы с этой библиотекой не было, но судя по форумам народ от неё не в сильном восторге.

пятница, 27 апреля 2012 г.

Linux mint 12. Отключаем гостевую учётную запись

В Linux Mint 12 зачем-то сделали гостевую учётную запись. Отключим её.
Для этого введём команду : sudo gedit /etc/lightdm/lightdm.conf.
Добавим в конец файла строку allow-guest=false . Теперь надо перезапустить компьютер.

воскресенье, 8 апреля 2012 г.

LinuxMint 12 & медленный wifi

Итак, после продолжительной работы в интернете на новом дистрибутиве у меня сложилось впечатление, что скорость работы wifi маленькая - не превышает 100 Кб\с. Очень странно.

Поиск в интернете показал, что такая проблема встречается у многих пользователей. Решение оказалось таким - нужно установить пакет linux-backports-modules-cw-3.2-oneiric-generic-pae. Внимание: у меня ядро с PAE, поэтому вам необходимо самим определить подходящий пакет. После перезагрузки скорость скачки поднялась до 12 мегабит, скорость выгрузки данных поднялась до 19 мегабит.

Индикатор загрузки

Я очень не люблю, когда не понимаю, чем занят мой компьютер. Потому одним из инструментов, которые помогают за компьютером, является системный монитор ресурсов. Ставим его с помощью sudo apt-get install indicator-multiload и наслаждаемся жизнью.

Отвалился тачпад в Linux Mint 12

Сегодня вдруг перестал работать тачпад. Сам по себе. Очень странно. Вылечилось "просто": apt-get install gpointing-devices-settings.
Далее запускаем  gpointing-devices-settings и включаем  тачпад.

суббота, 7 апреля 2012 г.

Thinkpad R61 & Linux Mint 12

Меня достал windows своими сообщениями, что он не лицензионный и достал Касперский, что сажает батарейку.

Потому было принято решение перейти на линукс. Я решил поставить какой-нибудь десктопный дистрибутив, с которым можно будет легко работать на моём ноутбуке -- Lenovo ThinkPad R61. Выбор пал на Linux Mint 12.

Так как у меня всего 4 Гб памяти на ноутбуке, то выбор пал на 32 битную версию дистрибутива. Сказано - сделано! Скачал через торренты нужную версию, прожёг на ДВД, перегрузился и начал ставить.

Установка прошла легко, меня спросили о пароле к беспроводной сети, а потом я доверился установщику. Все параметры были установлены по умолчанию.

После установки у меня не заработал тачпад. Первое, что делаем - обновляем систему через менеджер обновлений. Перегружаемся - и тачпад заработал.

Далее, у меня 4Гб памяти, а ядро видит только 3. Поэтому ставим ядром с поддержкой PAE, а текущее удаляем. Теперь uname -a выдаёт:
Linux duglasThink 3.0.0-17-generic-pae #30-Ubuntu SMP Thu Mar 8 17:53:35 UTC 2012 i686 i686 i386 GNU/Linux

Изначально, не работает управление вентилятором, и поэтому он всё время работает на 100%. Это не простительно. Поэтому беглый поиск по интернету выдал мне решение - программка thinkfan.

Делаем sudo apt-get install thinkfan.
Добавляем модуль 'coretemp' в /etc/modules.
Загружаем модуль 'coretemp'

Добавим следующие строчки в файл /etc/thinkfan.conf до параметров температуры:
sensor /sys/devices/platform/coretemp.0/temp2_input
sensor /sys/devices/platform/coretemp.0/temp3_input
sensor /sys/devices/virtual/hwmon/hwmon0/temp1_input

Добавим в файл /etc/modprobe.d/thinkfan.conf строку
options thinkpad_acpi fan-control=1

Загрузим модуль ядра thinkpad_acpi.
В файле /etc/default/thinkfan установим параметр START в значение yes.
Запустим thinkfan: /etc/init.d/thinkfan start
Проверим его работу: cat /proc/acpi/ibm/fan.

Если уроверь level находится в пределах от 0 до 7, значит демон работает.

В ноутбуке Lenovo есть акселерометр. Чтобы его установить, необходимо выполнить sudo apt-get install tp-smapi-dkms
sudo modprobe -a tp_smapi hdaps

grep -r . /sys/devices/platform/smapi/BAT0

echo "tp_smapi" >> /etc/modules
echo "hdaps" >> /etc/modules.

Также необходимо настроить intel speedstep. Для этого в Synaptic можно поставить cpufreqd.

Первоначальная настройка на этом завершена.


понедельник, 26 марта 2012 г.

WebSphere Application Server 6. Диагностика зависших потоков.

Иногда в логе WebSphere Application Server можно наблюдать следующие строки WSVR0605W: Thread <threadname> has been active for <time> and may be hung.  There are <totalthreads> in total in the server that may be hung.

Что делать в этом случае? Как понять, в чём проблема? Ответ на этот вопрос состоит в том, чтобы сгенерировать javacore и изучать его содержимое. В апп сервер встроена диагностика зависших потоков. 

Для этого необходимо сделать следующее:
  1. Из консоли администрирования выбрать Servers > Application Servers > server_name.

  2. Далее в разделе Server Infrastructure выбрать Administration > Custom Properties.

  3. Нажать New.

  4. Добавить следующее свойство:

    Name: com.ibm.websphere.threadmonitor.dump.java
    Value: true

  5. Нажать Apply.

  6. Нажать OK и сохранить изменения.

  7. Рестартовать Application Server.
Теперь в случае если, WAS увидет, что поток подвис, то он автоматически создаст javacore, который можно в дальнейшем изучать.
 

DB2 8.2. Оптимизация

Добрый вечер,
Сегодня расскажу пару слов об оптимизации СУБД DB2 8.2.

Итак, для начала необходимо проводить следующие процедуры для поддержания СУБД в рабочем состоянии:
1) сбор статистики,
2) реорганизация таблиц и индексов,
3) обновление статистики,
4) ребиндинг хранимых процедур.

Что касается обновления статистики, то в сети можно найти скрипты по сбору статистики в DB2.
То же самое касается и реорганизации данных. 

Ребиндинг можно делать с помощью команды db2rbind <имя бд> -l <лог файл> all.
Правда названная выше команда может корректно выполнится если никто не использует хранимые процедуры в настоящий момент, поэтому эту команду необходимо выполнять в оффлайн режиме.

Также, если у нас DB2 стоит на линуксе с ядром серии 2.6, то можно выставить следующие параметры:
db2set DB2LINUXAIO=true
db2set DB2_SCATTERED_IO=ON
db2set DB2_DIRECT_IO=YES
 
После выставления параметров необходимо перезапустить db2.
Начиная с версии 9 параметр DB2_DIRECT_IO использовать не рекомендуется.
 
Также отключить кеширование можно на уровне табличного пространства. Это делается с 
помощью команды 
ALTER TABLESPACE <имя табличного пространства> NO FILE SYSTEM CACHING; 
 
После выполнения команды ALTER TABLESPACe существующие соединения с БД необходимо закрыть,
чтобы новые правила кеширования вступили в силу. 

 
Однако в боевой системе это делать стрёмно - куда проще поменять параметр среды и 
рестартовать СУБД.
 
Это хороший старт для дальнейшей оптимизации БД.

вторник, 20 марта 2012 г.

JQuery ajax post on Safari windows and Apache2

Добрый вечер,
Недавно я словил удивительный баг: иногда при попытке отправить post запрос через jQuery в Safari под Windows на Apache HTTP Server 2 происходило следующее. Запрос отправлялся, однако на сервере я не мог получить ни одного параметра http запроса. Более того, подобная ситуация не имела какого-либо сценария воспроизведения.

Решение:
Проблема решилась с помощью редактирования файла httpd.conf и выставлении опции KeepAlive Off.

Подобные ситуации возникают, и они описаны в сети. Достаточно ввести поиск по словам "jquery ajax tcp post".

понедельник, 12 марта 2012 г.

Русификация консоли NetBSD

Удалось настроить русификацию в консоли.
Но выяснилось следующее - если переключиться из консоли в иксы, а потом выйти из иксов в текстовый режим, то на экране получаем мусор и неработающую консоль. Разбираться с этим дальше нет времени и желания.

Конечно, можно пользоваться и иксами, но это уже не так интересно. В общем, на desktope NetBSD не жилец.

Да, наверное со всем остальным в этой системе обстоят дела лучше, но текстовая консоль является основополагающим инструментом.

Всем спасибо, кто помогал.

среда, 7 марта 2012 г.

NetBSD и X

Мораль сей басни такова - внимательно читайте man xorg.conf!

Русификация NetBSD 5.1.2 в X

1. установил usr/pkgsrc/fonts/dejavu-ttf и mlterm.
В ~/.xinitrc прописать
export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'

2. Указываем на них фонтконфигу. Fontconfig -- это поделие Кейта
Пакарда для настройки и доступа к шрифтам на уровне системы. В файле
/etc/fonts/fonts.conf ищем записи вида <dir>...</dir> (они расположены
на самом верхнем уровне вложенности документа, после большого
коммента) и добавляем туда:

     <dir>/usr/pkg/lib/X11/fonts/TTF</dir>

3. Обновляем кэш фонтконфига:

     # fc-cache -fv
4. В файле /etc/X11/xorg.conf в разделе InputDevice
прописываем следующую строку: Option "XkbOptions" "grp:alt_shift_toggle".

Переключение раскладки клавиатуры будет осуществлено по нажатию alt+shift.

понедельник, 5 марта 2012 г.

OpenJDK 1.7.0 на NetBSD

В этой небольшой заметке я расскажу как установить jdk 1.7 на NetBSD 5.1.2.

Войдём как root.
Далее cd /usr/pkgsrc/lang/openjd7.
make install && clean && clean-depends.

Java установится по пути /usr/pkg/java/openjdk7.

Полёт нормальный.

суббота, 3 марта 2012 г.

Trac + Fedora 12 + MySQL

Версии компонентов:
Trac 0.12.3
MySQL 5.1.47-2
Russian Fedora 12

При попытке создать проект Trac, который будет хранить данные в MySQL вываливается вот такая ошибка:
unsupported operand type(s) for /: 'int' and 'NoneType'
Traceback (most recent call last):
File "build/bdist.linux-i686/egg/trac/admin/console.py", line 437, in do_initenv
  options=options)
File "build/bdist.linux-i686/egg/trac/env.py", line 214, in __init__
  self.create(options)
File "build/bdist.linux-i686/egg/trac/env.py", line 402, in create
  DatabaseManager(self).init_db()
File "build/bdist.linux-i686/egg/trac/db/api.py", line 146, in init_db
  connector.init_db(**args)
File "build/bdist.linux-i686/egg/trac/db/mysql_backend.py", line 106, in init_db
  for stmt in self.to_sql(table, utf8_size=utf8_size):
File "build/bdist.linux-i686/egg/trac/db/mysql_backend.py", line 155, in to_sql
  utf8_size=utf8_size))
File "build/bdist.linux-i686/egg/trac/db/mysql_backend.py", line 119, in _collist
  limit_col = 767 / utf8_size
TypeError: unsupported operand type(s) for /: 'int' and 'NoneType'

В общем, не удалось подружить Trac и MySQL.
Необходимо  проверить как поведёт себя Trac и PosgreSQL.

Безбраузерное тестирование javascript кода


Безбраузерное тестирование
Автоматизированное тестирование javascript
Автоматизированное тестирование с помощью Rhino + QUnit
Работа с отладчиком Rhino
Автоматизированное тестирование с помощью Rhino + Jasmine
Тестирование AJAX вызовов в безбраузерной среде с помощью Jasmine



Безбраузерное тестирование

Бурное развитие создания приложений для браузера с помощью javascript привело к тому, что методы выполнения unit тестов для серверных приложений необходимо адаптировать для клиентских приложений, выполняющихся в браузере.

До тех пора, пока приложение является небольшим, тестирование автоматизированное или ручное в браузере является терпимым. Однако более практичным представляется атоматизированное безбраузерное тестирование.  Разумеется недостатком такого подхода является то, что мы не можем проследить как ведёт себя код в разных браузерах, но это может стать подспорьем при разработке приложения. Для ручного тестирования в различных браузерах рекомендуется использовать либо отдельные виртуальные машины для каждого браузера либо использовать набор IE Collection (http://utilu.com/IECollection/).

Для безбраузерного тестирования нам понадобится javascript движок. На февраль 2012 года известны следующие движки javascript:
Rhino: Mozilla’s Java JavaScript implementation.
SpiderMonkey: Mozilla’s C implementation of JavaScript.
V8: Google’s JavaScript virtual machine for Chrome.

Автоматизированное тестирование javascript



Мне пока известны следующие подходы к тестированию:

1) на базе Node.js
2) на базе движка Rhino от Mozilla

Рассмотрим второй подход.

Для этого можно использовать:  
  1. Rhino - реализация javascript на java.
  2. Envjs - реализация DOM API для Rhino. Эту библиотеку разработал разработчик jQuery.
  3. Jasmine - библиотека для тестирования.
  4. Jquery-jasmine - упрощение тестирования jasmine и DOM.
  5. QUnit - ещё одна библиотека для тестирования.

Автоматизированное тестирование с помощью Rhino + QUnit


Попробуем поставить Rhino и заставить работать Envjs.
1) Скачиваем Rhino rhino1_7R2 с сайта  Mozilla ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_7R2.zip.
Распаковываем архив. В этом архиве нам потребуется файл js.jar.
Теперь проверим, что Rhino действительно работает.
Для этого запустим команду
java -cp js.jar org.mozilla.javascript.tools.shell.Main -opt -1

Затем введём команду print("Hello world");
quit();

Далее необходимо установить Envjs.
Установим пропатченную версию Envjs.
Для этого скачаем её по ссылке https://github.com/ryan-roemer/envjs-1.2.

Скачаем также QUnit - система для создания тестов.
https://github.com/jquery/qunit/blob/a46610796b457fab05587945e743d4e857f580b5/qunit/qunit.css
https://github.com/jquery/qunit/blob/a46610796b457fab05587945e743d4e857f580b5/qunit/qunit.js


Теперь нам надо будет создать ещё два файла:
setup.js - для интеграции Envjs с QUnit.
run-tests.js - скрипт для запуска тестов.

Создадим файл my-lib.js с тестируемой функцией:
function addTwo(x, y) {
   return x + y;
}

Создадим файл my-tests.js с QUnit тестом.
module("My Module");

test("addTwo", function () {
   equals(addTwo(0, 0), 0, "Add nothing.");
   equals(addTwo(1, 2), 3, "Add numbers.");
   equals(addTwo(-1, -2), -3, "Add negatives.");
});

Теперь создадим страницу test.html:
<html>
 <head>
   <title>QUnit</title>
   <link rel="stylesheet" href="qunit.css" type="text/css" />
   <script type="text/javascript" src="qunit.js"></script>
   <script type="text/javascript" src="my-lib.js"></script>
   <script type="text/javascript" src="my-tests.js"></script>
 </head>
 <body>
   <h1 id="qunit-header">QUnit Test Suite</h1>
   <h2 id="qunit-banner"></h2>
   <div id="qunit-testrunner-toolbar"></div>
   <h2 id="qunit-userAgent"></h2>
   <ol id="qunit-tests"></ol>
   <div id="qunit-fixture"></div>
 </body>
</html>

После того, как мы убедились, что в браузере файл test.html выполняется, можно настроить
Envjs и Qunit.

Создадим файл setup.js со следующим содержимым:
load('env.rhino.1.2.js');
load('qunit.js');

var starttime = new Date().getTime();

// Envjs/QUnit Bridge.
Envjs({
   // Straight from the Envjs guide.
   scriptTypes: {
       "": true,
       "text/javascript": true
   },
   // Straight from the Envjs guide.
   beforeScriptLoad: {
       'sharethis': function (script) {
           script.src = '';
           return false;
       }
   },

   // Hook QUnit logging to console.
   afterScriptLoad: {
       'qunit': function () {
           var count = 0, testName;

           console.log("* QUnit test runner loaded.");

           // Grab current test name.
           QUnit.testStart = function(name, testEnvironment) {
               testName = name;
           };
           // Override log to display to stdout.
           QUnit.log = function (result, message) {
               // Strip out HTML in results messages.
               message = message.replace(/<\/?.*?>/g, '');
               console.log("  * {%s}(%s)[%s] %s",
                   testName, count++,
                   result ? 'PASS' : 'FAIL', message);
           };
           QUnit.done = function (fail, total){
               var endtime = new Date().getTime();
               var pass = total - fail;
               console.log("\n" +
                   "*****************\n" +
                   "* QUnit Results *\n" +
                   "*****************\n" +
                   "* PASSED: %s\n" +
                   "* FAILED: %s\n" +
                   "* Completed %s tests total in %s seconds.\n",
                   pass, fail, total,
                   parseFloat(endtime-starttime) / 1000.0);
          };
       },

       // Straight from the Envjs guide.
       '.': function (script) {
           script.type = 'text/envjs';
       }
   }
});

Создадим теперь скрипт для запуска тестов run-tests.js:
load('setup.js');

console.log("Starting QUnit tests...");
window.location = "test.html";

Теперь проверим как всё это работает.
Выполним команду
java -cp ~/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js

[duglas@vmstation js]$ java -cp ~/projects/Rhino/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js
[  Envjs/1.6 (Rhino; U; Linux i386 2.6.32.11-99.fc12.i686; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13  ]
Starting QUnit tests...
* QUnit test runner loaded.
 * { addTwo }( 0 )[ PASS ]  Add nothing.
 * { addTwo }( 1 )[ PASS ]  Add numbers.
 * { addTwo }( 2 )[ PASS ]  Add negatives.

*****************
* QUnit Results *
*****************
* PASSED:  3
* FAILED:  0
* Completed  3  tests total in  3.233  seconds.

[duglas@vmstation js]$ java -cp ~/projects/Rhino/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js
[  Envjs/1.6 (Rhino; U; Linux i386 2.6.32.11-99.fc12.i686; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13  ]
Starting QUnit tests...
* QUnit test runner loaded.
 * { addTwo }( 0 )[ PASS ]  Add nothing.
 * { addTwo }( 1 )[ PASS ]  Add numbers.
 * { addTwo }( 2 )[ PASS ]  Add negatives.

*****************
* QUnit Results *
*****************
* PASSED:  3
* FAILED:  0
* Completed  3  tests total in  3.466  seconds.

Ура!
Заработали наши тесты.

Работа с отладчиком Rhino

Чтобы вызвать отладчик Rhino необходимо выполнить команду:
java -cp js.jar org.mozilla.javascript.tools.debugger.Main


Автоматизированное тестирование с помощью Rhino + Jasmine


Скачаем Jasmine по ссылке https://github.com/downloads/pivotal/jasmine/jasmine-0.10.0.zip.
Скачаем Jasmie-reporters по ссылке https://github.com/larrymyers/jasmine-reporters.  Этот проект представляет собой набор из подключаемых адаптеров для форматирования результатов теста.

По умолчанию Jasmine использует TrivialReporter для отображения результатов тестов в браузере. Jasmie-reporters содержит ConsoleReporter для вывода результатов в консоль и JUnitXmlReporter - для формирования отчёта в формате JUnit.

Создадим пример теста Jasmine и ConsoleReporter.


Создадим модель Калькулятора.
Для этого создадим файл calc.js со следующим содержимым:

/*
   Класс калькулятора
*/

var Calculator = function(){
return {
    add: function(a,b){
       return a+b;
    },
    sub: function(a,b){
       return a-b;
    },
    div: function(a,b){
       return a/b;
    },
    mul: function(a,b){
       return a*b;
    },
    writeTofile: function(filename, text){
       try {
               var out = new java.io.BufferedWriter(new java.io.FileWriter(filename));
               out.write(text);
               out.close();
               return;
           } catch (e) {}
    }
}
};

Создадим файл calc-test.js с нашими тестами:

           describe('калькулятор',function(){
               var calc = Calculator();
               it('Складываем 1 и 2',function(){
                   var result = calc.add(1,2);
                   expect(result).toEqual(3);
               });
               
               it('Вычитаем 1 и 2',function(){
                   var result = calc.sub(1,2);
                   expect(result).toEqual(-1);
               });
               
           });

Мы написали 1 модуль с 2 тестами. Один тест на сложение двух чисел, а второй тест на вычитание двух чисел. Нам также понадобятся следующие файлы:
env.rhino.1.2.js
jasmine.console_reporter.js
jasmine.css
jasmine.js
jasmine-html.js
jquery-1.6.2.min.js

Создадим файл setup.js, который будет загружать DOM модель в Rhino:
load('env.rhino.1.2.js');
Envjs.scriptTypes['text/javascript'] = true;  

Создадим файл index.html, представляющий собой нашу страницу:
<html>
<head>
<link rel="stylesheet" type="text/css" href="jasmine.css">
 <script type="text/javascript" src="jasmine.js"></script>
 <script type="text/javascript" src="jasmine-html.js"></script>
<script type="text/javascript" src="jquery-1.6.2.min.js"></script>
 <script type="text/javascript" src="jasmine.console_reporter.js"></script>
 <script type="text/javascript" src="calc.js"></script>
 <script type="text/javascript" src="calc-test.js"></script>
</head>
<body>

<script type="text/javascript">
   (function($){
       $(document).ready(function(){
           var jasmineEnv = jasmine.getEnv();
       
         var trivialReporter = new jasmine.TrivialReporter();

         jasmineEnv.addReporter(trivialReporter);
                 jasmineEnv.addReporter(new jasmine.ConsoleReporter());
         
       
           jasmineEnv.execute();
           
           var calc = Calculator();
           //calc.writeTofile('./test.txt','мой простой текст');
       })    
   })(jQuery);
   
   
</script>
   <div  >
   <p>
       http://net.tutsplus.com/tutorials/javascript-ajax/testing-your-javascript-with-jasmine/ - интересная страница по jasmine
       http://www.build-doctor.com/2010/12/08/javascript-bdd-jasmine
       https://github.com/velesin/jasmine-jquery
       http://stanislavvitvitskiy.blogspot.com/2009/04/calling-java-from-xul-applications.html
$ java -cp ~/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js

   </p>    
   </div>
</body>
</html>

Теперь нам нужен файл для запуска непосредственно процесса тестирования. Содержимое файла run-tests.js:
load('setup.js');

console.log("Starting Jasmine tests...");
window.location = "index.html";

Запустим тесты с помощью следующей команды :
[duglas@vmstation jasminetest]$ java -cp ~/projects/Rhino/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js
[  Envjs/1.6 (Rhino; U; Linux i386 2.6.32.11-99.fc12.i686; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13  ]
Starting Jasmine tests...
Runner Started.
калькулятор : Складываем 1 и 2 ...
Passed.
калькулятор : Вычитаем 1 и 2 ...
Passed.
калькулятор: 2 of 2 passed.
Runner Finished.
2 specs, 0 failures in 0.087s.

Таким образом мы смогли выполнить jasmine тесты, а результат своей работы вывели в консоль.

Очень легко подключить JUnitXmlReporter. Для этого необходимо вставить строчку <script type="text/javascript" src="jasmine.junit_reporter.js"></script>
в раздел подключаемых скриптов и подключить новый адаптер в коде jasmineEnv.addReporter(new jasmine.JUnitXmlReporter());

После прогона тестов будет создан xml файл вида TEST-<имя спецификации>.xml, который можно обрабатывать в JUnit.



Тестирование AJAX вызовов в безбраузерной среде с помощью Jasmine

Пока не очень понятно, что можно написать.
В данном случае возможны следующие виды тестирования:
  1. Unit тесты, которые подменяют AJAX запросы и позволяют выполнять код до вызова AJAX запроса и сразу после него. Также можно подменять ответ от сервера.
  2. Интеграционные тесты, которые выполняют настоящие AJAX запросы.


Jasmine имеет поддержку и тех и других видов тестов.

Также написан плагин jasmine-ajax. Найти его можно по ссылке https://github.com/pivotal/jasmine-ajax. Этот плагин совместим с jQuery и Prototype.  Плагин подменяет AJAX вызовы и таким образом не один запрос не уйдёт на сервер.