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:
io.vertx:vertx-dropwizard-metrics:3.2.1
as compile dependencysrc/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
)${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.