运行exec:java时如何注册SPI实现 [英] How to register a SPI implementation when running exec:java

查看:49
本文介绍了运行exec:java时如何注册SPI实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 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-指标已设置为启用,但在类路径上未找到VertxMetricsFactory

我尝试了几种方法:

  • 添加 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><配置>< additionalClasspathElements>< element> $ {basedir}/src/main/resources</element></additionalClasspathElements>< mainClass> io.vertx.core.Launcher</mainClass>< commandlineArgs>运行$ {vertx.mainVerticle} -conf $ {vertx.config}</commandlineArgs>< systemProperties>< systemProperty>< key> vertx.logger-代理工厂类名称</key><值> io.vertx.core.logging.SLF4JLogDelegateFactory</值></systemProperty>< systemProperty>< key> vertx.metrics.options.enabled</key>< value> true</value></systemProperty></systemProperties></configuration></plugin>

这是起作用的 exec:exec 配置,,但是我想了解是否和为什么使用 exec可以(为什么)做到这一点:java

<代码><个人资料>< id> exec</id>< build>< plugins>< plugin>< groupId> org.codehaus.mojo</groupId>< artifactId> exec-maven-plugin</artifactId><执行><执行><目标>< goal> exec</goal></goals><阶段>处理类别</阶段>.<配置>< executable> java</executable>< arguments>< argument> -Dvertx.metrics.options.enabled = true</argument>< argument> -Dvertx.logger-代理工厂类名称= $ {vertx.logger-delegate-工厂类名称}</argument>< argument> -classpath</argument>< classpath/>< argument> io.vertx.core.Launcher</argument>< argument>运行</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 使用应用程序类加载器加载 META-INF/services 中列出的所有类.这就是为什么 ServiceLoader 在带有自定义类加载器(例如OSGi)的环境中经常不起作用的原因.

由于Maven为每个Maven插件构造了自己的类加载器,因此即使您声明包含SPI的编译时相关性,这些类也仅对Maven类加载器可见,而对应用程序类加载器不可见.

I'm trying to make VertX Mertrics work when running via the exec:java Maven plugin.

All works as expected when I package the application into a fatjar and run it with java -jar fat.jar -conf config.json -Dvertx.metrics.options.enabled=true

When I run it with mvn clean package exec:java -DskipTests I see: 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

I tried several approaches:

  • adding io.vertx:vertx-dropwizard-metrics:3.2.1 as compile dependency
  • create an in-house metrics implementation and register it by means of src/main/resources/META-INF/services/io.vertx.core.spi.VertxMetricsFactory file (double-checked that it's actually copied to target/classes/META-INF/services/io.vertx.core.spi.VertxMetricsFactory)
  • also adding ${basedir}/src/main/resources as additional classpath element (in addition to previous point)

I have double-checked in the debugger that ServiceLoader actually returns an empty iterator.

This is my exec-plugin config: <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>

Here is exec:exec configuration that does work, but I want to understand if and why it's (im-)possible to do it with 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>

解决方案

Did you try exec:exec instead of exec:java?

exec:exec runs in a separate process, and this might solve your problem.

ServiceLoader uses the application class loader to load any classes listed in META-INF/services. This is why ServiceLoader often does not work in environments with custom class loaders (e.g. OSGi).

Since Maven constructs its own class loader for each Maven plugin, even if you declare compile time dependencies containing your SPI, these classes will only be visible to the Maven class loader, but not to the application class loader.

这篇关于运行exec:java时如何注册SPI实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