2011-04-14 37 views
6

Estoy intentando construir un archivo jar de cliente para acceder a un servicio web. Incluyo el jar en un servlet/war que hace que el cliente llame al servicio web. Estoy recibiendo el siguiente error:CXF - ClassCastException (SEIStub/ClientProxy)

INFO: 2011 Apr 14 14:57:32,780 MDT [http-thread-pool-8181(4)] ERROR  my.package.ClientServlet - Caught exception 
java.lang.ClassCastException: com.sun.xml.ws.client.sei.SEIStub cannot be cast to org.apache.cxf.frontend.ClientProxy 
at org.apache.cxf.frontend.ClientProxy.getClient(ClientProxy.java:93) 
at my.package.Client.<init>(Client.java:54) 
at my.package.ClientServlet.testService(TestServlet.java:118) 

me encontré con este post que dice http://yaytay.wordpress.com/2010/03/06/lsned-29-persuading-jdk-6-to-use-cxf-classes-rather-than-its-own-avoiding-seistub/ de solucionar el problema es necesario incluir cxf-rt-frontend-jaxws como una dependencia, lo que hago. Entonces, ese no es el problema/solución en mi caso.

Mi pom frasco cliente tiene estas dependencias:

<properties> 
    <cxf.version>2.3.3</cxf.version> 
</properties> 
<dependencies> 
    <dependency> 
     <groupId>org.apache.cxf</groupId> 
     <artifactId>cxf-rt-frontend-jaxws</artifactId> 
     <version>${cxf.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.cxf</groupId> 
     <artifactId>cxf-rt-ws-security</artifactId> 
     <version>${cxf.version}</version> 
    </dependency> 
</dependencies> 

La guerra servlet contiene lo siguiente en su lib:

asm-3.3.jar 
bcprov-jdk15-1.45.jar 
commons-logging-1.1.1.jar 
cxf-api-2.3.3.jar 
cxf-common-schemas-2.3.3.jar 
cxf-common-utilities-2.3.3.jar 
cxf-rt-bindings-soap-2.3.3.jar 
cxf-rt-bindings-xml-2.3.3.jar 
cxf-rt-core-2.3.3.jar 
cxf-rt-databinding-jaxb-2.3.3.jar 
cxf-rt-frontend-jaxws-2.3.3.jar 
cxf-rt-frontend-simple-2.3.3.jar 
cxf-rt-ws-addr-2.3.3.jar 
cxf-rt-ws-security-2.3.3.jar 
cxf-tools-common-2.3.3.jar 
geronimo-javamail_1.4_spec-1.7.1.jar 
jaxb-impl-2.1.13.jar 
log4j-1.2.14.jar 
neethi-2.0.4.jar 
my-client-cxf-1.0.jar 
serializer-2.7.1.jar 
slf4j-api-1.4.2.jar 
slf4j-log4j12-1.4.2.jar 
stax2-api-3.0.2.jar 
woodstox-core-asl-4.0.8.jar 
wsdl4j-1.6.2.jar 
wss4j-1.5.11.jar 
xalan-2.7.1.jar 
xml-resolver-1.2.jar 
XmlSchema-1.4.7.jar 
xmlsec-1.4.4.jar 

También he leído algunos mensajes que hablan de un archivo javax.xml.ws.spi.Provider, pero no han podido encontrar ninguna referencia que detalle qué debe ser nombrado, contener y colocar.

¿Alguien puede señalarme en la dirección correcta?

Respuesta

7

La solución fue incluir un archivo sun-web.xml (o glassfish-web.xml) en la guerra WEB-INF. Ver How to pick CXF over Metro on Glassfish

EDIT

Contenido de glassfish-web.xml:

<?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'> 

<glassfish-web-app> 
    <!-- Need this to tell Glassfish not to load the JAX-WS RI classes so it will 
     use the CXF ones instead --> 
    <class-loader delegate="false" /> 
</glassfish-web-app> 
+3

Juro por Dios, si esto funciona para mí, tienes alguna recompensa rodar su camino;) – javamonkey79

+0

¿Se puede publicar los archivos XML que trabajaron para usted? ¿O al menos las partes relevantes? – javamonkey79

+0

Agregado a la respuesta, espero que funcione para usted. – sdoca

1

Probé CXF en el pasado y encontré extrañas excepciones como esta. Supongo que ya lo intentó CXF mailing list.

Intentaré ir despacio: empiece con un ejemplo de trabajo de la distribución de CFX y haga un cambio a la vez hasta que llegue al problema.

1

Retire JAX-WS Bibliotecas de BuildPath, por lo que este puede resuelve mi problema es que (ClassCastException) SEIStub a ClientProxy .

2

Si falla todo lo demás, puede usar la reflexión para anular el delegado del servicio.

 QName qName = new QName(wsTargetNamespace, wsName); 
     service = new YourServiceScheduler(loc, qName); 
     Field delegateField = Service.class.getDeclaredField("delegate"); 
     delegateField.setAccessible(true); 
     ServiceDelegate previousDelegate = (ServiceDelegate)delegateField.get(service); 
     if(!previousDelegate.getClass().getName().contains("cxf")) { 
      ServiceDelegate serviceDelegate = ((Provider) Class.forName("org.apache.cxf.jaxws.spi.ProviderImpl").newInstance()) 
       .createServiceDelegate(loc, qName, service.getClass()); 
      log.info("The " + getClass().getSimpleName() + " delegate is changed from " + "[" + previousDelegate + "] to [" + 
       serviceDelegate + 
       "]"); 
      delegateField.set(service, serviceDelegate); 
     } 
     port = service.getYourServiceSoap(); 
+1

(pregunta relevante: http://stackoverflow.com/questions/6364333/jax-ws-when-apache-cxf-is-installed-it-steals-default-jdk-jax-ws-implementat/) – EpicPandaForce

+0

Estoy intentando esto, pero estoy recibiendo: NoSuchField delegado – ronnyfm

+1

¿Estás seguro de que estás usando el 'Service.class' correcto? El nombre completo es 'javax.xml.ws.Service'. Espero que este detalle de implementación no haya cambiado – EpicPandaForce