camel-k icon indicating copy to clipboard operation
camel-k copied to clipboard

Error occurred when deploying Route file containing Camel Soap using Camel

Open halouprogramer opened this issue 2 years ago • 10 comments

What happened?

Hello Everyone Locally, the Quarkus application does not report an error, but when deploying the Route file using Camel I guess it has something to do with QuarkusClassLoader, but I don't know how to modify it.

JDK VERSION: 11 camel-k version: 1.10.1 camel version: 3.18

Steps to reproduce

  1. Use cxf-codegen-plugin 3.6.2 create Java Soap Entity
  2. Route File
// camel-k: language=java
// camel-k: env=TZ=Asia/Shanghai
// camel-k: dependency=mvn:com.sun.xml.ws:jaxws-rt:2.3.3
// camel-k: dependency=mvn:com.sun.xml.ws:rt:2.3.3
// camel-k: dependency=camel-soap
// camel-k: trait=container.name=demo
// camel-k: resource=file:../../../target/demo.jar
// camel-k: trait=jvm.classpath=/etc/camel/resources/demo.jar

import org.apache.camel.dataformat.soap.SoapDataFormat;
import org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy;
import org.apache.camel.quarkus.core.CamelQuarkusClassResolver;

public class DemoRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {  
        // Soap Convert
        SoapDataFormat soapDataFormat = new SoapDataFormat();
        soapDataFormat.setContextPath("wsdl");


        soapDataFormat.setElementNameStrategy(new ServiceInterfaceStrategy(
                getContext().getApplicationContextClassLoader().loadClass(DemoPortType.class.getName()) , true));

        // Source: Knative Event
        from("knative:event/demo")
       		// ...
        .marshal(soapDataFormat)
        .to("direct:outbound_http");
    }
}
  1. Deploy kamel run --name demo --profile Knative --property file:../../../biz.properties DemoRoute.java

Relevant log output

Failed to start application: java.lang.IllegalArgumentException: The number of @WebParam annotations for Method syncUBREXCHANGE does not match the number of parameters. This is not supported.
	at org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy.getInInfo(ServiceInterfaceStrategy.java:122)
	at org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy.analyzeMethod(ServiceInterfaceStrategy.java:145)
	at org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy.analyzeServiceInterface(ServiceInterfaceStrategy.java:157)
	at org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy.<init>(ServiceInterfaceStrategy.java:58)
	at DemoRoute.configure(DemoRoute.java:133)
	at org.apache.camel.builder.RouteBuilder.checkInitialized(RouteBuilder.java:672)
	at org.apache.camel.builder.RouteBuilder.configureRoutes(RouteBuilder.java:618)
	at org.apache.camel.builder.RouteBuilder.addRoutesToCamelContext(RouteBuilder.java:554)
	at org.apache.camel.impl.engine.AbstractCamelContext.addRoutes(AbstractCamelContext.java:1178)
	at org.apache.camel.main.RoutesConfigurer.addDiscoveredRoutes(RoutesConfigurer.java:237)
	at org.apache.camel.main.RoutesConfigurer.configureRoutes(RoutesConfigurer.java:212)
	at org.apache.camel.quarkus.main.CamelMain.configureRoutes(CamelMain.java:70)
	at org.apache.camel.main.BaseMainSupport.postProcessCamelContext(BaseMainSupport.java:637)
	at org.apache.camel.quarkus.main.CamelMain.initCamelContext(CamelMain.java:116)
	at org.apache.camel.quarkus.main.CamelMain.doInit(CamelMain.java:86)
	at org.apache.camel.support.service.BaseService.init(BaseService.java:83)
	at org.apache.camel.quarkus.main.CamelMain.startEngine(CamelMain.java:137)
	at org.apache.camel.quarkus.main.CamelMainRuntime.start(CamelMainRuntime.java:49)
	at org.apache.camel.quarkus.core.CamelBootstrapRecorder.start(CamelBootstrapRecorder.java:45)
	at io.quarkus.deployment.steps.CamelBootstrapProcessor$boot173480958.deploy_0(Unknown Source)
	at io.quarkus.deployment.steps.CamelBootstrapProcessor$boot173480958.deploy(Unknown Source)
	at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:110)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:70)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:43)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:123)
	at io.quarkus.runner.GeneratedMain.main(Unknown Source)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:61)
	at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:32)

Camel K version

Camel K Client Red Hat 1.10.1 Camel K Operator 1.10.1

