Ce billet complète la série de billets sur les Services Web. Il s’agit d’une actualisation de la série dans le cadre d’une utilisation avec le serveur d'application WebSphere 8.5.5 et Java 1.7.
Vous pouvez trouver le début de la série à l’url suivante : http://jl2tho.blogspot.fr/2011/11/tutorial-approche-contract-first-avec.html. Elle présente la création d'un service web avec les annotations JAX-WS et JAXB.

La norme JAX-WS a pour objectif d'assurer la portabilité des services web réalisés à travers les différents serveurs d'application. Néanmoins, on constate que le passage d'un serveur JEE à un autre peut nécessiter un certain nombre d'adaptations.

Ce billet a pour objectif de préciser les modifications faites pour assurer le déploiement du service web sur WebSphere 8.5. Il a également vocation à conserver une trace des erreurs spécifiques rencontrées dans le déploiement du service. On verra que la modification principale a concerné la simplification du fichier web.xml.

Environnement de travail 

Un environnement de travail mal maitrisé est une des sources principales de problèmes dans la mise en œuvre des services web. C'est pour cette raison que je précise l'environnement utilisé pour réaliser mon test.
L'élément le plus important est l'utilisation à la fois en développement et en exploitation d'un JDK 1.7. L'utilisation d'une version différente (et surtout inférieure) nécessitera probablement de nombreuses adaptations.

J’ai utilisé un Eclipse Luna (version 4.4) for JEE Web developper sur un MacOs Yosemite. Le JDK utilisé pour la compilation est un JDK 1.7. Les tests ont été réalisés sur un WebSphere tournant dans une VM Virtual Box de type Fedora. Le runtime Java utilisé est le 1.7.

L’utilisation d’un JDK 1.7 est importante car elle a permis de s’affranchir de l’ajout de Jar dans la configuration du projet Eclipse. Le JDK 1.7 contient la description des interfaces JAX-WS et JAXB.
L’utilisation d’un runtime Java 1.7 pour WebSphere est importante car il existe un certain nombre de remarques sur le Web indiquant des problèmes quand le WebSphere est configuré avec une version 1.6 du runtime Java.

Création du projet

Cette étape fait référence au billet : http://jl2tho.blogspot.fr/2011/11/etape-2-du-tutorial-configuration-dun.html
Nous créons comme dans le billet, un projet de type Dynamic Web : c’est important pour avoir une structure de projet Web.

J’utilise comme server runtime le Tomcat 8.0 que j’utilise pour mes autres projets. La version du serveur d'application n'a pas grande importance, il ne sera pas utilisé autrement que pour en déduire l'environnement de compilation : ce qui a de l'importance c'est le runtime java 1.7 qu'il utilise.
Mon serveur Tomcat 8.0 utilise un runtime Java 1.7.
Pour éviter les problèmes, je vous recommande l'utilisation d'un serveur JEE configuré avec un runtime 1.7.

Lors de la création du projet, je force le « Dynamic Web Module version » pour prendre la 3.0.

Attention à ne pas utiliser une version antérieure avec WebSphere 8.5. Cela semble poser des problèmes.
C'est l'unique différence dans la phase de création d'un projet avec le billet d'origine.

Pour le test, on a coché l’option « Generate web.xml deployment descriptor ».

Une fois le projet Eclipse créé, je n'ai pas eu besoin d'ajouter aucun jar pour disposer des annotations JAX-WS et JAXB. Ces annotations sont incluses (depuis la 1.7) dans le runtime Java. Ce point est une différence vis à vis du tutoriel.

Configuration du web.xml

Par rapport au billet d'origine (http://jl2tho.blogspot.fr/2011/11/etape-2-du-tutorial-configuration-dun.html), c'est le contenu du fichier web.xml qui a été la source de tous les problèmes rencontrés lors de nos tests.

