users@glassfish.java.net

Re: Problem using CXF on Glassfish 3.1.1: keep getting the Metro implementation

From: Andreas Loew <Andreas.Loew_at_oracle.com>
Date: Mon, 09 Jan 2012 23:59:03 +0100

Hi sonicfab,

Am 09.01.2012 21:50, schrieb forums_at_java.net:
> We want to run a JAX-WS web service client based on CXF, inside
> Glassfish 3.1.1. The application is packaged in an EAR.
>
> The CXF libraries are packaged in the lib directory at the root of the
> EAR (standard Java EE 5/6 lib packaging). When we call the WS client,
> the JAX-WS implementation that is systematically picked up is Metro,
> whereas we want to use the CXF implementation.
>
> It would seem that the ContextClassloader is picking up the Metro
> libraries from the server instead of the CXF libs in the EAR. We have
> tried to include a javax.xml.ws.spi.Provider file under
> META-INF/services in the EAR, but that didn’t solve the problem.

I fear that what you are trying to do is not covered by the Java EE 6
specification:

The standard only describes that you need to be able a container's web
application classloader by a non-delegating classloader, but does not
require the same for the EJB container.

See

http://cxf.apache.org/docs/application-server-specific-configuration-guide.html#ApplicationServerSpecificConfigurationGuide-Glassfish

which only has a solution for the web container, namely to set

<class-loader delegate="false"/>

in the glassfish-web.xml deployment descriptor, but again: This will
only work for the web container.

So the most simple solution is to run your CXF client from the Glassfish
web container...


If you still think you indeed need to run your CXF client from the GF
EJB container, this is a quite advanced programming task which involves
fiddling with classloaders:

You will need to establish a custom non-delegating classloader in the
EJB container. You can try do so by leveraging something like One-JAR:

http://one-jar.sourceforge.net/

to package all your code that needs a custom non-delegating classloader
into the One-JAR, put the One-JAR into your application EAR as a library
JAR, and initialize the One-JAR manually to utilize your custom
classloader which extends com.simontuffs.onejar.JarClassLoader, but
implements a non-delegating classloading strategy for all classes within
this exact same One-JAR, and only delegates to the parent Glassfish EAR
classloader when a class is not found locally in one of the JARs
contained within the One-JAR...

I hope you got the idea... ;-)

I did something very similar some time ago to introduce Metro 1.0 into
the EJB container of former Sun App Server 8.1 (which did only support
JAX-RPC at that time), and it worked out fine, but I have warned you -
it is definitely not easy to get everything right...

Hope this helps & best regards,

Andreas

-- 
Andreas Loew | Senior Java Architect
Oracle Advanced Customer Services
ORACLE Germany