halouprogramer avatar Oct 24 '23 08:10 halouprogramer

It seems a runtime error caused by camel-soap component [1]. You mention, this is not happening when running with Camel Quarkus. Can you please verify what version of Camel Quarkus are you using? Can you also repeat the test with Camel Quarkus 2.13.3 which is the one used in 1.10.1 runtime?

[1] https://github.com/apache/camel/blob/e2ea12fdd29d8d446ec7b3fdf7c6db2147e196b4/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/ServiceInterfaceStrategy.java#L123

squakez avatar Oct 24 '23 15:10 squakez

I built a similar application using Camel Quarkus 2.3.0, and it still doesn't report any errors when starting locally. However, when deploying the application to OpenShift using Kamel, it reports an error during the startup phase. Here is the example: https://github.com/halouprogramer/camel-soap-demo

The deployment process is as follows:

mvn clean compiler:compile jar:jar kamel run --name camel-soap-demo DemoRoute.java

Could it be a problem with the ClassLoader? The loader used by the local Quarkus is QuarkusClassLoader:Quarkus Base Runtime ClassLoader: DEV@55fe41ea. The loader printed after deployment to OpenShift is io.quarkus.bootstrap.runner.RunnerClassLoader@7fbe847c.

halouprogramer avatar Oct 25 '23 06:10 halouprogramer

The problem lies in this line. https://github.com/apache/camel/blob/e2ea12fdd29d8d446ec7b3fdf7c6db2147e196b4/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/ServiceInterfaceStrategy.java#L115C21-L115C31 annotation instanceof WebParam The local Quarkus startup result is true, but it is false when deployed to OpenShift by Kamel.

halouprogramer avatar Oct 25 '23 07:10 halouprogramer

Yeah, likely this is because in Camel K Runtime, the routes are loaded dynamically, hence they have a different classloader. I am not sure there is an easy way to solve this with the actual model. @lburgazzoli wdyt?

squakez avatar Oct 25 '23 11:10 squakez

I don't think the classloader should make a difference in this case, I would first check if the version of camel-k supports the jakarta namespace or not.

lburgazzoli avatar Oct 25 '23 11:10 lburgazzoli

I will try replacing it with jakarta.

But I would like to add one thing.

Method 1: When I use the following method, the Route can start normally. 1.Upload the camel-soap-demo.jar package to Nexus. 2.Import the dependency using the dependency method, // camel-k: dependency=mvn:com.demo:camel-soap-demo:1.0.0

Method 2: Using the following method will result in the aforementioned exception, and the application fails to start. // camel-k: resource=file:../../../target/camel-soap-demo.jar // camel-k: trait=jvm.classpath=/etc/camel/resources/camel-soap-demo.jar

I don't know the difference between these two methods. I hope to receive further advice.

halouprogramer avatar Oct 25 '23 12:10 halouprogramer

I think the difference is that with an explicit dependency, any additional transitive dependency is also added to the classpath, whereas the second method, won't probably do so and the dependency is only added at runtime.

you can compare the integration kit generated by the two options and see if there is any difference.

lburgazzoli avatar Oct 25 '23 12:10 lburgazzoli

I think the difference is that with an explicit dependency, any additional transitive dependency is also added to the classpath, whereas the second method, won't probably do so and the dependency is only added at runtime.

you can compare the integration kit generated by the two options and see if there is any difference.

The second method indeed cannot search for any information related to camel-soap-demo.jar in the integration kit. However, I still don't understand the exact reason for the above exception.

halouprogramer avatar Oct 26 '23 06:10 halouprogramer

I don't think the classloader should make a difference in this case, I would first check if the version of camel-k supports the jakarta namespace or not.

The version of kamel-k I am using does not support jakarta namespace. The jakarta namespace can only be used in camel-soap version 4.0.0 and above, which means the JDK version may also need to be upgraded to JDK17. At the same time, I am also worried that the same situation will occur after the upgrade.

https://github.com/apache/camel/blob/camel-4.0.x/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/name/ServiceInterfaceStrategy.java#L28

I don't know if there are any other solutions under the current version environment.

halouprogramer avatar Oct 26 '23 07:10 halouprogramer

I have the feeling this one depends on #4639 It looks like the resources are used correctly when the dependency is provided at build time (via -d option) but not when it happens at runtime (via -t jvm option).

squakez avatar Dec 05 '23 16:12 squakez