Статьи

Весенняя партия как модуль Wildfly

Долгое время в спецификации Java EE отсутствовал API пакетной обработки. Сегодня это крайне необходимо для корпоративных приложений. Наконец, это было исправлено с помощью пакетных приложений JSR-352 для платформы Java, которые теперь доступны в Java EE 7. JSR-352 получил вдохновение от аналога Spring Batch . Оба охватывают одни и те же понятия, хотя получающиеся API немного отличаются.

Поскольку команда Spring также сотрудничала в JSR-352 , для них было только вопросом времени предоставить реализацию, основанную на Spring Batch . Последняя основная версия Spring Batch (версия 3) теперь поддерживает JSR-352 .

Я много лет пользуюсь Spring Batch, и мне всегда нравилось, что у этой технологии был интересный набор встроенных читателей и писателей. Это позволило вам выполнять самые распространенные операции, необходимые для пакетной обработки. Вам нужно читать данные из базы данных? Вы можете использовать JdbcCursorItemReader , как насчет записи данных в фиксированном формате? Используйте FlatFileItemWriter и так далее.

К сожалению, реализации JSR-352 не имеют такого количества читателей и писателей, которые доступны в Spring Batch . Мы должны помнить, что JSR-352 появился совсем недавно и не успел наверстать упущенное. jBeret , реализация Wildfly для JSR-352 уже предоставляет несколько пользовательских программ для чтения и записи.

В чем смысл?

Я надеялся, что с последним выпуском все читатели и писатели из оригинальной Spring Batch также будут доступны. Это еще не так, поскольку потребуется много работы, но есть планы сделать их доступными в будущих версиях. Это позволило бы нам перенести собственные приложения Spring Batch в JSR-352 . У нас все еще есть проблема блокировки реализации реализации, но в некоторых случаях это может быть интересно.

мотивация

Я являюсь одним из основных разработчиков тестов для примеров Java EE в спецификации JSR-352 . Я хотел выяснить, имеют ли тесты, которые я реализовал, то же самое поведение, используя реализацию Spring Batch . Как мы можем сделать это?

Код

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

Добавление модуля Wildfly с Maven

Немного поработав, можно автоматически добавить модуль с помощью плагина Wildfly Maven и CLI (командной строки). Давайте начнем создавать два файла, которые представляют команды CLI, которые нам нужны для создания и удаления модуля:

wildfly-add-spring-batch.cli

wildfly-надстройка весна-batch.cli

1
2
3
4
5
6
7
8
9
# Connect to Wildfly instance
connect
 
# Create Spring Batch Module
# If the module already exists, Wildfly will output a message saying that the module already exists and the script exits.
module add \
    --name=org.springframework.batch \
    --dependencies=javax.api,javaee.api \
    --resources=${wildfly.module.classpath}

Модуль --name важен. Нам понадобится ссылка для ссылки в нашем приложении. --resources--resources , так как вам нужно указать полный путь к классу для всех необходимых зависимостей модуля, но мы создадим пути в следующих нескольких шагах.

wildfly-remove-spring-batch.cli

wildfly-удалить-весенне-batch.cli

1
2
3
4
5
# Connect to Wildfly instance
connect
 
# Remove Oracle JDBC Driver Module
module remove --name=org.springframework.batch

Обратите внимание на wildfly.module.classpath . Это свойство будет содержать полный путь к классу для необходимых зависимостей Spring Batch . Мы можем сгенерировать его с помощью плагина Maven Dependency :

П-Maven-зависимость-plugin.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>${version.plugin.dependency}</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>build-classpath</goal>
            </goals>
            <configuration>
                <outputProperty>wildfly.module.classpath</outputProperty>
                <pathSeparator>:</pathSeparator>
                <excludeGroupIds>javax</excludeGroupIds>
                <excludeScope>test</excludeScope>
                <includeScope>provided</includeScope>
            </configuration>
        </execution>
    </executions>
</plugin>

Это javax выбрать все зависимости (включая транзитивные), исключить javax (поскольку они уже присутствуют в Wildfly ) и исключить зависимости области test . Нам нужны следующие зависимости для Spring Batch :

П-dependencies.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!-- Needed for Wildfly module -->
<dependency>
    <groupId>org.springframework.batch</groupId>
    <artifactId>spring-batch-core</artifactId>
    <version>3.0.0.RELEASE</version>
    <scope>provided</scope>
