Open michalcukierman opened 1 year ago
The issue had no activity for 30 days, mark with Stale label.
What is the impact of the deprecated annotations library?
In the Pulsar code base, there are some dependencies to javax libraries due to Jetty 9.4.x dependencies. It could be useful to first upgrade to Jetty 12 (#22939) and then migrating to use Jakarta annotations and libraries (Servlet) during that. The reason for this is that in Pulsar, all dependencies are in a flat classpath structure.
To use this with Quarkus, you’ll need to add the following dependency:
<!-- Use an alternative package because Quarkus excludes javax.annotation-api after build -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-annotations-api</artifactId>
</dependency>
This is necessary because javax.annotation-api
is removed from the build artifact by Quarkus.
What's more - the annotation API is often available in recent versions (using Jakarta) in the project classpaths, so relying on the deprecated javax.annotation
can be inconvenient.
Although this isn’t a critical issue, I believe it may make it progressively more challenging to integrate admin-client with codebases over time.
To use this with Quarkus, you’ll need to add the following dependency:
<!-- Use an alternative package because Quarkus excludes javax.annotation-api after build --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-annotations-api</artifactId> </dependency>
This is necessary because
javax.annotation-api
is removed from the build artifact by Quarkus. What's more - the annotation API is often available in recent versions (using Jakarta) in the project classpaths, so relying on the deprecatedjavax.annotation
can be inconvenient.Although this isn’t a critical issue, I believe it may make it progressively more challenging to integrate admin-client with codebases over time.
@michalcukierman what's the impact if you don't specify this library? do you get some error message or does something fail? Please share the possible error message to make it searchable.
Jakarta migration dev mailing list thread: https://lists.apache.org/thread/dp2zkqxorqpwsjg2yjmmqgq4lrfst1r8
Without tomcat annotations-api, the exception is thrown at runtime:
2024-11-02 19:13:51 INFO exec -a "java" java -XX:MaxRAMPercentage=80.0 -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:+ExitOnOutOfMemoryError -Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager -cp "." -jar /deployments/quarkus-run.jar
2024-11-02 19:13:51 INFO running in /deployments
2024-11-02 19:13:51 __ ____ __ _____ ___ __ ____ ______
2024-11-02 19:13:51 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
2024-11-02 19:13:51 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
2024-11-02 19:13:51 --\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2024-11-02 19:13:51 2024-11-02 18:13:51,648 WARN [io.qua.config] (main) Unrecognized configuration key "quarkus.http.host" was provided; it will be ignored; verify that the dependency extension for this configuration is set or that you did not make a typo
2024-11-02 19:13:51 2024-11-02 18:13:51,738 INFO [dev.str.pul.ini.PulsarInitializer] (main) Starting Pulsar initialization
2024-11-02 19:13:51 2024-11-02 18:13:51,766 ERROR [io.qua.run.Application] (main) Failed to start application: java.lang.RuntimeException: Failed to start quarkus
2024-11-02 19:13:51 at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
2024-11-02 19:13:51 at io.quarkus.runtime.Application.start(Application.java:101)
2024-11-02 19:13:51 at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:119)
2024-11-02 19:13:51 at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
2024-11-02 19:13:51 at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
2024-11-02 19:13:51 at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
2024-11-02 19:13:51 at io.quarkus.runner.GeneratedMain.main(Unknown Source)
2024-11-02 19:13:51 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2024-11-02 19:13:51 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
2024-11-02 19:13:51 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2024-11-02 19:13:51 at java.base/java.lang.reflect.Method.invoke(Method.java:568)
2024-11-02 19:13:51 at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:62)
2024-11-02 19:13:51 at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:33)
2024-11-02 19:13:51 Caused by: java.lang.NoClassDefFoundError: javax/annotation/Priority
2024-11-02 19:13:51 at org.glassfish.jersey.JerseyPriorities.getPriorityValue(JerseyPriorities.java:48)
2024-11-02 19:13:51 at org.glassfish.jersey.model.internal.CommonConfig$FeatureRegistration.priority(CommonConfig.java:133)
2024-11-02 19:13:51 at org.glassfish.jersey.model.internal.CommonConfig$FeatureRegistration.<init>(CommonConfig.java:118)
2024-11-02 19:13:51 at org.glassfish.jersey.model.internal.CommonConfig$FeatureRegistration.<init>(CommonConfig.java:106)
2024-11-02 19:13:51 at org.glassfish.jersey.model.internal.CommonConfig.processFeatureRegistration(CommonConfig.java:505)
2024-11-02 19:13:51 at org.glassfish.jersey.model.internal.CommonConfig.register(CommonConfig.java:412)
2024-11-02 19:13:51 at org.glassfish.jersey.client.ClientConfig$State.register(ClientConfig.java:217)
2024-11-02 19:13:51 at org.glassfish.jersey.client.ClientConfig.register(ClientConfig.java:616)
2024-11-02 19:13:51 at org.apache.pulsar.client.admin.internal.PulsarAdminImpl.<init>(PulsarAdminImpl.java:133)
2024-11-02 19:13:51 at org.apache.pulsar.client.admin.internal.PulsarAdminBuilderImpl.build(PulsarAdminBuilderImpl.java:45)
2024-11-02 19:13:51 at dev.streamx.pulsar.init.PulsarInitializer.init(PulsarInitializer.java:56)
2024-11-02 19:13:51 at dev.streamx.pulsar.init.PulsarInitializer_Bean.doCreate(Unknown Source)
2024-11-02 19:13:51 at dev.streamx.pulsar.init.PulsarInitializer_Bean.create(Unknown Source)
2024-11-02 19:13:51 at dev.streamx.pulsar.init.PulsarInitializer_Bean.create(Unknown Source)
2024-11-02 19:13:51 at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:119)
2024-11-02 19:13:51 at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:38)
2024-11-02 19:13:51 at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:35)
2024-11-02 19:13:51 at io.quarkus.arc.generator.Default_jakarta_enterprise_context_ApplicationScoped_ContextInstances.c1(Unknown Source)
2024-11-02 19:13:51 at io.quarkus.arc.generator.Default_jakarta_enterprise_context_ApplicationScoped_ContextInstances.computeIfAbsent(Unknown Source)
2024-11-02 19:13:51 at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:35)
2024-11-02 19:13:51 at io.quarkus.arc.impl.ClientProxies.getApplicationScopedDelegate(ClientProxies.java:21)
2024-11-02 19:13:51 at dev.streamx.pulsar.init.PulsarInitializer_ClientProxy.arc$delegate(Unknown Source)
2024-11-02 19:13:51 at dev.streamx.pulsar.init.PulsarInitializer_ClientProxy.arc_contextualInstance(Unknown Source)
2024-11-02 19:13:51 at dev.streamx.pulsar.init.PulsarInitializer_Observer_Synthetic_dU_lJeM9CzqEdv-Hh8KHZ1SYvpE.notify(Unknown Source)
2024-11-02 19:13:51 at io.quarkus.arc.impl.EventImpl$Notifier.notifyObservers(EventImpl.java:351)
2024-11-02 19:13:51 at io.quarkus.arc.impl.EventImpl$Notifier.notify(EventImpl.java:333)
2024-11-02 19:13:51 at io.quarkus.arc.impl.EventImpl.fire(EventImpl.java:80)
2024-11-02 19:13:51 at io.quarkus.arc.runtime.ArcRecorder.fireLifecycleEvent(ArcRecorder.java:156)
2024-11-02 19:13:51 at io.quarkus.arc.runtime.ArcRecorder.handleLifecycleEvents(ArcRecorder.java:107)
2024-11-02 19:13:51 at io.quarkus.deployment.steps.LifecycleEventsBuildStep$startupEvent1144526294.deploy_0(Unknown Source)
2024-11-02 19:13:51 at io.quarkus.deployment.steps.LifecycleEventsBuildStep$startupEvent1144526294.deploy(Unknown Source)
2024-11-02 19:13:51 ... 13 more
2024-11-02 19:13:51 Caused by: java.lang.ClassNotFoundException: javax.annotation.Priority
2024-11-02 19:13:51 at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
2024-11-02 19:13:51 at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
2024-11-02 19:13:51 at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
2024-11-02 19:13:51 at io.quarkus.bootstrap.runner.RunnerClassLoader.loadClass(RunnerClassLoader.java:114)
2024-11-02 19:13:51 at io.quarkus.bootstrap.runner.RunnerClassLoader.loadClass(RunnerClassLoader.java:72)
2024-11-02 19:13:51 ... 44 more
2024-11-02 19:13:51
2024-11-02 19:13:51 Exception in thread "Shutdown thread" java.lang.NullPointerException: Cannot invoke "io.quarkus.runtime.Application.isStarted()" because "app" is null
2024-11-02 19:13:51 at io.quarkus.runtime.ApplicationLifecycleManager$ShutdownHookThread.run(ApplicationLifecycleManager.java:455)
This is happening, because annotation-api
is banned. The mechanism is explained here:
https://quarkus.io/guides/class-loading-reference#banned-dependencies
I don't argue with the reasoning.
Without tomcat annotations-api, the exception is thrown at runtime:
@michalcukierman Thanks. It looks like it's jersey-client 2.42 which pulls in the annotation-api dependency:
[INFO] | +- org.glassfish.jersey.core:jersey-client:jar:2.42:compile
[INFO] | | +- jakarta.ws.rs:jakarta.ws.rs-api:jar:2.1.6:compile
[INFO] | | +- org.glassfish.jersey.core:jersey-common:jar:2.42:compile
[INFO] | | | +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
[INFO] | | | \- org.glassfish.hk2:osgi-resource-locator:jar:1.0.3:compile
[INFO] | | \- org.glassfish.hk2.external:jakarta.inject:jar:2.6.1:compile
We'd have to migrate to jersey-client 3.0.x or higher to get rid of the dependency.
Without tomcat annotations-api, the exception is thrown at runtime:
@michalcukierman Thanks. It looks like it's jersey-client 2.42 which pulls in the annotation-api dependency:
[INFO] | +- org.glassfish.jersey.core:jersey-client:jar:2.42:compile [INFO] | | +- jakarta.ws.rs:jakarta.ws.rs-api:jar:2.1.6:compile [INFO] | | +- org.glassfish.jersey.core:jersey-common:jar:2.42:compile [INFO] | | | +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile [INFO] | | | \- org.glassfish.hk2:osgi-resource-locator:jar:1.0.3:compile [INFO] | | \- org.glassfish.hk2.external:jakarta.inject:jar:2.6.1:compile
We'd have to migrate to jersey-client 3.0.x or higher to get rid of the dependency.
Actually that's already using jakarta.annotation-api.
It looks like there are problems with the shading configuration of pulsar-client-all and pulsar-client-admin-shaded. There are transitive dependencies which should be shaded. This could be seen in the published pom.xml files (https://repo1.maven.org/maven2/org/apache/pulsar/pulsar-client-all/4.0.0/pulsar-client-all-4.0.0.pom and https://repo1.maven.org/maven2/org/apache/pulsar/pulsar-client-admin/4.0.0/pulsar-client-admin-4.0.0.pom).
Actually that's already using jakarta.annotation-api.
Yes, but in version 1.x the jakarta annotation api is still using the javax package :).
Regarding the shading configuration: I've taken a look at the pulsar-client-shaded
pom, but it is unclear to me what exactly should be shaded and what should not. I see that there is an exclude for jackson-annotations
and bouncycastle
, from what I can tell it attempts to shade the rest? Would the solution to this problem be to complete this list with the missing javax libraries?
@lhotari I would happily contribute a PR for this, but right now I'm still not sure what the desired outcome of the shading configuration is exactly.
Also, can you maybe remove the Stale
label from this Issue, I don't think it applies anymore and it might make it harder to find it in searches.
I have recently worked on moving Starlight for JMS to the Jakarta packages and I had many problems due to this issue (and the users have to import the old package anyway) We should move to Jakarta
Search before asking
Motivation
It seems like Pulsar, (especially Pulsar Admin Client) still depends on javax.annotation-api 1.3.2, which has been archived, deprecated and replaced by jakarta-annotation-api. This can block the future libraries upgrade and make it complicated to integrate with new framworks/libraries, due to classloading issues.
Observed on using Pulsar Admin Client with Quarkus.
Solution
Upgrade to jakarta-annotation-api, which is also used by transitive dependencies. The source code can be found here: https://github.com/eclipse-ee4j/common-annotations-api
Alternatives
Not a long-term solution, but we could stick with javax.annotation-api for a while. Sooner or later we need to upgrade.
Anything else?
No response
Are you willing to submit a PR?