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

Groovy как скриптовый язык и DSL для Java

Мой первый хабрапост  Groovy как скриптовый язык и DSL для Java...
Читайте )

Читать далее

воскресенье, 4 октября 2009 г.

Использование Spring и IBM Websphere MQ в Java приложениях


Spring (Spring Framework)  - open source фреймворк для разработки приложений на Java.

IBM Websphere MQ  (MQSeries) - коммерческий продукт всем известной компании IBM для обмена сообщениями.

Данный текст в основном предназначен для разработчиков приложений на базе Spring и интересующимися  асинхронными средствами обмена.

Будем рассматривать отправку и прием сообщений из Websphere  MQ средствами Spring-Jms.



1. Создадим пустой maven проект spring-mq. Структура проекта будет следующей:

spring-mq\src\
spring-mq\src\main\
spring-mq\src\main\java\
spring-mq\src\main\resources\
spring-mq\src\test\
spring-mq\src\test\java\
spring-mq\src\test\resources\
spring-mq\pom.xml

2. В файле pom.xml  вы должны прописать зависимости к проектам spring-context, spring-jms, spring-test версий 2.5.5, jms 1.1, junit 4.4  и  к библиотекам ibm mqjms  и  dhbcore версии, соответствующей версии установленной у вас Websphere MQ (соответствие необязательно, если вы будете использовать клиентские соединения, см. далее).

Так как java библиотеки для MQ не выложены в репозиториях maven, вам это придется сделать самим, выложив их в свой локальный репозиторий. Библиотеки для MQ 5 и 6, сконфигурированные для maven можно здесь (4,3Мб) и распаковать их в каталог $maven_repository/com/ibm вашего репозитория .


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.smogg.samples</groupId>
<artifactId>spring-mq</artifactId>
<version>1.0</version>
<name>Spring with Websphere MQ sample</name>

<build>

<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>2.5.5</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>logkit</groupId>
<artifactId>logkit</artifactId>
</exclusion>
<exclusion>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>2.5.5</version>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>2.5.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ibm</groupId>
<artifactId>com.ibm.mqjms</artifactId>
<version>6.0.2.5</version>
<exclusions>
<exclusion>
<groupId>javax.naming</groupId>
<artifactId>jndi</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.ibm</groupId>
<artifactId>com.ibm.dhbcore</artifactId>
<version>6.0.2.5</version>
</dependency>
</dependencies>
</project>


3. Отправка сообщений. Создадим класс JMSSender в папке main/java пакете com.smogg.samples.springmq, который будет отправлять сообщения посредством JMS.   Код практически аналогичен коду, приведенному в документации по Spring-JMS (п 19.3)
package com.smogg.samples.springmq;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class JMSSender {
private JmsTemplate jmsTemplate;
public void sendMesage(final byte[] mess) {
System.out.println("Send message...");
jmsTemplate.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
BytesMessage byteMess = session.createBytesMessage();
byteMess.writeBytes(mess);
return byteMess;
}
});

}

public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}

@Required
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
}

4. Настроим получателя сообщений посредством xml конфигурации – нужно будет определить ConnectoinFactory и Destination.  Создадим файл beans-jms.xml в каталоге test\resources. Определяем ConnectionFactory:

<bean id="jmsFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="queueManager">
<value>TEST</value>
</property>
<property name="transportType" value="0" />
</bean>

TEST – имя локального менеджера очередей. transportType=0, означает что соединение будет в режиме BINDING (подробнее).
Для возможности работы с удаленным менеджером очередей, расположенным на другом компьютере, нужно указать transportType=1 (режим CLIENT) и указать hostName, channel и port:

<bean id="jmsFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="hostName">
<value>127.0.0.1</value>
</property>
<property name="queueManager">
<value>TEST</value>
</property>
<property name="channel">
<value>SVRCONN</value>
</property>
<property name="port">
<value>1415</value>
</property>
<property name="transportType" value="1" />
</bean>

Определяем настройки для Destination:

<bean id="sendDestination" class="com.ibm.mq.jms.MQQueue">
<property name="baseQueueName">
<value>QUEUE_IN</value>
</property>
</bean>

QUEUE_IN – имя очереди на менеджере TEST  в которую бедет производиться отправка.

Далее нужно настроить jmsTemplate  и jmsSender. jmsTemplate:

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<bean class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory">
<ref local="jmsFactory" />
</property>
</bean>
</property>
<property name="defaultDestination">
<ref bean="sendDestination" />
</property>
<property name="receiveTimeout">
<value>30000</value>
</property>
</bean>

jmsSender:

<bean id="jmsSender" class="com.smogg.samples.springmq.JMSSender">
<property name="jmsTemplate">
<ref bean="jmsTemplate" />
</property>
</bean>

Настройка для отправки сообщений завершена

