Marian Macik created CXF-7925:
---------------------------------
Summary: Dynamic WSDL Client creation fails on JDK 11 because it
cannot compile generated classes
Key: CXF-7925
URL: https://issues.apache.org/jira/browse/CXF-7925
Project: CXF
Issue Type: Bug
Components: Core, JAX-WS Runtime
Affects Versions: 3.2.7, 3.1.16
Environment: JDK 11
Wildfly 14/EAP 7.2.0
Apache CXF 3.1.16/3.2.7
Reporter: Marian Macik
Hi guys,
sorry for a longer description, but I wrote here everything I know.
I am working on kiegroup projects (drools,jbpm,optaplanner) and we are now
upgrading to JDK 11. I am having the following issue (it works on JDK 8):
Enivornment is JDK 11, Wildfly 14/EAP 7.2.0 and I am running there our tests.
The test runs inside EAP and calls a
[WebService|https://github.com/kiegroup/jbpm/blob/ccddd0812225ec7666111700e4138d3a32a28b66/jbpm-container-test/jbpm-remote-ejb-test/jbpm-remote-ejb-test-suite/src/main/java/org/jbpm/remote/ejb/test/mock/WebService.java#L32-L37]
which is published from client side (outside container)
[here|https://github.com/kiegroup/jbpm/blob/ccddd0812225ec7666111700e4138d3a32a28b66/jbpm-container-test/jbpm-remote-ejb-test/jbpm-remote-ejb-test-suite/src/main/java/org/jbpm/remote/ejb/test/mock/WebService.java#L47].
So basically a code in the container is trying to connect to a WebService not
deployed on that container.
At first, the test creates a dynamic client
[here|https://github.com/kiegroup/jbpm/blob/master/jbpm-workitems/jbpm-workitems-webservice/src/main/java/org/jbpm/process/workitem/webservice/WebServiceWorkItemHandler.java#L410]
(classloader used is *Thread.currentThread().getContextClassLoader()*, its
toString method says "ModuleClassLoader for Module
"deployment.ejb-services-app.war" from Service Module Loader" - so it is
basically a classloader for the deployed application), but it fails to do that
with an exception:
*Unable to create JAXBContext for generated packages: "org.jboss.sepro" doesnt
contain ObjectFactory.class or jaxb.index*
However, this is not the root cause. I debugged it and the root cause is
following. When the client is being created, it downloads WSDL and then creates
a classes for marshalling/unmarshalling using XJC. Classes are generated, I can
find them in /tmp folder which is created by the code in
[DynamicClientFactory.java|https://github.com/apache/cxf/blob/4f9923c32688c57e31f933c69d9c2a667f20d63d/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java#L366].
After that, it's time for compilation which unfortunately fails in
[DynamicClientFactory#compileJavaSrc|https://github.com/apache/cxf/blob/4f9923c32688c57e31f933c69d9c2a667f20d63d/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java#L389].
When I dug deeper, I found that the classpath for compilation is set to "" (or
rather not set) in
[DynamicClientFactory#setupClasspath|https://github.com/apache/cxf/blob/4f9923c32688c57e31f933c69d9c2a667f20d63d/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java#L674]
method. I guess this is fine, since it is only filled in case a URLClassLoader
is used or in case we are in WebLogic, so there is a weblogic classloader. But
since we are using just Thread.currentThread().getContextClassLoader(), which
is not of type URLClassLoader, it does nothing. Then, before the compilation
itself, CXF sets arguments for a compiler in
[Compiler#addArgs|https://github.com/apache/cxf/blob/4f9923c32688c57e31f933c69d9c2a667f20d63d/core/src/main/java/org/apache/cxf/common/util/Compiler.java#L104]
method. Here you can see it uses
[java.class.path|https://github.com/apache/cxf/blob/4f9923c32688c57e31f933c69d9c2a667f20d63d/core/src/main/java/org/apache/cxf/common/util/Compiler.java#L105]
system property to set the classpath. However, since we are on EAP, the
java.class.path is set to:
*/home/mmacik/Workspace/jbpm/jbpm-container-test/jbpm-remote-ejb-test/jbpm-remote-ejb-test-suite/target/cargo/installs/jboss-eap-7.2.0.GA.CR2/jboss-eap-7.2/jboss-modules.jar*
and that's it. The code doesn't pass there anything else, just this one JAR
file.
And now why it fails. I copied the classes generated by XJC and tried to
compile them by myself (since programmatic way returns only true/false) using
javac and they doesn't compile since JAXB annotations (JAXP-API classes in
general) are not on the classpath. The reason is that in Java 11 these classes
were removed as part of [JEP-320|https://openjdk.java.net/jeps/320] document.
So on Java 8 it works, although the classpath is set to only jboss-modules.jar
as well, because Java 8 contains required annotations/classes from JAXB-API in
itself. When I tried to compile these generated classes manually using JDK 11
and I included jaxb-api artifact on classpath using -classpath option, they
compiled.
So ultimately the test fails on JAXBContext creation because it cannot find
ObjectFactory.class or jaxb.index file, which is completely fine since it
didn't compile.
So I think that now it is not possible to use Dynamic Client with WSDL in
Wildfly/EAP since generated classes won't compile. And it doesn't matter which
classloader we use since the classpath is obtained from java.class.path system
property, unless we use URLClassLoader or we are in Weblogic so we can use a
WebLogic classloader.
We have also a vice-versa test, meaning the test calls a WebService, which is
deployed in EAP, from outside the container. This scenario works with JDK 11 as
well as with JDK 8 because system property java.class.path contains all Maven
dependencies needed to build and run the tests (dynamic client creation now
happens as a part of a jUnit test in a failsafe plugin).
So do you have any ideas/hints/recommendations how to overcome this or is this
going to be fixed in the near future for JDK 11?
Thank you very much.
Marian Macik
Red Hat Business Automation
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)