How to pick CXF over Metro on Glassfish
Asked Answered
B

4

10

I'm having the following problem (reported there by someone else) when running my enterprise application under Glassfish. Under Jetty it works fine.

javax/xml/ws/spi/Provider mentions creating a META-INF/services/javax.xml.ws.spi.Provider resource, but this is already supplied with CXF and creating an additional resource file does not solve this problem under Glassfish.

Does anyone know how to ensure that CXF is picked up under GlassFish?
(I'm using a Maven Multi-modules project with CXF dependency 2.2.5)

Thanks!
Tim


EDIT #1

Skipping the problem for now and just working with Metro, but I'd really like to know how to use CXF instead if anyone has any pointers.. If nothing works I might have to switch web application container (or look into Metro to fill my requirements)


EDIT #2

Some of the solutions detail the fix for war's by adding <class-loader delegate="false"/> to the sun-web.xml file. However, this does not work for non-war ee apps.

Brachiopod answered 14/1, 2010 at 12:42 Comment(3)
I'm finding the same issue only with an ejb packed in an ear. I opened a bounty as I'd really like to hear some good answers to this without having to duplicate the question, hence my edits.Bullpen
+1: This is a bad feature of Glassfish that I am currently facing with jsf: Glassfish has built in jsf libraries and these generate conflicts about a code having jsf in it. Really annoying and the solution is worth of the bounty that is open! I absolutely want to know also the solution!Ottar
Also this post is telling how things work only in some Glassfish version and in some not.Ottar
E
6

Add a sun-web.xml and set delegate=false to the class-loader:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE sun-web-app PUBLIC '-//Sun Microsystems, Inc.//DTD 
Application Server 9.0 Servlet 2.5//EN' 
'http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd'> 
<sun-web-app> 
    <class-loader delegate="false"/> 
</sun-web-app> 
Eidolon answered 9/12, 2010 at 15:33 Comment(2)
Adding this file to the war web-inf directory worked for me. Thanks!Bullnecked
Do you know where to put it in springboot app? I tried resources folder but it didn't work.Multilateral
L
1

The Metro (Glassfish's JAX-WS implementation) jars are probably being included with Glassfish, can you exclude them from the classpath? Since you're using maven, you should analyze the glassfish dependencies and using an exclusion for the metro jars.


It seems that you need to have the CXF jars on the applications classpath before the Metro jars. You probably can't modify the system classloader/classpath but you can change the Thread.currentThread().getContextClassLoader() such that it loads CXF first. There also might a classpath settings in Glassfish you can modify

Check out the source for javax.xml.ws.spi.FactoryFinder#find() to see how the provider is actually loaded

Lubra answered 14/1, 2010 at 14:12 Comment(4)
This could very well be the case, but I'm unsure as to how to remedy this.. It's a compiled .war that I'm uploading to GlassFish, so will Maven excludes still have any effect after compilation? (Ie: will these excludes be passed along to the war and used on the server?)Brachiopod
So its picking up the Metro provider when you're application is deployed in to Glassfish, not during development?Lubra
I misunderstood your situation, sorry. I've updated my postingLubra
Hmm, the above linked FactoryFinder is helpfull in understanding the problem, but I'm as of yet unable to solve my problem using any of the described methods.. (.Provider & .properties files & system property)Brachiopod
B
0

The solution I came up with (and am unsatisfied with) is to use JaxWsProxyFactoryBean. There is an example here.

This is the jist of what you have to do:

public static void main(String args[]) throws Exception {

    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();

    // I didn't need these next 2 calls, but I doubt they hurt
    factory.getInInterceptors().add(new LoggingInInterceptor());
    factory.getOutInterceptors().add(new LoggingOutInterceptor());

    factory.setServiceClass(AuthService.class);
    factory.setAddress("http://localhost:7001/authManager/services/cxfAuth");

    // 'AuthService' is whatever your interface type is
    AuthService client = (AuthService) factory.create();

    Employee employee = client.getEmployee("0223938");
    System.out.println("Server said: " + employee.getLastName() + ", " + employee.getFirstName());
    System.exit(0);

}
Bullpen answered 15/8, 2011 at 22:21 Comment(1)
Could you copy over the relevant parts of the solution? External links tend to break over time..Brachiopod
M
0

For SpringBoot application I needed to add following file:

src/main/resources/META-INF/services/javax.xml.ws.spi.Provider

with content:

org.apache.cxf.jaxws.spi.ProviderImpl

Multilateral answered 24/3, 2022 at 13:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.