5.  Напишем тест для проверки работоспособности. Напишем класс JMSTest в каталоге test/java пакете com.smogg.samples.springmq:
package com.smogg.samples.springmq;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/beans-jms.xml" })
public class JMSTest {
JMSSender jsmSender;

@Autowired
public void setJsmSender(JMSSender jsmSender) {
this.jsmSender = jsmSender;
}

@Test
public void testJMSSend() throws Exception {
String text = "123456";
jsmSender.sendMesage(text.getBytes());
}

}

Если все сконфигурировано правильно, то после запуска теста в указанной очереди появится новое сообщение.
Заметки по тесту:
@RunWith(SpringJUnit4ClassRunner.class)  - говорит JUnit,  что должен использоваться класс SpringJUnit4ClassRunner для запуска теста.
@ContextConfiguration(locations = { "/beans-jms.xml" })  - устанавливает для SpringJUnit4ClassRunner  какие настройки загружать
@Autowired  - устанавливает, что Spring должен  сам определить объект и установить его значение в класс

6. Прием сообщений. Для приема сообщний в Spring  используется подход, аналогичный MDB (message driven bean) из спецификации JEE, Message Driven POJO (MDP).
Это означает то, что вы должны создать класс реализующий методы javax.jms.MessageListener, т.е. в спецификации jms 1.1 это один метод "public void onMessage(Message message);"
Создадим наш класс для чтения сообщений – MessageListener в папке main/java пакете com.smogg.samples.springmq:
package com.smogg.samples.springmq;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;

public class MessageListener implements javax.jms.MessageListener {
public void onMessage(Message message) {
if (message instanceof BytesMessage) {
try {
byte[] byteMess = new byte[(int) ((BytesMessage) message).getBodyLength()];
((BytesMessage) message).readBytes(byteMess );
String mess = new String(byteMess );
System.out.println("Received message: "+ mess);

} catch (JMSException ex) {
throw new RuntimeException(ex);
}
} else {
throw new IllegalArgumentException(
"Message must be of type ByteMessage");
}
}

7. Настройка MessageListener.  Для того, чтобы  наш класс начал получать сообщений нужно произвести следующие настройки в   beans-jms.xml – создать бин MessageListener, создать jmsContainer. В jmsContainer вы должны укзать сonnectionFactory, destination и ссылку на наш MessageListener. ConnectionFactory мы будем использовать существующую. Настройки:

<!-- this is the Message Driven POJO (MDP) -->
<bean id="messageListener" class="com.smogg.samples.springmq.MessageListener" />

<!-- and this is the message listener container -->
<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory">
<bean class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory">
<ref local="jmsFactory" />
</property>
</bean>
</property>
<property name="destination" ref="sourceDestination" />
<property name="messageListener" ref="messageListener" />
</bean>
<bean id="sourceDestination" class="com.ibm.mq.jms.MQQueue">
<property name="baseQueueName">
<value>QUEUE_IN</value>
</property>
</bean>

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

8. Модифицируем наш тест для проверки приема сообщений:
package com.smogg.samples.springmq;
@Test
public void testJMSSend() throws Exception {
String text = "123456";
jsmSender.sendMesage(text.getBytes());
Thread.sleep(3000);
}

Если все настроено правильно, то после запуска теста в логе вы должны увидеть текст:
Send message...
Received message: 123456

9. Модифицируем MessageListener и тест для автоматической проверки работы. В MessageListener добавим 2 поля - счетчик и текст последнего сообщения и будем устанавливать их при приеме:

package com.smogg.samples.springmq;
static String readedMessage;
static int messageCount =0;

public static String getReadedMessage() {
return readedMessage;
}
public void onMessage(Message message) {
if (message instanceof BytesMessage) {
try {
byte[] byteMess = new byte[(int) ((BytesMessage) message).getBodyLength()];
((BytesMessage) message).readBytes(byteMess );
String mess = new String(byteMess );
//only for testing
incMessageCount();
readedMessage = mess;
System.out.println("Received message: "+ mess);

} catch (JMSException ex) {
throw new RuntimeException(ex);
}
} else {
throw new IllegalArgumentException(
"Message must be of type BytesMessage");
}
}
private static synchronized void incMessageCount() {
++messageCount;
}
public static int getMessageCount() {
return messageCount;
}

Модифицируем тест:

public void testJMSSend() throws Exception {
String text = "123456";
String sendText = "";
for (int i = 0; i < 10; i++) {
sendText = text + i;
jsmSender.sendMesage(sendText.getBytes());
}
Thread.sleep(3000);
Assert.assertEquals(10, MessageListener.getMessageCount());
Assert.assertEquals(sendText, MessageListener.getReadedMessage());

}

Теперь при запуске теста, если сообщения не будут считываться или отправляться, будет ошибка.

Скачать архив с проектом spring-mq.zip

Успехов всем.
Ссылки:
Дополнительная информация по Spring-jms
Websphere MQ

Читать далее

воскресенье, 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-проект.
Скачать файл с проектами

Читать далее