[ 
https://issues.apache.org/jira/browse/CXF-8100?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16962849#comment-16962849
 ] 

Christof R commented on CXF-8100:
---------------------------------

For the reference, here is the entire service implementation. Let me know if 
you need the entire code base.
{code:java}
package webapp;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.ext.logging.LoggingInInterceptor;
import org.apache.cxf.ext.logging.LoggingOutInterceptor;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.jaxws.JaxWsClientFactoryBean;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.message.Message;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reference.namespace.servicea.RequestType;
import reference.namespace.servicea.ResponseType;
import reference.namespace.servicea_wsdl.ServiceAPortType;
import reference.namespace.serviceb.GetVersionResponse;
import reference.namespace.serviceb.SimpleRequestType;
import reference.namespace.serviceb_wsdl.ServiceBPort;

import javax.jws.WebParam;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@Service
public class ServiceA implements ServiceAPortType {

    private static final Interceptor<Message> LOGGING_IN_INTERCEPTOR = new 
LoggingInInterceptor();
    private static final Interceptor<Message> LOGGING_OUT_INTERCEPTOR = new 
LoggingOutInterceptor();

    @Autowired
    private String clientUrl;

    @Autowired
    public ServiceA() {
    }

    public ResponseType request(
        @WebParam(partName = "Request", name = "Request") RequestType request) {

        try {
            return CompletableFuture.supplyAsync(() -> 
runClientRequest()).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return ResponseType.responseTypeBuilder()
                .withReturn("error!")
                .build();

    }

    private ResponseType runClientRequest() {

        ServiceBPort serviceb = create(ServiceBPort.class);
        GetVersionResponse version = 
serviceb.getVersion(SimpleRequestType.simpleRequestTypeBuilder().build());

        return ResponseType.responseTypeBuilder()
                .withReturn("Got Version: " + version.getVersion())
                .build();

    }


    private <T> T create(Class<T> clazz) {

        var factory = new JaxWsClientFactoryBean();
        factory.setServiceClass(clazz);
        factory.setAddress(clientUrl);
        factory.getInInterceptors().add(LOGGING_IN_INTERCEPTOR);
        factory.getInFaultInterceptors().add(LOGGING_IN_INTERCEPTOR);
        factory.getOutInterceptors().add(LOGGING_OUT_INTERCEPTOR);
        factory.getOutFaultInterceptors().add(LOGGING_OUT_INTERCEPTOR);

        var proxy = new JaxWsProxyFactoryBean(factory).create();
        Client client = ClientProxy.getClient(proxy);

        var httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setConnectionTimeout(30000);
        httpClientPolicy.setReceiveTimeout(30000);

        HTTPConduit http = (HTTPConduit) client.getConduit();
        http.setClient(httpClientPolicy);

        return ((T) proxy);
    }

}
{code}

> JAXB Class Not Found Exception on Java >=9 and Tomcat
> -----------------------------------------------------
>
>                 Key: CXF-8100
>                 URL: https://issues.apache.org/jira/browse/CXF-8100
>             Project: CXF
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 3.3.3
>         Environment: Ubuntu 18.10
> OpenJDK Runtime Environment (build 12.0.1+12)
> Tomcat 9.0.14
>            Reporter: Christof R
>            Priority: Major
>              Labels: bug
>         Attachments: webapp.war
>
>
> When creating a SOAP Client with JaxWsProxyFactoryBean.create(), JAXB's class 
> loader does not find the context factory (see stack trace at the bottom) and 
> throws a ClassNotFound Exception. This does *not* happen when I run test with 
> Junit, but it happens when I deploy my Apache CXF Application to Tomcat. All 
> the JAXB artifacts (cxf-rt-databinding-jaxb-3.3.0.jar, jaxb-api-2.3.1.jar, 
> jaxb-core-2.3.0.1.jar, jaxb-impl-2.3.2.jar, jaxb-runtime-2.3.1.jar and 
> jaxb-xjc-2.3.2.jar) are in WEB-INF/lib and are therefore available to the web 
> apps class loader.
> The reason why JAXB does not find the class is, according to the stack 
> overflow post [JAXB not available on Tomcat 9 and Java 
> 9/10|https://stackoverflow.com/questions/51518781/jaxb-not-available-on-tomcat-9-and-java-9-10],
>  that JAXB uses the "thread's context class loader". In Tomcat, this class 
> loader is the system class loader, and because Tomcat [builds a class loader 
> hierarchy|https://tomcat.apache.org/tomcat-9.0-doc/class-loader-howto.html], 
> the system class loader does not know about a web app's dependencies. JAXB 
> Implementations were removed from the JRE in Java 9 and now the system class 
> loader does not find them.
> According to the mentioned post, this problem could be solved by refactoring 
> org.apache.cxf.common.jaxb.JAXBContextCache and switching invocations from
>   
> {code:java}
> newInstance( Class<?>[] classesToBeBound, Map<String,?> properties )
> {code}
> to
> {code:java}
> newInstance( String contextPath, ClassLoader classLoader, Map<String,?>  
> properties)
> {code}
> , where JAXBContextCache could pass down the correct classLoader.  Another 
> probably "hacky" solution is to wrap all interactions with JAXB in a proper 
> thread (as described in this post: [JAXB Hell on JDK 
> 9|https://sjhannah.com/blog/2018/11/21/jaxb-hell-on-jdk-9/]). 
> Stack trace: 
> {code:java}
> Caused by: org.apache.cxf.service.factory.ServiceConstructionException: null
>       at 
> org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:355)
>       at 
> org.apache.cxf.service.factory.AbstractServiceFactoryBean.initializeDataBindings(AbstractServiceFactoryBean.java:86)
>       at 
> org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:470)
>       at 
> org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:693)
>       at 
> org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:530)
>       at 
> org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:263)
>       at 
> org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:199)
>       at 
> org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:103)
>       at 
> org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:91)
>       at 
> org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:159)
>       at 
> org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:142)
>   ...
> Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not 
> been found on module path or classpath.
>       at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:232)
>       at javax.xml.bind.ContextFinder.find(ContextFinder.java:375)
>       at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
>       at 
> org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:346)
>       at 
> org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:344)
>       at 
> java.base/java.security.AccessController.doPrivileged(AccessController.java:551)
>       at 
> org.apache.cxf.common.jaxb.JAXBContextCache.createContext(JAXBContextCache.java:344)
>       at 
> org.apache.cxf.common.jaxb.JAXBContextCache.getCachedContextAndSchemas(JAXBContextCache.java:246)
>       at 
> org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:498)
>       at 
> org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:353)
>       ... 23 common frames omitted
>   Caused by: java.lang.ClassNotFoundException: 
> com.sun.xml.internal.bind.v2.ContextFactory
>       at 
> java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
>       at 
> java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
>       at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
>       at 
> javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:92)
>       at 
> javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:125)
>       at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:230)
> {code}
>  
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to