воскресенье, 2 августа 2009 г.

Oracle OC4J 10.1.3.3 и IBM Websphere MQ 6

Хотел поделиться опытом настройки OC4J (Oracle Containers for J2EE) для подключения к системе обмена сообщениями Websphere MQ 6.

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

До выхода WMQ 6, для подключения Oc4J к WMQ, мы использовали несколько модифицированный адаптер oraclejms (поставляется с Oc4j), jndi файлы с настройками очередей. Так же приходилось патчить класслоадер OC4J. В WMQ 6, начиная, кажется, с версии 6.0.2.5 появился JCA 1.5 адаптер для подключения java приложений к WMQ. Вот его я и решил попробовать использовать.

Итак, задача такая. Нужно научить JEE приложение читать сообщения из очередей WMQ и отправлять в WMQ.



Последовательность шагов такая:

  1. Подготавливаем архив с адаптером ресурсов WMQ и устанавливаем его в OC4J.
  2. Настраиваем коннектор в OC4J.
  3. Настраиваем приложение на данный адаптер ресурсов

Подготовка адаптера ресурсов к WMQ для OC4J.

1. Файл с адаптером находится в каталоге WMQ\Java\lib\jca\wmq.jmsra.rar. Нужно создать файл oc4j-ra.xml и поместить его внутутрь wmq.jmsra.rar в каталог META-INF

Файл oc4j-ra.xml:

<oc4j-connector-factories xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://xmlns.oracle.com/oracleas/schema/oc4j-connector-factories-10_0.xsd"
schema-major-version="10"
schema-minor-version="0">
<connector-factory location="WMQ/QueueConnectionFactory" connector-name="WMQ">
<config-property name="CCSID" value="1208"/>
<config-property name="channel" value="SRV.CONN"/>
<config-property name="failIfQuiesce" value="true"/>
<config-property name="hostName" value="127.0.0.1"/>
<config-property name="port" value="1414"/>
<config-property name="queueManager" value="TESTQMGR"/>
<config-property name="transportType" value="BINDINGS"/>
<config-property name="sslResetCount" value="1"/>
<connectionfactory-interface>javax.jms.QueueConnectionFactory</connectionfactory-interface>
</connector-factory>
<connector-factory location="WMQ/XAQueueConnectionFactory" connector-name="WMQ">
<config-property name="CCSID" value="1208"/>
<config-property name="channel" value="SRV.CONN"/>
<config-property name="failIfQuiesce" value="true"/>
<config-property name="hostName" value="127.0.0.1"/>
<config-property name="port" value="1414"/>
<config-property name="queueManager" value="TESTQMGR"/>
<config-property name="transportType" value="BINDINGS"/>
<config-property name="sslResetCount" value="1"/>
<connectionfactory-interface>javax.jms.QueueConnectionFactory</connectionfactory-interface>
</connector-factory>
</oc4j-connector-factories>


Параметры:
WMQ – имя адаптера ресурсов,
WMQ/QueueConnectionFactory (XAQueueConnectionFactory) – имя фабрики для соединения с WMQ,
TESTQMGR – имя менеджера очередей

2. Нужно скопировать следующие библиотеки из WMQ\java\lib в OC4J\j2ee\home\applib и перезапустить OC4J:
* com.ibm.mq.jar
* com.ibm.mqjms.jar
* dhbcore.jar
* mqconnector.jar

3. Через консоль администрирования установить wmq.jmsra.rar.

Настройка коннектора в OC4J.
Далее, нужно настроить адаптер, прописав нужные параметеры с файле oc4j-connectors.xml:

<connector name="WMQ" path="WMQ.rar">
<security-permission enabled="false">
<description>Security Permissions for the JMS client</description>
<security-permission-spec>grant {
permission java.security.AllPermission;
};</security-permission-spec>
</security-permission>
<config-property name="connectionConcurrency" value="10"/>
<config-property name="maxConnections" value="30"/>
<config-property name="logWriterEnabled" value="true"/>
<config-property name="reconnectionRetryCount" value="5"/>
<config-property name="reconnectionRetryInterval" value="300000"/>
<config-property name="timestampsEnabled" value="true"/>
<config-property name="traceDestination" value="wmq_jms.log"/>
<config-property name="traceEnabled" value="true"/>
<config-property name="traceLevel" value="10"/>
<adminobject-config location="WMQ/MQTest">
<adminobject-class>com.ibm.mq.connector.outbound.MQQueueProxy</adminobject-class>
<config-property name="encoding" value="NATIVE"/>
<config-property name="expiry" value="UNLIMITED"/>
<config-property name="baseQueueName" value="TESTQ"/>
<config-property name="failIfQuiesce" value="true"/>
<config-property name="targetClient" value="MQ"/>
<config-property name="baseQueueManagerName" value="TESTQMGR"/>
<config-property name="CCSID" value="1208"/>
<config-property name="priority" value="QDEF"/>
<config-property name="persistence" value="PERS"/>
<config-property name="port" value="1414"/>
</adminobject-config>
...


