Как зарегистрировать реализацию 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, но не загрузчику классов приложения.