JAX-WS : IllegalArgumentException lors de la préparation d'un appel.
Bonjour à tous,
Je viens d'être confronté à un problème que j'arrive désormais à contourner mais que je ne m'explique pas.
Et ça ne me satisfait pas.
En voici la description.
J'ai à développer un web service avec jax-ws qui fournit un petit tableau de byte codé en base 64 et, toujours avec jax-ws, un client.
Pour le serveur tout se passa à merveille. SOAPUI me fournit bien la chaine attendu dans la réponse.
Je récupère la wsdl avec ses xsd et jax-ws, sans message choquant, me fournit une librairie censé me permettre de solliciter le serveur.
Mais avant même de lancer l'appel j'ai une erreur.
Voici le code côté serveur :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.bind.annotation.XmlElement;
@WebService(name="ObtenirIdSync" , targetNamespace ="http://service.mastest/cobaltmastest/contratcob/ObtenirId")
@SOAPBinding(
style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
public interface ObtenirId
{
@WebMethod
public @WebResult(name="result") byte[] obtenirId();
} |
Le résultat dans la xsd définissant les types :
Code:
1 2 3 4 5 6
|
<xs:complexType name="obtenirIdResponse">
<xs:sequence>
<xs:element name="result" type="xs:base64Binary" nillable="true" minOccurs="0"/>
</xs:sequence>
</xs:complexType> |
Le code client :
Code:
1 2 3 4 5 6
|
QName qname = new QName(targetNameSpace, serviceName);
ObtenirIdSync client = new ObtenirIdImpl(null,qname).getObtenirIdImplPort();
((BindingProvider)client).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, accesp.toString());
return client.obtenirId(); |
Et dès la deuxième ligne j'ai droit à :
Code:
1 2 3 4 5 6
|
Exception in thread "main" com.sun.xml.ws.spi.db.DatabindingException: java.lang.IllegalArgumentException: can't parse argument number ''{0}''
at com.sun.xml.ws.db.glassfish.JAXBRIContextFactory.newContext(JAXBRIContextFactory.java:104)
at com.sun.xml.ws.spi.db.BindingContextFactory.create(BindingContextFactory.java:182)
at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:218)
... |
Si je remplace*:
<xs:element name="result" type="xs:base64Binary" nillable="true" minOccurs="0"/>
par
<xs:element name="result" type="xs:base64Binary" nillable="true"/>
Et que je relance jax-ws, plus de problème.
Du coup, j'ai remplacer dans mon serveur*:
public @WebResult(name="result") byte[] obtenirId();
par
public @WebResult(name="result") @XmlElement(nillable=false, required=true) byte[] obtenirId();
Et le xsd est directement utilisable. Qui plus est, ça correspond mieux à la réalité.
Mais je ne m'explique toujours pas le premier problème. Si je devais le résumer je dirais que jax-ws n'arrive pas à gérer côté client une wsdl qu'il a lui même généré côté serveur.
Je n'y crois pas moi-même et me dis que quelque chose doit m'échapper.
Une idée ?
Quelques versions :
on est en jdk 6 (et oui je travail dans une grand maison très conservatrice...) patché pour jaxws et jaxb (version 2.2.3 en lieu et place de la 2.1)
Et dans mes pom*:
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.2.8</version>
(du coup mon jaxb est en 2.2.7)
</dependency>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.3</version>