如何在 运行 exec:java 时注册 SPI 实现

How to register a SPI implementation when running exec:java

我正在尝试通过 exec:java Maven 插件使 VertX Mertrics 在 运行 时工作。

当我将应用程序打包到 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

我尝试了几种方法:

我在调试器中仔细检查 ServiceLoader 实际上 returns 是一个空迭代器。

这是我的执行插件配置: <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>

您是否尝试过 exec:exec 而不是 exec:java

exec:exec 在单独的进程中运行,这可能会解决您的问题。

ServiceLoader 使用应用程序 class 加载程序加载 META-INF/services 中列出的任何 classes。这就是为什么 ServiceLoader 通常无法在具有自定义 class 加载程序(例如 OSGi)的环境中工作。

由于 Maven 为每个 Maven 插件构建了自己的 class 加载器,即使您声明包含 SPI 的编译时依赖项,这些 classes 也只会对 Maven class 可见] 加载器,而不是应用程序 class 加载器。