Процесс, порожденный exec-maven-plugin, блокирует процесс maven

Я пытаюсь выполнить следующий сценарий, используя maven:

  1. фаза предварительной интеграции: запуск приложения на основе Java с использованием основного класса (с использованием exec-maven-plugin)
  2. фаза интеграции: выполните тестовые примеры интеграции (используя maven-отказоустойчивый плагин)
  3. пост-интеграционная фаза: прекратить приложение изящно (с помощью 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}

Ответ 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>