client_java
client_java copied to clipboard
Split package in simpleclient.servlet and simpleclient.pushgateway
Modules simpleclient.servlet
and simpleclient.pushgateway
are exporting classes from the same package io.prometheus.client.exporter
causing troubles when building Java modular applications due to a split package error:
java: the unnamed module reads package io.prometheus.client.exporter from both simpleclient.servlet and simpleclient.pushgateway
To reproduce the problem create a module-info.java
like this:
module test {
requires simpleclient.pushgateway;
requires simpleclient.servlet;
}
I'm not familiar with this, can you explain in exactly what systems this is a problem?
Renaming these would likely cause widespread breakage to existing code, so a split is not likely.
Basically you cannot build a modular Java application having a module which imports classes from both simpleclient.pushgateway
and simpleclient.servlet
modules
Here a repo reproducing the problem: https://github.com/Alexey1Gavrilov/java-module-issues/tree/master/promethues The compilation fails with the following error:
> mvn compile
...
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] the unnamed module reads package io.prometheus.client.exporter from both simpleclient.servlet and simpleclient.pushgateway
[ERROR] module simpleclient.pushgateway reads package io.prometheus.client.exporter from both simpleclient.servlet and simpleclient.pushgateway
[ERROR] module simpleclient.servlet reads package io.prometheus.client.exporter from both simpleclient.pushgateway and simpleclient.servlet
[ERROR] module simpleclient reads package io.prometheus.client.exporter from both simpleclient.servlet and simpleclient.pushgateway
[ERROR] /Users/agavrilov/Work/git/java-module-issues/promethues/src/main/java/module-info.java:[1,1] module javamodule.promethues reads package io.prometheus.client.exporter from both simpleclient.servlet and simpleclient.pushgateway
[INFO] 5 errors
A possible workaround for a modular application is to avoid importing from both in the one application module, ie have a two separate submodules requiring one of simpleclient.pushgateway
or simpleclient.servlet
.
Generally speaking splitting packages across .jar files should be avoided.
This SO question is a good source of info.
I think it makes sense to rename the package in a major version update. Should not cause much troubles to the users.
Ah, so this is yet another backwards incompatible change added in newer Java versions. As with all the other ways that Java is making supporting multiple versions challenging, I'm open to solutions that don't involve breaking existing users.
Should not cause much troubles to the users.
It's still a breaking change for something that affects presumably very few of them, considering this code has been here for 6 years and this is the first time this has come up.
I understand that changing the package name will have user impact but I believe making such a change in a major version update (like 1.0) is quite natural.
Even with a major version change, disruption should be minimised to only what is completely essential - and we're pre 1.0 anyway. Only if non-breaking ways to resolve this have been exhausted would a breaking change be considered.
Btw, this is also forbidden in OSGi since ever :) So at least if the client is used in an OSGi env this has never worked.
Two possible options to fix this would be
- Merge the two sub modules into one essentially eliminating the split package at the price of a higher footprint
- Actually keep both Jars, but offer a third variant with both. So if someone needs both the combined Jar can be used, while allowing consumers which only need one or the other to have their minimal footprint...
Hi, I've also found a similar problem when using simpleclient_hotspot and simpleclient_servlet on version 0.12.0 available from the maven repo.
My module info:
module test.prometheus {
requires simpleclient;
requires simpleclient.servlet;
requires simpleclient.hotspot;
}
Pom:
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.12.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_servlet</artifactId>
<version>0.12.0</version>
</dependency>
Error:
module test.prometheus reads package io.prometheus.client from both simpleclient and simpleclient.servlet
Note that this error is NOT present on version 0.11.0 (which I have rolled back to) - so it has been introduced in the newer version.
Thanks, Evynglais
I'm also having trouble using Prometheus in modular Java. There is a simple solution that would not break anyone. Just build a giant jar with everything in it and give it a proper module name like "io.prometheus.all". The split packages will all be unified and modular Java will be happy. My problem has to do with the activation dependency. Activation has been removed since Java 9. This Uber-jar could fix that problem too by simply relocating that package to another name with maven shading. Suggest creating a top-level project that builds last and does nothing but cram all the jars into one big jar with a module-info.java. Prometheus is pretty much a server thing. Probably people using Java 9+ care a lot more about easy integration than they do about jar file size. For myself, the jar size is not an issue.
module test.prometheus reads package io.prometheus.client from both simpleclient and simpleclient.servlet
I'm not familiar with the Java module system, but reading this message I'm wondering: Is it really necessary to read io.prometheus.client
from simpleclient_servlet
? The MetricsServlet
lives in io.prometheus.client.exporter
and the MetricsFilter
lives in io.prometheus.client.filter
. There is a helper class in io.prometheus.client
, but normally you would not use this directly. Is there a way of using simpleclient_servlet
with Java modules without reading io.prometheus.client
?