</dependency>
 
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.0.5.RELEASE</version>
    <scope>provided</scope>
</dependency>
 
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
    <scope>provided</scope>
</dependency>
 
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <version>2.3.2</version>
    <scope>provided</scope>
</dependency>

Теперь нам нужно заменить свойство в файле. Давайте использовать плагин Maven Resources :

П-Maven-ресурсы-plugin.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>${version.plugin.resources}</version>
    <executions>
        <execution>
            <id>copy-resources</id>
            <phase>process-resources</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <outputDirectory>${basedir}/target/scripts</outputDirectory>
                <resources>
                    <resource>
                        <directory>src/main/resources/scripts</directory>
                        <filtering>true</filtering>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

Это отфильтрует настроенные файлы и заменит свойство wildfly.module.classpath на значение, которое мы сгенерировали ранее. Это путь к классу, указывающий на зависимости в вашем локальном репозитории Maven. Теперь с плагином Wildfly Maven мы можем выполнить этот скрипт (вам нужно запустить Wildfly ):

ПОМ-Maven-wildfly-plugin.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<plugin>
    <groupId>org.wildfly.plugins</groupId>
    <artifactId>wildfly-maven-plugin</artifactId>
    <version>${version.plugin.wildfly}</version>
    <configuration>
        <skip>false</skip>
        <executeCommands>
            <batch>false</batch>
            <scripts>
                <!--suppress MavenModelInspection -->
                <script>target/scripts/${cli.file}</script>
            </scripts>
        </executeCommands>
    </configuration>
</plugin>

И эти профили:

П-profiles.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<profiles>
    <profile>
        <id>install-spring-batch</id>
        <properties>
            <cli.file>wildfly-add-spring-batch.cli</cli.file>
        </properties>
    </profile>
 
    <profile>
        <id>remove-spring-batch</id>
        <properties>
            <cli.file>wildfly-remove-spring-batch.cli</cli.file>
        </properties>
    </profile>
</profiles>

(Для полного содержания pom.xml , проверьте здесь )

Мы можем добавить модуль, выполнив:
mvn process-resources wildfly:execute-commands -P install-spring-batch .

Или удалите модуль, выполнив:
mvn wildfly:execute-commands -P remove-spring-batch .

Эта стратегия работает для любого модуля, который вы хотите создать в Wildfly . Подумайте о добавлении драйвера JDBC. Обычно вы используете модуль для добавления его на сервер, но вся документация, которую я нашел по этому поводу, всегда выполняется вручную. Это прекрасно работает для сборок CI, поэтому вы можете иметь все необходимое для настройки вашей среды.

Использовать Spring-Batch

Хорошо, у меня есть мой модуль, но как я могу проинструктировать Wildfly использовать его вместо jBeret ? Нам нужно добавить следующий файл в папку META-INF нашего приложения:

jboss-deployment-structure.xml

JBoss развертывания-structure.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
        <exclusions>
            <module name="org.wildfly.jberet"/>
            <module name="org.jberet.jberet-core"/>
        </exclusions>
 
        <dependencies>
            <module name="org.springframework.batch" services="import" meta-inf="import"/>
        </dependencies>
    </deployment>
</jboss-deployment-structure>

Поскольку JSR-352 использует загрузчик служб для загрузки реализации, единственным возможным результатом будет загрузка службы, указанной в модуле org.springframework.batch . Ваш пакетный код теперь будет работать с реализацией Spring Batch .

тестирование

Код репозитория github содержит примеры тестов Arquillian , демонстрирующие поведение. Проверьте раздел Ресурсы ниже.

Ресурсы

Вы можете клонировать полную рабочую копию из моего репозитория github. Вы можете найти там инструкции по его развертыванию.

Wildfly — Весенняя партия

Поскольку я могу изменить код в будущем, вы можете скачать исходный код этого поста с версии 1.0 . В качестве альтернативы клонируйте репозиторий и извлеките тег из выпуска 1.0 с помощью следующей команды: git checkout 1.0 .

Будущее

Мне все еще нужно применить это к образцам Java EE . Это в моем списке TODO.

Ссылка: Spring Batch as Wildfly Module от нашего партнера JCG Роберто Кортеса в блоге