如何在 运行 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
我尝试了几种方法:
- 添加
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
作为附加的类路径元素(除了上一点)
我在调试器中仔细检查 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 加载器。
我正在尝试通过 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
我尝试了几种方法:
- 添加
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
作为附加的类路径元素(除了上一点)
我在调试器中仔细检查 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 加载器。