Основные параметры, которые вам нужно будет поменять – это baseQueueManagerName (имя менеджера), baseQueueName (имя очереди), adminobject-config location (имя в JNDI)


После изменения фала нужно перезапустить OC4J перед установкой JEE приложения.

Настройка приложения


Настройка приложения на чтение, сводится к настройке MDB бина, прописыванием правильного activation-config.
Пример настройки:

@MessageDriven
(name = "GeneralTransportMQBean",
activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue ="TESTQ"),
@ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "false"),
@ActivationConfigProperty(propertyName = "hostName", propertyValue = "127.0.0.1"),
@ActivationConfigProperty(propertyName = "port", propertyValue = "1414"),
@ActivationConfigProperty(propertyName = "channel", propertyValue = "SRV.CONN"),
@ActivationConfigProperty(propertyName = "queueManager", propertyValue = "TESTQMGR"),
@ActivationConfigProperty(propertyName = "transportType", propertyValue = "BINDINGS")
})
@MessageDrivenDeployment(resourceAdapter = "WMQ")

public class TestMQBean implements MessageListener{…


Тут, вроде бы, все ясно, где какой параметр.
Если хочется, чтобы настройки на очередь находились вне приложения и их можно было менять без пересборки, то можно прописать конфиг с использованием JNDI:

@MessageDriven
(name = "TestMQBean",
activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "WMQ/MQTest"),
@ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true")
})
@MessageDrivenDeployment(resourceAdapter = "WMQ")
public class TestMQBean implements MessageListener{…



В принципе, вот и все - приложение готово для установки.

И еще, чтобы при ошибках обработки сообщения помещались из очереди TESTQ в другую очередь, например, очередь ошибочных сообщений, нужно в натройках MQ для очереди TESTQ указать "Backout threshold" (количество повторов обработки) и "Backout requeue queue" (имя очереди).
ps: При использовании JNDI имеется ряд проблем, которые мешают полноценно использовать конфигурацию в JNDI. Подробно проблему и ее решение я описывал на форуме mqseries.net - MQ 6.0.2.7 JCA 1.5 and OC4J. Problems and Solutions

Читать далее

пятница, 26 июня 2009 г.

Castor XML - WTF?

Castor XML - это библиотека для преобразования XML в Java объекты и обратно. Как ее использовать, может я еще напишу, позже. А в этой заметке хотел рассказать, что я увидел в исходниках, когда пытался отладить свою программу.
Так вот, при преобразовании XML в программе возникала ошибка внутри Castor в методе UnmarshallHandler.startElement, поставил я в нем брекпойнт и давай пошагово выполнять... Прошагал в отладке один экран исходника, второй, тут я не выдержал и давай листать... И что бы вы думали - в одном методе более 900 строк!!! WTF?
ps: После такого, вообще говоря, с опасением смотришь на этот продукт, а стоит ли такое чудо использовать...
Читать далее

суббота, 2 мая 2009 г.

Создание Web-сервиса в Java

Рассмотрим пример создания простого WEB-сервиса. Инструментов для создания WEB-сервисов в Java достаточно много, мы же будем использовать XFire. XFire - это Java SOAP фреймфорк, быстрый, расширяемый и т.д. Что для нас сейчас важно, так это то, что создать WEB-сервис "с нуля" можно достаточно просто.
Наш WEB-сервис будет совсем простой, а именно, будет иметь один метод без параметров и возвращать строку, например, "Привет - это WEB-сервис"

  1. Для начала нужно подготовить инфраструктуру проектов, как описано в предыдущей статье -"Создание проектов с помощью maven".


  2. Определим интерфейс (HelloService) и реализацию (HelloServiceImpl) сервиса в проекте SimpleLogic, разместим их в пакете com.dom.ws
    HelloService.java

    package com.dom.ws;

    public interface HelloService {
    public String getHello();
    }

    HelloServiceImpl.java

    package com.dom.ws;

    public class HelloServiceImpl implements HelloService {

    public String getHello() {
    return "Привет - это WEB-сервис!";
    }

    }
  3. В файл SimpleWEB\pom.xml добавим зависимости XFire

    <dependency>
    <groupId>org.codehaus.xfire</groupId>
    <artifactId>xfire-jaxb2</artifactId>
    <version>1.1.1</version>
    </dependency>
    <dependency>
    <groupId>org.codehaus.xfire</groupId>
    <artifactId>xfire-spring</artifactId>
    <version>1.1.1</version>
    </dependency>
    <dependency>
    <groupId>org.codehaus.xfire</groupId>
    <artifactId>xfire-java5</artifactId>
    <version>1.1.1</version>
    </dependency>
  4. Настроим XFire на публикацию нашего сервиса в виде WEB-сервиса.
    Создаем папку SimpleWEB\src\main\resources\META-INF\xfire и в ней файл services.xml следующего содержания:
    <beans xmlns="http://xfire.codehaus.org/config/1.0">
    <service>
    <name>HelloService</name>
    <namespace>http://localhost/HelloService</namespace>
    <serviceClass>com.dom.ws.HelloService</serviceClass>
    <implementationClass>com.dom.ws.HelloServiceImpl</implementationClass>
    </service>
    </beans>
  5. Настроим обработчики Xfire в SimpleWEB\src\main\webapp\WEB-INF\web.xml. Полный текст web.xml
    <!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

