Процесс, порожденный exec-maven-plugin, блокирует процесс maven
Я пытаюсь выполнить следующий сценарий, используя maven:
- фаза предварительной интеграции: запуск приложения на основе Java с использованием основного класса (с использованием exec-maven-plugin)
- фаза интеграции: выполните тестовые примеры интеграции (используя maven-отказоустойчивый плагин)
- пост-интеграционная фаза: прекратить приложение изящно (с помощью exec-maven-plugin)
Вот pom.xml snip:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>launch-myApp</id>
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<arguments>
<argument>-DMY_APP_HOME=/usr/home/target/local</argument>
<argument>-Djava.library.path=/usr/home/other/lib</argument>
<argument>-classpath</argument>
<classpath/>
<argument>com.foo.MyApp</argument>
</arguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<forkMode>always</forkMode>
</configuration>
</plugin>
</plugins>
Если я выполняю mvn post-integration-test, мое приложение запускается как дочерний процесс процесса maven, но процесс приложения блокирует процесс maven от выполнения интеграционных тестов, которые появляются на следующем этапе. Позже я обнаружил, что в плагине maven exec есть ошибка (или недостающая функциональность?), Из-за которой процесс приложения блокирует процесс maven. Чтобы решить эту проблему, я инкапсулировал вызов MyApp.java в сценарий оболочки, а затем добавил "/dev/null 2> & 1 &", чтобы создать отдельный фоновый процесс. Вот снип (это только отскок, а не фактический) от runTest.sh:
java - DMY_APP_HOME =$2 com.foo.MyApp > /dev/null 2>&1 &
Хотя это решает мою проблему, есть ли другой способ сделать это? Мне не хватает аргументов для exec-maven-plugin?
Ответы
Ответ 1
В этом потоке есть возможное решение, использующее решение Ant: Возможное решение: Maven и Exec: разветвление процесса?
Тот же недостаток, что и в вашем текущем решении, заключается в том, что он также зависит от платформы. Ваше текущее решение будет работать только в среде Unix/Linux, в то время как решение на основе Ant запускает экземпляр cmd
, который работает только в Windows. Используя профили Maven, можно создать конфигурацию, в которой используется ОС, на которой она запущена, чтобы определить, какую командную оболочку нужно запускать, конечно.
Ответ 2
(Только для Unix) Используйте exec: exec и запустите скрипт. Этот сценарий должен вызывать
java -DMY_APP_HOME =$2 com.foo.MyApp > /dev/null 2>&1 &
во-первых, и проверить запуск до завершения скрипта. Сбой программы через 2 секунды?
Когда вашему java-приложению нужно какое-то время, вы можете добавить скрипт, ожидающий полного запуска.
retrymax=30
retry=0
RETURNCODE=1
while [ ${retry} -lt ${retrymax} ]; do
todo_your_test
RETURNCODE=$?
if [ ${RETURNCODE} -eq 0 ]; then
echo MyApp started
break
else
(( retry = retry + 1 ))
sleep 2
fi
done
exit ${RETURNCODE}
Ответ 3
Я использую https://github.com/bazaarvoice/maven-process-plugin плагин, пока эта проблема по-прежнему открыта https://github.com/mojohaus/exec-maven-plugin/issues/18
Ответ 4
Вы можете использовать параметр конфигурации async для достижения требуемого. Также см. AsyncDestroyOnShutdown, который по умолчанию отключит приложение на выходе JVM.
https://www.mojohaus.org/exec-maven-plugin/exec-mojo.html#async
Если установлено значение true, дочерний процесс выполняется асинхронно, а выполнение сборки продолжается параллельно.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>launch-myApp</id>
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<arguments>
<argument>-DMY_APP_HOME=/usr/home/target/local</argument>
<argument>-Djava.library.path=/usr/home/other/lib</argument>
<argument>-classpath</argument>
<classpath/>
<argument>com.foo.MyApp</argument>
</arguments>
<async>true</async>
</configuration>
</plugin>