quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.56k stars 2.62k forks source link

quarkus-spring-web breaks startup of camel-quarkus-activemq in kubernetes environment #11996

Closed alrawas closed 15 hours ago

alrawas commented 4 years ago

Describe the bug Before writing any classes. starting with quarkus-container-image-jib, quarkus-kubernetes, camel-quarkus-activemq builds successfully and starts up successfully.

However when adding this extension to the pom quarkus-spring-web my quarkus app still builds successfully and pushes to my local kubernetes registry but it fails to start up and I get ClassNotFoundException: java.lang.ClassNotFoundException: org.springframework.beans.factory.InitializingBean

Expected behavior Startup to be successful in kubernetes environment

Actual behavior Startup fails and I get the following exception after adding quarkus-spring-web

C:\Users\Front2\camel-amq-kub>kubectl logs deployments/camel-amq-kub

Exception in thread "main" java.lang.ExceptionInInitializerError
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.lang.Class.newInstance(Class.java:584)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:60)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
        at com.alrawas.Main.main(Main.java:18)
Caused by: java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:436)
        ... 8 more
Caused by: java.lang.NoClassDefFoundError: org/springframework/beans/factory/InitializingBean
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at org.apache.camel.component.jms.JmsComponent.createConfiguration(JmsComponent.java:1213)
        at org.apache.camel.component.jms.JmsComponent.<init>(JmsComponent.java:72)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.lang.Class.newInstance(Class.java:584)
        at org.apache.camel.quarkus.core.CamelRecorder.bind(CamelRecorder.java:83)
        at io.quarkus.deployment.steps.CamelRegistryProcessor$bindBeansToRegistry1314779611.deploy_0(CamelRegistryProcessor$bindBeansToRegistry1314779611.zig:113)
        at io.quarkus.deployment.steps.CamelRegistryProcessor$bindBeansToRegistry1314779611.deploy(CamelRegistryProcessor$bindBeansToRegistry1314779611.zig:40)
        at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:416)
        ... 8 more
Caused by: java.lang.ClassNotFoundException: org.springframework.beans.factory.InitializingBean
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 46 more

To Reproduce Steps to reproduce the behavior:

  1. execute this command to create a new project mvn io.quarkus:quarkus-maven-plugin:1.7.2.Final:create -DprojectGroupId=org.acme -DprojectArtifactId=camel-amq-kub

  2. add the first 3 non problematic extensions mvn quarkus:add-extension -Dextensions="camel-quarkus-activemq, quarkus-kubernetes, quarkus-container-image-jib"

  3. add your kubernetes registry properties in application.properties

  4. run mvn clean package -Dquarkus.kubernetes.deploy -Dquarkus.profile=kub -DskipTests and check logs using kubectl logs deployments/camel-amq-kub. Up to this point you should see no exceptions.

  5. add the following extension to the pom

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-spring-web</artifactId>
    </dependency> 
  6. do step 4 again. you should see the exception now.

Configuration


quarkus.container-image.group=alrawasabed
quarkus.container-image.registry=localhost:5000
quarkus.container-image.insecure=true
quarkus.kubernetes.service-type=node-port

%kub.brokerURL=tcp://host.docker.internal:61616

Environment (please complete the following information):

quarkusbot commented 4 years ago

/cc @geoand

geoand commented 4 years ago

@lburgazzoli looking at the stacktrace, it looks like Camel is trying to load some Spring classes for some reason.

lburgazzoli commented 4 years ago

it is the first time I see this but yes camel-jms and camel-activemq which is based on it have a dependency on spring as they use spring-jms.

We need to investigate what triggers this issue.

In the meantime, a workaround could be to use camel-sjms or camel-sjms2 as they are based on the jms specs without dependency on spring. An example can be found here https://github.com/apache/camel-quarkus/tree/master/integration-tests/messaging

jamesnetherton commented 3 years ago

I've been looking into this. The problem stems from this quarkus-spring-di plugin configuration:

<plugin>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-bootstrap-maven-plugin</artifactId>
    <configuration>
        <excludedArtifacts>
            <excludedArtifact>org.springframework:spring-core</excludedArtifact>
            <excludedArtifact>org.springframework:spring-beans</excludedArtifact>
            <excludedArtifact>org.springframework:spring-context</excludedArtifact>
        </excludedArtifacts>
    </configuration>
</plugin>

Which effectively bans dependencies that some of the camel-quarkus extensions depend on.

I can work around this in camel-quarkus, but was wondering if it could make sense to have a BuildItem, or some other way for extensions to unexclude these artifacts if they really need them. WDYT @geoand?

geoand commented 3 years ago

Unfortunately a BuildItem is executed way too late for that to be possible.

geoand commented 15 hours ago

Is this still an issue?

jamesnetherton commented 15 hours ago

Pretty sure this was fixed long ago. CQ now shades the required bits from spring-core, spring-beans & spring-context into a dedicated 'spring support' extension. So the problem I mentioned above is not present anymore.

geoand commented 15 hours ago

Gotcha, thanks a lot!