    <web-app>

    <servlet>
    <servlet-name>XFireServlet</servlet-name>
    <display-name>XFire Servlet</display-name>
    <servlet-class>
    org.codehaus.xfire.transport.http.XFireConfigurableServlet
    </servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>XFireServlet</servlet-name>
    <url-pattern>/servlet/XFireServlet/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
    <servlet-name>XFireServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
    </web-app>
  6. Сервис написан, Xfire сконфигурирован. Собираем проект. В каталоге ${work}\parent выполняем комманду:
    mvn package
  7. Установим наше приложение в Tomcat. Приложение находится здесь - SimpleWEB\target\SimpleWEB.war
  8. Доступ к WEB-сервису можно получить по следующему адресу "http://localhost:8080/SimpleWEB/services/HelloService?WSDL"


Скачать файл с проектом

Ссылки:
XFire - быстрый старт
XFire + Maven


Читать далее

Java. Создание и сборка проектов с помощью Maven на примере Web-проекта

Maven - средство для управления программным проектом - сборка, тестирование, генерация отчетов и т.д. Имеет большое количество плагинов для разных целей.

Рассмотрим, как с помощью maven можно создать и собрать проект.
В качестве примера возьмем пример Web-приложения имеющего 2 модуля, собственно сам WEB-проект (SimpleWEB) и модуль (SimpleLogic), в котором будет находиться логика.

Первое, что нам нужно сделать, это настроить maven. Полную инструкцию можно прочитать на сайте maven. Краткое описание:
  1. Скачаваем дистрибутив с сайта maven. В нашем примере, версия 2.0.9.
  2. Распаковываем на диск, например в c:\tools\apache-maven (в дальнейшем, ${maven.home})
  3. Прописываем в системную переменную "path" путь к bin каталогу ${maven.home}\bin
  4. Можно поменять путь к репозиторию (хранилищу) библиотек на свой (по-умолчанию будет использоватья каталог ${user.home}/.m2/repository) - в файле ${maven.home}\conf\settings.xml прописать элелемент localRepository в разделе settings, например <localrepository>c:/tools/MavenRepository</localrepository>
Создание проектов.
  1. Создаем каталог, например, c:\work\java\Simple\ (в дальнейшем - ${work}).
  2. Запускаем консоль в этом каталоге или делаем в консоле этот каталог текущим.
  3. Создание проекта SimpleWEB
    Создание проекта с помощью maven производится командой
    mvn archetype:create -DgroupId=<groupid> -DartifactId=<artifactid> -DarchetypeArtifactId=<archetypeartifactid>,
    где groupID - ваш идентификатор группы проектов, он же будет использован для создания пакета по-умолчанию, например, groupID=com.dom.simple,
    artifactId - имя проекта , например SimpleWEB,
    archetypeArtifactId - тип проекта, если не задан, то будет создан jar проект

    Выполняем следующую команду:
    mvn archetype:create -DgroupId=com.dom.simple -DartifactId=SimpleWEB -DarchetypeArtifactId=maven-archetype-webapp


  4. Создание проекта SimpleLogic. Выполняем команду:
    mvn archetype:create -DgroupId=com.dom.simple -DartifactId=SimpleLogic

  5. Укажем что проект SimpleWEB зависит от SimpleLogic - в файле {work}\SimpleWEB\pom.xml в разделе "dependencies" прописать новую зависимость:

    <dependency>
    <groupId>com.dom.simple</groupId>
    <artifactId>SimpleLogic</artifactId>
    <version>1.0-SNAPSHOT</version>
    </dependency>

  6. Обычно, при использовании maven, создается еще один проект, который содержит в себе ссылки на все остальные проекты. Назовем его "parent". Выполняем комманду:
    mvn archetype:create -DgroupId=com.dom.simple -DartifactId=parent
    Далее нужно:
    • В ${work}\parent\pom.xml в "jar" заменить "jar" на "pom"
    • Блок "dependencies" можно удалить
    • Прописать блок "modules" с сылками на другие проекты

      <modules>
      <module>../SimpleLogic</module>
      <module>../SimpleWeb</module>
      </modules>

  7. Проверим как собираются наши проекты. В каталоге ${work}\parent выполняем комманду:
    mvn package
    Если все сделали правильно, то проекты собирутся успешно и в каталоге "${work}\SimpleWEB\target" будет создан файл "SimpleWEB.war" который содержит наш проект SimpleWEB и внутрь war фала также помещен SimpleLogic.jar
  8. Созданный при сборке war файл можно публиковать, например, в Tomcat.


  9. Все, инфраструктура проектов создана, проекты собираются. Можно писать логику, добавлять странички и с помощью команды "mvn package" собирать web-проект.
Скачать файл с проектами

Читать далее