Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-7925

Dynamic WSDL Client creation fails on JDK 11 because it cannot compile generated classes

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Reopened
    • Major
    • Resolution: Unresolved
    • 3.1.16, 3.2.7
    • None
    • Core, JAX-WS Runtime
    • JDK 11
      Wildfly 14/EAP 7.2.0
      Apache CXF 3.1.16/3.2.7

    • Unknown

    Description

      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 which is published from client side (outside container) here.

      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 (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. After that, it's time for compilation which unfortunately fails in DynamicClientFactory#compileJavaSrc. When I dug deeper, I found that the classpath for compilation is set to "" (or rather not set) in DynamicClientFactory#setupClasspath 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 method. Here you can see it uses java.class.path 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 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

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              mmacik Marian Macik
              Votes:
              1 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

                Created:
                Updated: