Как зарегистрировать реализацию SPI при запуске exec:java

Я пытаюсь заставить VertX Mertrics работать при запуске через exec:java Плагин Maven.

Все работает как положено, когда я упаковываю приложение в FATJAR и запускаю его с java -jar fat.jar -conf config.json -Dvertx.metrics.options.enabled=true

Когда я запускаю его с mvn clean package exec:java -DskipTests Я вижу: 2016-03-22 18:39:58.833 WARN i.v.c.i.VertxImpl:348 - Metrics has been set to enabled but no VertxMetricsFactory found on classpath

Я попробовал несколько подходов:

  • добавление io.vertx:vertx-dropwizard-metrics:3.2.1 как зависимость компиляции
  • создать внутреннюю реализацию метрик и зарегистрировать ее с помощью src/main/resources/META-INF/services/io.vertx.core.spi.VertxMetricsFactory файл (дважды проверил, что он действительно скопирован в target/classes/META-INF/services/io.vertx.core.spi.VertxMetricsFactory)
  • также добавляя ${basedir}/src/main/resources как дополнительный элемент classpath (в дополнение к предыдущему пункту)

Я дважды проверил в отладчике, что ServiceLoader фактически возвращает пустой итератор.

Это мой конфиг exec-plugin: <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <configuration> <additionalClasspathElements> <element>${basedir}/src/main/resources</element> </additionalClasspathElements> <mainClass>io.vertx.core.Launcher</mainClass> <commandlineArgs>run ${vertx.mainVerticle} -conf ${vertx.config}</commandlineArgs> <systemProperties> <systemProperty> <key>vertx.logger-delegate-factory-class-name</key> <value>io.vertx.core.logging.SLF4JLogDelegateFactory</value> </systemProperty> <systemProperty> <key>vertx.metrics.options.enabled</key> <value>true</value> </systemProperty> </systemProperties> </configuration> </plugin>

Вот exec:exec Конфигурация, которая работает, но я хочу понять, если и почему (это) возможно сделать с exec:java

<profile> <id>exec</id> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <executions> <execution> <goals> <goal>exec</goal> </goals> <phase>process-classes</phase> <configuration> <executable>java</executable> <arguments> <argument>-Dvertx.metrics.options.enabled=true</argument> <argument>-Dvertx.logger-delegate-factory-class-name=${vertx.logger-delegate-factory-class-name}</argument> <argument>-classpath</argument> <classpath /> <argument>io.vertx.core.Launcher</argument> <argument>run</argument> <argument>${vertx.mainVerticle}</argument> <argument>-conf</argument> <argument>${vertx.config}</argument> </arguments> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile>

1 ответ

Ты пробовал exec:exec вместо exec:java?

exec:exec выполняется в отдельном процессе, и это может решить вашу проблему.

ServiceLoader использует загрузчик классов приложения для загрузки любых классов, перечисленных в META-INF/services, Вот почему ServiceLoader часто не работает в средах с пользовательскими загрузчиками классов (например, OSGi).

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

Другие вопросы по тегам