Dans WebContent/WEB-INF/web.xml, j’ajoutai, dans le tutoriel, la déclaration du web service en définissant un mapping d’url du type « /* ».
<servlet>
<servlet-name>WebContractHelpdesk</servlet-name>
<servlet-class>fr.j2ltho.webcontracthelpdesk.server.HelpdeskServiceBean</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>WebContractHelpdesk</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>



Il n’est plus nécessaire de modifier le web.xml : la déclaration de la servlet est inutile. C’est même pour WebSphere une source d’erreur.

Avec la déclaration de ma servlet et de son mapping, j’avais initialement l’erreur suivante au démarrage de l’application:

[29/05/15 11:27:26:212 CEST] 00000087 WASSessionCor I SessionContextRegistry getSessionContext SESN0176I: Un nouveau contexte de session va être créé pour la clé d'application default_host/exContartFirst [29/05/15 11:27:26:294 CEST] 00000087 webapp        W com.ibm.ws.webcontainer.webapp.WebApp initializeStaticFileHandler SRVE0278E: Erreur lors de l'ajout du mappage de servlet --> /*.

La documentation WebSphere recommande l’ajout d’un fichier ibm-web-ext.xml dans le WebContent/WEB-INF du projet.

SRVE0278E: Erreur lors de l''ajout du mappage de servlet --> {0}. 
 Explication
 Il s'agit d'une erreur d'application.
 Action
 Définissez fileServingEnabled=false dans le fichier ibm-web-ext.xmi situé dans le dossier WEB-INF.

J'ai donc créé le fichier ibm-web-ext.xml (attention en WebSphere 8.5, c’est bien une extension xml qu’il faut utiliser) avec le contenu suivant :

<?xml version="1.0" encoding="UTF-8"?>
<web-ext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd
version="1.0">
  <enable-file-serving value="false" />
</web-ext>


L’erreur s’est alors transformée en :

[29/05/15 14:07:30:667 CEST] 000000ff WSModuleDescr E   WSWS7027E: Les descriptions de service JAX-WS n'ont pas pu être générées correctement en raison de l'erreur suivante : javax.servlet.ServletException: WSWS7067E: Le servlet WebContractHelpdesk ne peut pas spécifier le caractère * comme masque d'URL.     at com.ibm.ws.websvcs.desc.WSModuleDescriptorImpl.updateEndpointURLS(WSModuleDescriptorImpl.java:1550)     at com.ibm.ws.websvcs.desc.WSModuleDescriptorImpl.buildJAXWSServices(WSModuleDescriptorImpl.java:1313)

On notera que cette seconde erreur survient à l’installation/déploiement du war.
Ce second message est clair : le pattern /* n'est pas apprécié par le module JAX-WS de WebSphere.

J'ai également constaté dans les exemples d'implémentation de la norme JAW-WS, que le servlet restait vide.

En conséquence, j'ai corrigé le web.xml afin d'obtenir cette version qui sera la finale

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>JaxWsContractFirst</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>


Cette version résout le problème et permet de se passer du fichier ibm-web-ext.xml qui est donc inutile pour notre test.

Vous noterez le numéro de version à 3.0 et sa cohérence avec le web_app_3_0.xsd. Ce point peut être important pour un serveur WebSphere 8.5 : on trouve beaucoup de billets indiquant des problèmes quand le numéro de version n'est pas 3.0.

Suppression des annotations EJB

Mon tutorial s’appuyait sur la création d’un EJB que l’on transformait ensuite en Web Service.
Ainsi dans le billet : http://jl2tho.blogspot.fr/2011/12/etape-4-annotations-jax-ws-et-jaxb-des.html on ajoute plusieurs annotations celles des EJB et celles spécifiques aux Services Web.


Pour simplifier ma configuration et la rendre plus portable (certain container WebService comme CXF ne supporte pas les EJB), j’ai supprimé les annotations suivantes :
  • @Remote au niveau de l’interface
  • @Stateles au niveau du bean implémentant l’interface.


ll s’agit d’une suppression simple : elles n’ont pas été remplacée par une autre annotation.


Déploiement dans WebSphere 8.5

Je n’utiliserai pas la fonctionnalité de test intégré à Eclipse, car je n'ai jamais eu la patience de configurer mon Eclipse pour qu'il fonctionne en développement avec WebSphere.
La solution repose, sur la production d'un war que je déploie ensuite dans WebSphere.


La première étape est la réalisation du war. Il est créé manuellement depuis Eclipse grâce à la fonctionnalité Export -> Export war.
Mon war porte le nom de mon projet Eclipse : JaxWsContractFirst.war


Pour réaliser le déploiement sur WAS 8.5, il faut se connecter à la console d'administration.
Attention ! Dans WebSphere, le port de la console d'administration diffère de celui des applications. Dans mon cas, l'url était : http://vmwebsphere:9060/ibm/console


Une fois connecté, on ouvre le nœud Application puis on clique sur le lien « Nouvelle application ».
Le panneau « Nouvelle application » apparaît.

On clique sur le lien « Nouvelle application d'entreprise ».
Le panneau « Préparation de l'installation de l'application » s'affiche.
Dans chemin de la nouvelle application, on sélectionne « Système de fichiers local » pour récupérer un fichier qui se trouve sur l'ordinateur qui exécute le navigateur.
Pour information, le système de fichiers éloigné fait référence aux disques du serveur sur lequel s'exécute le serveur WebSphere.
On utilise le bouton parcourir pour récupérer le war que l'on a créé plus tôt.



Si on clique sur Suivant, on arrive à l'écran du choix « Comment voulez-vous installer l'application ?».
Je sélectionne l'option  Raccourci - Ne demander que si des informations supplémentaires sont requises. »


Ensuite, on conserve le défaut jusqu’à l’étape 4 « Mappage des racines de contexte des modules Web » pour laquelle on complète la colonne « Racine du contexte » avec la valeur /wsContractFirst.
Cette valeur est libre à condition qu’il n’existe pas d’autres applications sur le serveur qui utilise la même valeur.





Ensuite, on conserve les valeurs par défaut jusqu’à la fin.
On termine en appuyant sur le lien « Sauvegarder ».


Si on retourne sur les « Applications d’entreprise WebSphere », on doit avoir dans la liste une application « JaxWsContractFirst_war » dont l’état est Arrêter (croix rouge).


Si on clique sur le lien « JaxWsContractFirst_war » on obtient la page « Application d’entreprise > JaxWsContractFirst_war.
Cette page doit impérativement contenir un pavé « Propriétés des services Web ».




Le lien « Publication des fichiers WSDL » permet la récupération du fichier WSDL et XSD. C’est le seul mécanisme pour avoir accès à la totalité du WSDL.




Attention, si le pavé « Propriétés des services Web » n’est pas présent, c’est qu’une erreur a eu lieu lors du déploiement.
Pour en savoir plus, vous pouvez aller dans le répertoire : /opt/IBM/WebSphere/AppServer/profiles/NatSystemWAS/logs/natsystem où natsystem est le nom du serveur.
Le fichier SystemOut.log contient les erreurs.


Il faut ensuite démarrer l’application depuis la page « Applications d’entreprise ».
Une fois, démarrée, la page http://vmwebsphere:9080/wsContractFirst/WebContractHelpdesk?WSDL doit renvoyer le WSDL.


Si vous obtenez, l’erreur suivante :
Error 404: com.ibm.ws.webcontainer.servlet.exception.NoTargetForURIException: No target servlet configured for uri: /wsContractFirst/WebContractHelpdesk


Cela peut vouloir dire que vous avez oublié de la démarrer ou qu’une erreur a eu lieu lors du démarrage.


Quelques erreurs de déploiement

Property {} is present but not specified in @XmlType.propOrder 


On a dans la log, une première erreur :

[01/06/15 13:56:28:883 CEST] 00000090 WSModuleDescr E WSWS7027E: Les descriptions de service JAX-WS n'ont pas pu être générées correctement en raison de l'erreur suivante : javax.xml.ws.WebServiceException: WSWS7054E: Le fichier WSDL (Web Services Description Language) n'a pas pu être généré pour la classe d'implémentation du service Web fr.j2ltho.webcontracthelpdesk.server.HelpdeskServiceBean en raison de l'erreur suivante : javax.xml.ws.WebServiceException: Unable to create JAXBContext
at com.ibm.ws.websvcs.wsdl.WASWSDLGenerator.generateWsdl(WASWSDLGenerator.java:238)
at org.apache.axis2.jaxws.description.impl.EndpointDescriptionImpl.generateWSDL(EndpointDescriptionImpl.java:2084)
at org.apache.axis2.jaxws.description.impl.EndpointDescriptionImpl.<init>(EndpointDescriptionImpl.java:449)


Suivi plus loin de :
Caused by: java.security.PrivilegedActionException: com.ibm.jtc.jax.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Property lastModification is present but not specified in @XmlType.propOrder
this problem is related to the following location:
at private java.util.Date fr.j2ltho.webcontracthelpdesk.server.QuestionMsg.lastModification
at fr.j2ltho.webcontracthelpdesk.server.QuestionMsg
at private fr.j2ltho.webcontracthelpdesk.server.QuestionMsg fr.j2ltho.webcontracthelpdesk.server.jaxws.CreateQuestion.inputQUESTION
at fr.j2ltho.webcontracthelpdesk.server.jaxws.CreateQuestion



La propriété indiquée (en l’occurence lastModification) de la classe indiquée (QuestionMsg) possède une annotation @XmlElement mais n’est pas présente dans la liste propOrder de l’annotation @XmlType de la classe.


Test avec SOAP UI

Soap UI dispose d’une fonctionnalité « New SOAP project » qui permet à partir d’un « Initial WSDL », la génération d’un jeu de requête pur ce WSDL.
La fonctionnalité permet de spécifier une URL de WSDL, si dans notre cas, on précise l’URL suivante : http://vmwebsphere:9080/wsContractFirst/WebContractHelpdesk?WSDL


On aura une erreur :


Pour importer, le WSDL, il faut le récupérer depuis la console d’administration (comme décrit précédemment) puis le dezipper dans un répertoire.


Ensuite, on pointe sur le fichier récupéré.
Attention à changer l’url ! Dans mon cas, c’était http://vmwebsphere:9080/wsContractFirst/WebContractHelpdesk.


Conclusion

Ce billet complète la série sur les Web Services en l'actualisant dans un contexte WebSphere 8.5 et un JDK 1.7



0

Ajouter un commentaire

Archives du blog
S'abonner
S'abonner
Libellés
Qui êtes-vous ?
Qui êtes-vous ?
Ma photo
Directeur Technique d'un éditeur de logiciel français
Links
Messages les plus consultés
Messages les plus consultés
Chargement en cours