barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

воскресенье, 24 февраля 2013 г.

DFC: единицы измерения таймаута в IDfSession.getLoginTicketEx()

JavaDoc по  DFC скромно сообщает, что параметр timeout метода IDfSession.getLoginTicketEx() - это "How long will acquired loigin ticket remain valid since generation". При этом про единицы измерения таймаута не говорится ни слова. Экспериментальным путем удалось определить, что измеряется таймаут в минутах.

вторник, 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)
at com.google.gdata.client.GoogleAuthTokenFactory.getAuthException(GoogleAuthTokenFactory.java:628)
... 
Почитал http://apiblog.youtube.com/2011/03/clientlogin-fail.html, ничего такого, что помогло бы в моем случае, там не нашел.

Решение:

Пользователь ни разу не загружал видео на 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();