JavaDoc по DFC скромно сообщает, что параметр timeout метода IDfSession.getLoginTicketEx() - это "How long will acquired loigin ticket remain valid since generation". При этом про единицы измерения таймаута не говорится ни слова. Экспериментальным путем удалось определить, что измеряется таймаут в минутах.
barbitoff programmer`s blog
Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)
воскресенье, 24 февраля 2013 г.
четверг, 21 февраля 2013 г.
WSO2 ESB: вызов конечного сервиса, требующего HTTP Basic авторизацию
Тут все просто, перед <send/> делаем:
<property expression="fn:concat('Basic ', base64Encode('username:password'))" name="Authorization" scope="transport"></property>
вторник, 19 февраля 2013 г.
Запуск job`а Pentaho из Java
Задача:
Запустить имеющийся job Pentaho (kjb-файл) из Java-приложения.
Решение:
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleXMLException;
import org.pentaho.di.job.Job;
import org.pentaho.di.job.JobMeta;
...
KettleEnvironment.init();
JobMeta jobMeta = new JobMeta(PATH_TO_KJB_DIR+"/my.kjb", null);
jobMeta.setInternalKettleVariables();
Job job = new Job(null, jobMeta);
job.setVariable("Internal.Job.Filename.Directory", PATH_TO_KJB_DIR);
job.execute(0, null);
job.waitUntilFinished();
if(job.getErrors() > 0)
{
fail("Job execution error");
}
Данный код выполнит Job из файла my.kjb, расположенного в директории, задаваемой переменной PATH_TO_KJB_DIR. Вызов job.setVariable() используется для того, чтобы переменная ${Internal.Job.Filename.Directory} внутри Job`а действительно указывала на папку, в которой расположен файл Job`а (так, как она это делает при запуске Job`а через Kitchen). Если этот вызов опустить, Job будет считать, что он лежит в папке, откуда запущено Java-приложение (это принципиально, если Job использует какие-то внешние ресурсы, например, трансформации).
Что касается необходимых для данного кода зависимостей, то для сборки maven`ом я добавил в pom`ку следующие:
<!-- Pentaho -->
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-engine</artifactId>
<version>4.4.0-stable</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-core</artifactId>
<version>4.4.0-stable</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>commons-vfs</groupId>
<artifactId>commons-vfs</artifactId>
<version>1.0</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-db</artifactId>
<version>4.4.0-stable</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>pentaho-library</groupId>
<artifactId>libformula</artifactId>
<version>1.2.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>pentaho-library</groupId>
<artifactId>libbase</artifactId>
<version>1.2.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>rhino</groupId>
<artifactId>js</artifactId>
<version>1.7R2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>janino</groupId>
<artifactId>janino</artifactId>
<version>2.5.15</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.12</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-apache-client</artifactId>
<version>1.12</version>
<scope>test</scope>
<type>jar</type>
</dependency>
</dependencies>
Не претендую на полноту списка, возможно, какие-то необходимые зависимости уже были в pom`ке ранее.
понедельник, 18 февраля 2013 г.
Maven: delpoy на Oracle Weblogic
Для развертывания maven`ом веб-приложений на Weblogic в поставку последнего входит соответствующий плагин weblogic-maven-plugin. Правда его перед использованием придется самостоятельно собрать, перейдя в директорию MW_HOME/wlserver_10.3/server/lib/ и выполнив там:
java -jar wljarbuilder.jar -profile weblogic-maven-pluginВот небольшой пример использования этого плагина для развертывания веб-приложения:
<!-- weblogic deployment -->
<plugin>
<groupId>com.oracle.weblogic</groupId>
<artifactId>weblogic-maven-plugin</artifactId>
<version>10.3.4</version>
<configuration>
<adminurl>t3://${deployment.host}:${deployment.port}</adminurl>
<user>${deployment.user}</user>
<password>${deployment.password}</password>
<upload>true</upload>
<action>deploy</action>
<remote>true</remote>
<verbose>true</verbose>
<source>${project.build.directory}/${project.build.finalName}.${project.packaging}</source>
<name>${project.name}</name>
</configuration>
</plugin>
В этом примере все параметры подключения к целевому Weblogic`у берутся из соответствующих свойств, и деплоится приложение под именем, равным имени проекта. К сожалению, с помощью параметров плагина нельзя управлять контекстом, в который деплоится приложение, так что приходится для этого использовать дескрипторы weblogic.xml / application.xml.
Всё вышеописанное взято из оракловской документации: http://docs.oracle.com/cd/E21764_01/web.1111/e13702/maven_deployer.htm.
WSO2 ESB: замена пространств имен в сообщении перед проксированием на конечный сервис
Задача:
Во входящем сообщении перед его проксированием на конечный сервис у всех элементов в пространстве имен "http://ns1" установить пространство имен "http://ns2".
Решение:
Возможно, можно как-то лучше, но пока реализовал так:
<script language="js"><![CDATA[
var targetNs = new Namespace("http://ns2");
var srcNs = new Namespace("http://ns1");
var payload = mc.getPayloadXML();
var payloadElems = payload..srcNs::*;
for(i in payloadElems)
{
if(payloadElems[i].namespace()!=null)
{
payloadElems[i].setNamespace(targetNs);
}
}
mc.setPayloadXML(payload);
]]></script>
Проверка пространства имен на null в цикле выполняется из-за того, что в payloadElems попадают зачем-то текстовые узлы, у которых пространство имен равно null и попытка установить его с помощью setNamespace приведет к ошибке.
Youtube Java API: AuthenticationException: Error authenticating (check service name)
Проблема:
Создал новый аккаунт google, без проблем могу войти из-под него на YouTube. Пытаюсь авторизоваться этим акканутом через Java API GData с помощью Clientlogin, используя такой код:
YouTubeService service = new YouTubeService(CLIENT_ID, DEVELOPER_KEY);На что получаю:
service.setUserCredentials("xxxxxxx@gmail.com", "xxxxxxx");
com.google.gdata.util.AuthenticationException: Error authenticating (check service name)Почитал http://apiblog.youtube.com/2011/03/clientlogin-fail.html, ничего такого, что помогло бы в моем случае, там не нашел.
at com.google.gdata.client.GoogleAuthTokenFactory.getAuthException(GoogleAuthTokenFactory.java:628)
...
Решение:
Пользователь ни разу не загружал видео на Youtube. Чтобы исправить проблему, даже загружать видео не надо, достаточно просто зайти браузером на Youtube и нажать кнопку "Добавить видео", а в появившемся окошке - "Продолжить":
После этого Clientlogin-аутентификация начинает проходить без проблем.
пятница, 15 февраля 2013 г.
KettleDatabaseException: database type with plugin id [Oracle] couldn't be found!
Проблема:
Причина:
Решение:
Пытаюсь из Java выполнить Kettle job. На строчке:
JobMeta jobMeta = new JobMeta(PATH_TO_KJB, null);
падает:
Unable to load the job from XML file [/.../.../my.kjb]
Unable to load job info from XML node
Database type not found!
at org.pentaho.di.job.JobMeta.<init>(JobMeta.java:879)
...Caused by: org.pentaho.di.core.exception.KettleXMLException:
Unable to load job info from XML node
Database type not found!
at org.pentaho.di.job.JobMeta.loadXML(JobMeta.java:1212)
...Caused by: org.pentaho.di.core.exception.KettleDatabaseException:
database type with plugin id [Oracle] couldn't be found!
at org.pentaho.di.core.database.DatabaseMeta.findDatabaseInterface(DatabaseMeta.java:498)
at org.pentaho.di.core.database.DatabaseMeta.getDatabaseInterface(DatabaseMeta.java:474)
at org.pentaho.di.core.database.DatabaseMeta.setValues(DatabaseMeta.java:549)
... 34 more
При этом в kjb используется БД, вот только никакой не Oracle, а MSSQL.
Причина:
Не выполнена инициализация окружения Kettle, из-за этого срабатывают какие-то умолчания, в которых забит Oracle.
Решение:
KettleEnvironment.init();
суббота, 9 февраля 2013 г.
com.sun.xml.bind.v2.runtime.JAXBContextImpl cannot be cast to com.sun.xml.internal.bind.api.JAXBRIContext
Проблема:
Есть веб-приложение, которое тащит с собой (в WEB-INF/lib) api и имплементацию JAXB, а именно, jar-ники:
- jaxb-api.jar - версии 2.1
- jaxb-impl.jar - версии 2.1.4
В приложении используется JAX-WS клиент к веб-сервису. При попытке отправить с помощью него запрос валится:
java.lang.ExceptionInInitializerError
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:239)
...
Caused by: java.lang.ClassCastException: com.sun.xml.bind.v2.runtime.JAXBContextImpl cannot be cast to com.sun.xml.internal.bind.api.JAXBRIContext
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.<clinit>(SOAPFaultBuilder.java:488)
...
Что примечательно, проблема не воспроизводится на Tomcat 7, а вылезает только на Tomcat 6.
Причина:
Причина ClassCastException заключается в данном случае в том, что один класс (JAXBContextImpl) тянется из jaxb-impl в WEB-INF, а второй (JAXBRIContext) - из стандартной имплементации JAX-WS из JDK. Первый грузится ClassLoader`ом каталины, второй же - bootstrap`ом. Однако почему-то на 7ом томкате это не приводит с ClassCastException.
Решение:
Раз уже приложение идет со своим JAXB, то и JAX-WS придется также поставлять с ним. В моем случае это означало добавление в pom-ку зависимости:
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.4</version>
<scope>runtime</scope>
</dependency>
WSO2 ESB 4.5.1 + IBM WebSphere MQ 7.0.1.3: ошибка JMSCC0051 при попытке положить сообщения в очередь
Проблема:
Есть прокси сервис, перекладывающий сообщения из одной JMS-очереди в другую JMS-очередь (обе очереди на WebSphere MQ). При попытке положить сообщение в конечную очередь валится исключение:
com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0051: The property 'JMS_IBM_PutApplType' should be set using type 'java.lang.Integer', not 'java.lang.String'. JMS_IBM properties may only be set using a specific variable type. Correct application code to use the required variable type when setting this JMS_IBM property.
Решение:
Чистить транспортные заголовки перед отправкой на endpoint:
<property action="remove" name="TRANSPORT_HEADERS" scope="axis2"/>
Какой именно из транспортных заголовков мешает MQ, я не изучал.
WSO2 ESB + IBM WebSphere MQ: ошибки при передаче больших сообщений
Вот пара ошибок, которые могут возникнуть на WSO2 ESB при попытке положить большое сообщение в MQ:
1) MQRC_MSG_TOO_BIG_FOR_Q:
com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ2007: Failed to send a message to destination 'xxx'. JMS attempted to perform an MQPUT or MQPUT1; however WebSphere MQ reported an error. Use the linked exception to determine the cause of this error.
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:608)
....
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2030' ('MQRC_MSG_TOO_BIG_FOR_Q').
Тут все понятно - сработало ограничение на максимальный размер сообщения, установленное для очереди. Меняем ограничение на большее, радуемся.
2) MQRC_DATA_LENGTH_ERROR:
com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ2007: Failed to send a message to destination 'wso2test2'. JMS attempted to perform an MQPUT or MQPUT1; however WebSphere MQ reported an error. Use the linked exception to determine the cause of this error.
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:608)
...
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2010' ('MQRC_DATA_LENGTH_ERROR').
Причина этой ошибки менее очевидна и кроется в ограничении на максимальный размер сообщения, установленном для канала соединения с сервером. Увеличиваем:
и обязательно перезапускаем канал.
Также есть еще третье ограничение - ограничение на максимальный размер сообщения, устанавливаемое для администратора очередей.
вторник, 5 февраля 2013 г.
Java: определение, из какого файла загружен класс
При решении проблем с CLASSPATH бывает очень полезно знать, откуда таки загрузился тот или иной класс. Делается это так:
MyCalss.class.getProtectionDomain().getCodeSource().getLocation().getFile()
Форматтер для NetBeans, использующий Ecplise`овские конфиги
Собственно возникла необходимость в плагине для любимого IDE Netbeans 7.2.1, который форматировал бы исходники и при этом съедал конфигурационные файлы, предназначенные для Eclipse JDT.
После некоторых поисков нашел вообще универскальное решение: плагин для мавена, позволяющий форматировать исходники хоть из cmd: http://maven-java-formatter-plugin.googlecode.com/svn/site/0.3.1/usage.html. Конфигурируется он в pom:
<plugin>
<groupId>com.googlecode.maven-java-formatter-plugin</groupId>
<artifactId>maven-java-formatter-plugin</artifactId>
<version>0.3.1</version>
<configuration>
<configFile>Q:/my_formatter_config.xml</configFile>
</configuration>
</plugin>
Его вызов можно встроить в GUI Netbeans также, как и вызов любого гола maven, т.е. зайдя в Properties -> Actions -> Add Custom, выбрав имя (например, "Format"), и установив гол "com.googlecode.maven-java-formatter-plugin:maven-java-formatter-plugin:format". После этого форматирование исходников проекта выполняется через контекстное меню проекта:
Плагин позволяет, в том числе, задавать списки включаемых / исключаемых файлов:
<plugin>
<groupId>com.googlecode.maven-java-formatter-plugin</groupId>
<artifactId>maven-java-formatter-plugin</artifactId>
<version>0.3.1</version>
<configuration>
<configFile>Q:/my_formatter_config.xml</configFile>
<includes>
<include>**/Test*.java</include>
</includes>
</configuration>
</plugin>
Развертывание Carbon Application с помощью maven
Для автоматизации развертывания Carbon Application`ов на Carbon Server`ах (например, на WSO2 ESB) существует плагин maven-car-deploy-plugin, который, насколько мне известно, пока является экспериментальным. Настраивается он незамысловато:
<plugin>
<groupId>org.wso2.maven</groupId>
<artifactId>maven-car-deploy-plugin</artifactId>
<version>1.0.0</version>
<extensions>true</extensions>
<configuration>
<carbonServers>
<CarbonServer>
<trustStorePath>${basedir}/resources/security/wso2carbon.jks</trustStorePath>
<trustStorePassword>wso2carbon</trustStorePassword>
<trustStoreType>JKS</trustStoreType>
<serverUrl>https://localhost:9443</serverUrl>
<userName>admin</userName>
<password>admin</password>
<operation>deploy</operation>
</CarbonServer>
</carbonServers>
</configuration>
</plugin>
Собственно, для настройки нам необходимо задать URL сервера, логин / пароль, хранилище доверенных сертификатов для работы по HTTPS (можно взять тоже, что используется на сервере), а также операцию: deploy или unpdeploy. К сожалению, плагин предоставляет единственный гол: "org.wso2.maven:maven-car-deploy-plugin:deploy-car", а сама операция (deploy / undeploy) задается в конфигурации. Поэтому редеплой выполняется немного неочевидным способом, а именно, указанием одного и того же сервера дважды, с разными операциями:
<plugin>
<groupId>org.wso2.maven</groupId>
<artifactId>maven-car-deploy-plugin</artifactId>
<version>1.0.0</version>
<extensions>true</extensions>
<configuration>
<carbonServers>
<CarbonServer>
<trustStorePath>${basedir}/resources/security/wso2carbon.jks</trustStorePath>
<trustStorePassword>wso2carbon</trustStorePassword>
<trustStoreType>JKS</trustStoreType>
<serverUrl>https://localhost:9443</serverUrl>
<userName>admin</userName>
<password>admin</password>
<operation>undeploy</operation>
</CarbonServer>
<CarbonServer>
<trustStorePath>${basedir}/resources/security/wso2carbon.jks</trustStorePath>
<trustStorePassword>wso2carbon</trustStorePassword>
<trustStoreType>JKS</trustStoreType>
<serverUrl>https://localhost:9443</serverUrl>
<userName>admin</userName>
<password>admin</password>
<operation>deploy</operation>
</CarbonServer>
</carbonServers>
</configuration>
</plugin>
ЗЫ гол уже навешен на фазу Deploy, поэтому развертывание можно выполнять просто выполнением:
mvn clean deploy
в
00:58:00
0
коммент.
Отправить по электронной почтеНаписать об этом в блогеПоделиться в XОпубликовать в FacebookПоделиться в Pinterest
Ярлыки:
CAR,
Carbon Application,
deploy-car,
Maven,
Maven deploy CAR,
Maven redeploy CAR,
maven-car-deploy-plugin,
redeploy,
WSO2,
WSO2 Carbon,
WSO2ESB,
WSO2ESB 4.5.1
WSO2 ESB: объект какого типа возвращает mc.getPayloadXML() в script-медиаторе
mc.getPayloadXML() возвращает объект XML, определенный в ECMAScript for XML - расширении языка ECMAScript для работы с XML: http://www.mynajs.org/shared/docs/js/libOO/files/E4X-js.html#XML.
WSO2 ESB: ответ HTTP 411 Length Required от конечного сервиса
Проблема:
Некий сервис прокинут через WSO2 ESB. При вызове прокси-сервиса возвращается SOAP-Fault:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">, из чего следует, что конечный сервис ответил странным "411 Length Required", да ещё и с html в теле ответа. При вызове же конечного сервиса из soapUI приходит корректный ответ.
<soapenv:Body>
<soapenv:Fault>
<soapenv:Code>
<soapenv:Value>axis2ns4:</soapenv:Value>
</soapenv:Code>
<soapenv:Reason>
<soapenv:Text xml:lang="en">Unexpected response received. HTTP response code : 411 HTTP status : Length Required exception : First Element must contain the local name, Envelope , but found html</soapenv:Text>
</soapenv:Reason>
<soapenv:Detail/>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
Причина:
HTTP-код 411 говорит о том, что сервис требует, чтобы при его вызове был установлен заголовок "Content-Length". Шина же использует Chunked transfer encoding, не устанавливая этого заголовка. К сожалению, отключить chunked-encoding можно только переключив шину на использование HTTP 1.0 установкой свойства:
<property name="FORCE_HTTP_1.0" value="true" scope="axis2"/>перед отправкой запроса во входящей цепочке медиации.
воскресенье, 3 февраля 2013 г.
Maven Surefire + jUnit 4.x: запуск одного тестового метода
Свойство "test", задающее surefire`у имя тестового класса, позволяет также указать и имя метода, если нужно запустить не все тестовые методы, а только один из них. Делается это через "#" после имени класса:
mvn -Dtest=TestClass#myTest test
Можно также запускать несколько методов, разделяя их имена символом "+":
mvn -Dtest=TestClass#myTestOne+myTestTwo test
Или же вообще использовать регулярные выражения:
mvn -Dtest=TestClass#myTest* test(http://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html)
Подписаться на:
Сообщения (Atom)