Présentation La Mêlée Numérique 14 : Stratégies et développements mobiles multi-plates-formes

Plus de présentations presentations de DocDoku.
Concernant les problématiques de compilation croisée, il est à noter qu’Apple a modifié récemment la licence d’utilisation que chaque développeur doit signer lors du téléchargement de l’iPhone OS 4 SDK :
3.3.1 — Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs. Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine, and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs (e.g., Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited).
Le risque de se voir refuser l’accès à l’Appstore pour une application conçue par cross compilation est donc bien réel.

JSF 2.0, enfin correct !

Voila quelques mois maintenant sortait dans sa version finalisée la spécification Java EE 6.
Dans la foulée la version 3 de glassfish était mise à disposition.

Globalement, la plateforme va vers plus de modularité et de simplicité avec notamment la généralisation des annotations ou encore l’apparition des profils qui servent à regrouper les API Java EE en plusieurs familles. Pour l’instant, il n’existe que deux profils, le profil complet et le profil Web.

Java EE a clairement atteint aujourd’hui l’âge de la maturité, le modèle de développement standard Java pour les applications d’entreprises n’a plus de véritables faiblesses comme par le passé avec les abominables EJB2. Malgré tout, parmi les nombreuses briques définies par la spécification, il en reste une que les développeurs auront tendance à substituer par une alternative open source ; je pense à JSF.

JSF n’a jamais été le framework brillant devant lequel on tombe en émerveillement le jour où on le découvre. Il n’a pas l’étoffe d’un Struts qui au début des années 2000 structura en MVC nos applications web ni la souplesse de Spring Ioc, la puissance de Spring AOP ou encore la simplicité de GWT. Toutefois la version 2 efface les principaux reproches qui étaient faits au framework en apportant :

  • Support de la méthode HTTP GET qui permet de faire des URLs « bookmarkable »
  • Support d’AJAX avec le rendu partiel de la vue
  • Moteur de templating
  • Navigation implicite entre les pages (<navigation-rules> n’est plus obligatoire)
  • Facelets préféré aux JSP

Ainsi aujourd’hui, il est possible de choisir JSF 2 pour implémenter la couche de présentation d’une application web sans forcément faire une erreur !

HTML 5, the next big thing

HTML 5 est assurément la prochaine révolution en matière de développement de sites internet et d’applications web. Grâce entre autres à WebGL (API 3D), WebSocket (connexions TCP full-duplex) ou encore Web Storage (stockage de données en local côté navigateur) il n’y a plus de frontière entre applications natives et applications web et cela sans plugin.

Pour se convaincre des possibilités, il suffit de voir le portage du jeu Quake 2 sur ces technologies.

La référence sur GWT 2

J’ai eu le plaisir il y a quelques jours de recevoir, de la main même de l’auteur à l’occasion d’un déjeuner, le livre Programmation GWT 2.

J’ai préféré attendre d’avoir bien parcouru le livre avant d’écrire ce billet. J’aime autant le dire tout de suite : ce livre est LA référence sur GWT 2. Tout y est : les incontournables services RPC, l’intégration JEE, l’UiBinder, la communication avec le monde JavaScript mais aussi les Designs Patterns MVC (Model View Controller) ou MVP (Model View Presenter).

Au niveau de l’approche, la grande force du livre de Sami Jaber est qu’il est didactique et pointu à la fois, il convient donc aussi bien aux débutants qui veulent plonger dans le monde AJAX avec GWT qu’aux développeurs chevronnés. Un signe qui ne trompe pas sur la qualité de l’ouvrage : nos consultants qui ont près de 2 ans d’expériences sur GWT se l’arrachent !

Le cache d’entités JPA

Si le recours à un ORM (Object-Relational Mapping) permet des gains de productivité et facilite la maintenance des applications, ce type de framework introduit néanmoins des problématiques nouvelles, qui, pour être évitées, exigent une très bonne connaissance des mécanismes internes au moteur de mapping.

Parmi ces difficultés classiques, on peut citer la gestion du cache d’objets.

La validation finale de la spécification de JEE 1.6 (JSR 316) qui inclut la version 2 de JPA, intégrant des évolutions appréciables en matière de prise en compte du cache, est l’occasion de revenir ici un peu sur le sujet.

En réalité les ORM possèdent deux caches distincts :

jpa_caches

Cache de premier niveau (L1)

Le cache de premier niveau est rattaché à l’objet EntityManager, il s’agit en fait du « persistence context » qui lui est associé. Pour rappel, c’est à partir d’une instance d’EntityManager que les entités (les objets persistés en base de données) sont créés, récupérés ou encore supprimés. La classe EntityManager est définie par l’API standard JPA, elle est l’équivalente de la classe Session dans l’API native Hibernate.

Le contexte de persistance regroupe un ensemble d’entités en garantissant que pour une même entité il n’y aura qu’une seule instance d’objet. En prenant garde à ne pas dupliquer les objets de même identité, le contexte de persistance agit donc comme un cache d’objets : les recherches, qu’elles soient faites au travers d’une Query ou avec la méthode find(Class<T> entityClass, Object primaryKey), retourneront toujours les mêmes instances d’objets, piochées dans le cache, pour matérialiser un même enregistrement en base. Le contexte de persistance est lié à la transaction en cours, il sera vidé à la conclusion de celle-ci.

Le fonctionnement du contexte de persistance qui vient d’être décrit est celui qui est le plus couramment employé, il s’agit du mode PersistenceContextType.TRANSACTION. Néanmoins, il existe un autre mode dit « étendu », le paramétrage du contexte de persistance se fait dans le code Java, lors de l’injection de l’EntityManager :

@PersistenceContext(type=PersistenceContextType.EXTENDED)
private EntityManager em;

Dans cette configuration, le PersistenceContext n’aura pas une durée de vie corrélée à la transaction mais au Stateful Session Bean dans lequel il est déclaré. Ainsi, le cache d’objets sera maintenu sur plusieurs transactions à la base de données. Ce type de contexte de persistance peut par exemple être utilisé pour alimenter en données une page web requêtant en AJAX.

Cache de deuxième niveau (L2)

En dessous de ce cache placé sous la direction des EntityManagers se trouve un autre cache dit de second niveau. Ce cache est global à la JVM ou plus exactement à l’EntityManagerFactory. Il peut aussi être configuré au niveau cluster, dans ce cas le cache sera répliqué sur chaque JVM. Le cache de second niveau est donc partagé entre les EntityManagers qui iront l’interroger, si l’entité recherché n’est pas présent dans leur propre contexte de persistance, avant de se résigner à taper dans la base de données.

Si les règles régissant le cache de premier niveau sont relativement limpides, celles gouvernant le cache de 2ème niveau le sont un peu moins et le développeur peut légitimement se poser de nombreuses questions :

  • Quelle est la durée de rétention des objets dans le cache ?
  • Que se passe t-il si la base de données est modifiée en dehors de l’application JPA ?
  • Peut-on contrôler par configuration ou par du code ce cache ?

De manière générale, les réponses à ces questions dépendent avant tout de l’implémentation JPA choisie. D’ailleurs, si EclipseLink et TopLink activent par défaut un cache de second niveau ce n’est pas le cas d’Hibernate. Ce dernier a par contre été très tôt pensé de façon modulaire et accepte divers « cache provider » comme EhCache, OS Cache ou encore JBoss Cache. Chaque système de cache vient avec ses options et ses fichiers de paramétrages, il est souvent possible de les spécifier dans le fichier persistence.xml entre la balise <properties> ou dans le code par la méthode Query.setHint(String hintName, Object value).

En ce qui concerne les changements opérés dans la base sans passer par les couches de persistance de l’ORM ; là le résultat est identique quelque soit le framework : le cache de niveau 2 se retrouve obsolète et cela tant que l’entité en question ne sera pas rechargé. La plupart des caches d’objets utilisant des SoftReferences ou des WeakReferences, l’éviction de l’objet se produira à un moment indéterminé, au gré des pérégrinations du garbage collector. Pour ceux ne pouvant se contenter du caractère aléatoire des références faibles et qui veulent expressément déclencher le rafraichissement des données la classe EntityManager propose heureusement la méthode refresh qui s’utilise habituellement ainsi :

MonEntity e = em.find(MonEntity.class, id);
try {
em.refresh(e);
} catch(EntityNotFoundException ex){
e = null;
}

Toutefois, ce n’est que depuis la version 2 de JPA que le cache L2 est officiellement mentionné dans la spécification. Dans cette API, une classe Cache accompagnée de ses méthodes « evict » a fait son apparition et certains points de configuration ont été standardisés.

En conclusion

Il y aurait encore beaucoup à dire sur les caches d’entités et plusieurs billets seraient nécessaires, c’est pourquoi je conclurai simplement en invitant tous les développeurs et architectes à regarder sous le capon de leur framework de persistance et à ne pas se laisser « endormir » par la simplicité trompeuse de l’API JPA.

VMware Serveur OVH avec Windows 2003 en guest

L’hébergeur bien connu OVH propose, sur ses serveurs dédiés, un large choix d’OS parmi lesquels figure une distribution Linux pré-conçue pour accueillir des environnements virtualisés. Il s’agit en fait d’une Debian Etch 4.0 32bit avec VMware server 1.08 configuré pour tourner au-dessus. Pour ceux désireux d’affecter leur machine à un usage exclusif de host VMware et voulant privilégier les performances il faudra plutôt choisir l’OS VMware ESXi qui lui est un hyperviseur natif.

J’ai très récemment eu à mettre en place un serveur virtualisé Windows 2003 sur la distribution « VMware server » d’OVH. A cette occasion, j’ai constaté que les guides de l’hébergeur manquaient quelques peu de précisions et, qui plus est, sur des éléments capitaux.

Les tutoriels en question sont les suivants :

http://guides.ovh.com/vmware
http://guides.ovh.com/AjouterAliasIp

OVH, pour des raisons de sécurité, interdit l’usage du « bridged networking », nous avons donc le choix entre le « NAT » et le « host-only » où grâce à une IP failover le guest aura pleinement accès au réseau.

Même si en principe le choix du mode de connexion peut être changé par la suite, sélectionner malencontreusement le mode « bridged networking » engendre des modifications dans plusieurs fichiers de configuration qui s’avèrent difficile à défaire même en corrigeant l’option réseau. Il faut donc bien veiller à ne jamais choisir le mode « bridged networking » sur un serveur OVH.

Le paramétrage de la machine host ne pose pas de difficulté particulière. Là où ça se corse, c’est au niveau du guest Windows 2003 Server. Le tutoriel OVH oublie de mentionner un paramètre essentiel : la passerelle de la machine guest doit être elle-même, c’est à dire, elle doit avoir pour valeur l’IP failover qui est également l’adresse de la machine guest ! Ainsi va la virtualisation, la machine guest se sert du host pour communiquer avec le monde extérieur, toutefois cette configuration qui peut sembler étrange dans un contexte plus classique aurait méritée d’être ici explicitement notifiée.

Présentation Android

Le 6 octobre dernier lors de la deuxième session du JUG (Java User Group) de Toulouse et en prévision de la sortie de mon livre sur Android, j’ai fait une présentation générale de la plateforme.

Pour ceux qui n’étaient pas présents, le pdf est téléchargeable ici.

JavaFx vs Flex vs Silverlight

Après une période d’inactivité importante due à un beau projet Pierre et Vacances et l’écriture d’un livre sur Android, je reprends ce blog en main !

Je suis tombé dernièrement sur une comparaison des performances entre JavaFx, Flex et Silverlight. Bien que je ne sois pas tout à fait certain de la validité des résultats, il semblerait à vue de nez que JavaFx s’en sorte très honorablement.
Pourtant, je ne pense pas que dans son état actuel, cette technologie pourra décoller.
Le problème n’est pas qu’il faille réapprendre un nouveau langage de script, après tout même si cela demande un petit effort au départ, l’avantage de bénéficier d’un langage (DSL) spécifique à la définition d’interfaces graphiques devrait au final l’emporter.
Le souci n’est pas non plus l’absence d’outils orientés design car Production Suite devrait convenir à la plupart d’entre nous.
Non, le défaut majeur de JavaFx est son manque de discrétion : le temps de démarrage est beaucoup trop long et sans rapport avec Flash, la petite icône Java qui apparait dans la barre de notification est gênante car elle nous rappelle que « quelque chose » se lance, les fenêtres de sécurité sont invasives (heureusement aujourd’hui crossdomain.xml est en partie supporté) et enfin l’expérience utilisateur de l’installation du runtime et des mises à jour de la JVM, avec sa publicité Open Office et sa toolbar Yahoo, plus que moyenne.

A mon sens, tant que ces inconvénients ne seront pas corrigés, il y a très peu de chance qu’émerge un « youtube » s’appuyant sur JavaFx et cela quelles que soient les autres qualités de la plateforme.

Eclipse RAD

Il y a quelques jours lors d’un déjeuner avec Jean-Marie Damas (un des organisateurs de l’Agile Tour), nous avons évoqué le framework Eclipse RAP (Rich Ajax Platform).
Ce framework n’est pas vraiment tout nouveau et finalement si discret qu’il n’est pas très connu.
L’idée de RAP est d’être le pendant de RCP (Rich Client Platform) dans le monde Web. Il fournit le même environnement « Workbench » et les applications RAP sont implémentées avec les mêmes APIs SWT et JFace que celles tournant sous RCP.
Cette approche universelle peut séduire mais elle me rappelle un peu trop de nombreuses autres tentatives de grand écart qui se sont soldées pour la plupart par des échecs. JDO (Java Data Objects), par exemple, voulait offrir une API unique de persistance et cela quelque soit le système de stockage sous-jacent (BD, XML, fichiers à plat…).

Si l’on souhaite obtenir le meilleur de la plateforme d’exécution il n’est pas souhaitable de concevoir une application web comme une application lourde, une application de bureau comme une application pour mobile…La liste est longue !

architecture-RAP

JUG Toulouse

Ca y est, Toulouse a dorénavant son JUG !
Il était anormal qu’une ville avec une telle concentration de sociétés technologiques n’abrite pas de Java User Groups.

Pour ceux qui ne le savent, l’idée des JUG est de réunir les utilisateurs et les développeurs de Java dans un esprit d’échange et de convivialité. Nous organiserons des conférences gratuites et ouvertes à tous où seront faites des présentations techniques.

La première est prévue autour de mars/avril, le temps de trouver des sponsors et de mettre en place la logistique.

N’hésitez pas à vous inscrire sur le site ou à nous contacter pour participer.

A bientôt.

eBay

En faisant le ménage sur mon PC, je suis tombé sur cette photo que j’avais prise lors de mon séjour au mois de janvier chez eBay.
La raison de ma venue chez eux était liée à eBox.
Sans pouvoir donner beaucoup de détails pour cause de NDA, eBox est un framework extrêmement ambitieux. Le calendrier initial prévoyait la sortie de la version 1 pour 2008 avec certains modules en open source.
Hélas, l’année s’achève et quand on recherche « ebay ebox » sur google on ne trouve rien de plus récent que 2007 !

J’espère que cela n’est pas le signe d’un deuxième Krach Internet, j’ai rencontré chez eBay des gens passionnants dont les travaux m’ont souvent impressionné et j’aimerais bien en parler !

Installation de Glassfish sous linux

Comment installer glassfish en tant que service sous linux ?
Contrairement à Windows, installer n’importe quelle application sous forme de service n’est pas très compliqué sous un OS de type Unix.
Le billet suivant explique clairement la démarche à adopter.

Malheureusement, un petit hic survient quand on souhaite faire tourner glassfish sur le port 80.
Sous linux, il est purement et simplement impossible de configurer glassfish sur le port 80 si celui-ci ne tourne pas avec le compte root ce qui est toujours regrettable pour des raisons évidentes de sécurité.

Confronté à ce problème, j’ai tout d’abord envisagé (comme à la grande époque de Tomcat) de positionner un apache écoutant sur le port 80 devant glassfish qui serait lui sur le 8080. Je me suis aussi dit qu’au passage grâce à apache je pourrais faire du « Virtual Hosting » et utiliser les quelques applications php dont nous avons besoin.

Cependant, un tour sur internet, a vite calmé mes ardeurs. Les nombreux commentaires de ce post n’encouragent pas à la confiance.

Finalement, après mûre réflexion, j’ai choisi de laisser glassfish s’exécuter avec le compte root. Hormis cet inconvénient qui je l’espère ne tardera pas à être corrigé, les fonctionnalités natives de « Virtual Hosting » de glassfish, l’architecture modulaire OSGi de la version 3 et le repositionnement de la JVM comme une plateforme multi-langage me font penser que glassfish pourrait bien également concurrencer apache !

Upload et download de fichiers avec un web service (suite)

Ce message fait suite à mon précédent billet concernant le download et surtout l’upload de fichiers par Web Services SOAP.

Le bug 29 du projet jax-ws a bien été résolu, avec un petit bémol car la correction ne fonctionne qu’avec les Web Services à base de Servlet et non ceux basés sur les EJB Session. Cependant, pour transférer les données binaires MTOM utilise un transfer-coding de type chunked. Il s’agit d’une fonctionnalité d’HTTP 1.1 permettant d’envoyer ou de recevoir une requête HTTP par morceau.

La version 1.1 du protocole HTTP est vieille de plus de 10 ans. Malheureusement, dans de nombreuses organisations, sévissent encore des proxies web ne supportant que la version 1.0 !
Du coup, il n’est plus possible d’appliquer la propriété JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE sur le proxy du client. On se retrouve alors avec le problème initial ; on risque le « out of memory » côté client en téléchargeant sur le serveur (upload) un fichier volumineux.

Enfin, que les utilisateurs de DocDoku se rassurent, par défaut les échanges de fichiers se font par Web Services MTOM et en cas d’environnement réseau hostile (proxy http 1.0) le client bascule automatiquement dans un mode HTTP basique (multipart/form-data).

JavaOne

JavaOne s’est déroulé au début du mois à San Francisco. Cette conférence a mis à l’honneur Glassfish, le serveur d’application JavaEE Open Source de Sun, avec le lancement du GlassFish Technology Partner Program dont nous faisons partie. Ce partenariat matérialise notre expertise de la plateforme Java en général et de Glassfish en particulier.
L’autre technologie majeure présentée à JavaOne fut JavaFX. Beaucoup pensent que JavaFX arrive trop tard et qu’il ne pourra pas trouver sa place face à des concurrents comme Flash notamment. Pour ma part, je suis convaincu du contraire.
Le succès de Flash est éclatant et cela est largement justifié : très grande facilité de déploiement, temps de démarrage à froid impressionnant, qualité des outils de production, des codecs vidéo…
Néanmoins, dans le cadre du développement d’une application d’entreprise disposer d’un langage aussi riche que Java sur le client, surtout s’il est aussi utilisé sur le serveur, est un énorme avantage. Si JavaFX continue de progresser et que la version finale de Java SE 6 Update 10 tient toutes ses promesses, je recommanderai JavaFX et non Flex à nos clients industriels.

Goojet

Voilà un certain temps que Thomas m’a filé une invitation pour essayer Goojet et que je m’étais dit qu’il fallait que je poste sur le sujet.

goojet

Goojet est, avant tout, une application pour téléphone portable. Son ambition est de devenir le portail de votre mobile. L’innovation de Goojet tient à son approche hybride : web/téléphone. Vous pouvez en effet utiliser Goojet depuis votre ordinateur puis synchroniser l’état de l’application sur votre mobile.
Au delà de sa levée de fond, la force de Goojet réside dans la qualité de son équipe. Projet à suivre assurément, en plus c’est une startup Toulousaine !

Le futur de JSF

JSF ne s’est pas encore, gardons espoir, véritablement imposé comme LE framework web java.
La première des raisons est sans doute sa complexité. Essayez d’expliquer à un féru de php son Unified Expression Language pour vous en convaincre.
Deuxièmement, la spécification de JSF ne définit qu’une palette de composants graphiques très limité. Dans un projet réel, ceux-ci suffisent rarement ; il faut alors se tourner vers des extensions propriétaires, perdant du même coup la neutralité vis à vis de l’implémentation de JSF.
Enfin, le dernier point problématique est la difficulté d’intégration de JSF et d’AJAX.
Il est en effet compliqué de mixer l’approche purement « server-side » de JSF avec une logique AJAX où une partie du MVC est directement implémentée sur le client en javascript.
La jsr 314, celle de JSF 2.0, devrait remédier à cela en apportant des modifications importantes au cycle de vie notamment le parcours partiel de l’arbre des widgets.
Cela va dans le bon sens, néanmoins, il n’en demeurera pas moins que de plus en plus la logique cliente se trouvera portée par du code AJAX, laissant à JSF la gestion des tâches annexes.
Si JSF 2 marquera indéniablement l’acceptation d’AJAX par Java EE, ne faudrait-il cependant pas aller plus loin, en d’autre terme ; pour préserver sa pertinence, JSF 3 ne devra t-il pas être un framework en bonne partie javascript ?

Upload et download de fichiers avec un web service

Comment faire pour « uploader » et « downloader » un fichier vers et depuis un web service ?
Très simple me diriez-vous et depuis longtemps. Il suffit d’utiliser SAAJ (SOAP with Attachments API for Java) ou encore mieux MTOM (Message Transmission Optimization Mechanism) pour bénéficier de l’assurance d’une compatibilité .Net/Java optimale.
En théorie cela semble simple mais quand on passe à la pratique, dans le contexte d’une application réelle, les choses se compliquent bigrement, en tout cas en ce qui concerne l’implémentation de JAXWS.
La plus grosse lacune de JAXWS au niveau MTOM est son incapacité à transmettre les données binaires sous forme de flux de bout en bout. Comme expliqué ici il est bien possible d’indiquer au client d’utiliser le mode « streaming » mais côté serveur rien à faire, l’ensemble des octets constituant le fichier est monté en mémoire.
Même côté client, JAXWS mériterait quelques améliorations. En effet il n’est pas possible de superviser la progression du transfert, de plus le mode « streaming » opère en appelant HttpURLConnection.setChunkedStreamingMode sur la connexion sous-jacente ce qui pose des problèmes car de nombreux serveurs web ou proxy ne supportent pas ce mode. Il serait intéressant que JAXWS calcule la taille du contenu à poster et invoque plutôt la méthode HttpURLConnection.setFixedLengthStreamingMode.

Conclusion de tout cela, pour uploader un fichier en http rien ne vaut d’utiliser directement HttpURLConnection et d’implémenter le basique et standard upload multipart/form-data.

JAXB 2.1 avec Java 6

Le choix d’inclure (précipitamment ?) JAXB au jdk 1.6 a des conséquences fâcheuses. En effet, la version de l’API intégrée au jdk est la 2.0, et très souvent il est indispensable de passer à la 2.1 pour bénéficier de fonctionnalités comme par exemple l’annotation XmlSeeAlso.
Pas de problème me diriez-vous, il suffit de rajouter -Djava.endorsed.dirs=jaxb-api.jar à la ligne de commande de java pour « patcher » le jdk.
Malheureusement, si votre application est distribuée au travers de Java Web Start, le mécanisme de classes « endorsed » ne fonctionne pas.
Pour s’en sortir une seule solution faire des acrobaties avec les ClassLoaders. Ce billet explique cela en détail. Dans le cadre d’une application swing, il faudra bien penser à appeler la méthode setContextClassLoader également sur le thread gérant les événements système comme ceci :
EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
eq.invokeAndWait(new Runnable() {


public void run() {


Thread.currentThread().setContextClassLoader(modifiedClassLoader);

}


});

C’est du sport mais ça marche !

web services avec JAX-WS

Initialement le client (java web start) DocDoku communiquait au serveur (composants ejb) à l’aide du protocole corba IIOP.
Malheureusement, à tort ou à raison, les proxies http sont souvent le passage obligé pour accéder à internet dans de nombreuses sociétés.
Nous avons donc décidé de passer aux web services. Aujourd’hui cette migration est terminée mais je dois avouer que ce fut plus compliqué que prévu. Voici un bref retour d’expérience :

Au niveau sécurité, les options sont nombreuses, nous avons néanmoins opté, par prudence, pour la simplicité : authentification basic sur du SSL.
Ce poste explique ceci en détails.

Ensuite, la grande difficulté a été d’utiliser nos POJOs sur le client et le serveur sans passer par une couche d’objets intermédiaires mappant le wsdl.
Etrangement, aucun tutorial de Sun n’explique clairement cela et les assistants de netbeans génèrent invariablement cette couche d’objets (avec la commande wsimport) même si le webservice a été créé à partir d’une interface SEI (Service Endpoint Interface).
Sous les conseils d’Alexis, j’ai filé un bug chez netbeans.
Enfin, la solution est la suivante, il faut donc définir une interface pour l’EJB avec endpoint webservice et non simplement annoter les méthodes avec @WebMethod.
Ensuite, importer les classes produites par wsgen également sur le client.
Enfin, récupérer le web service Port par javax.xml.ws.Service.getPort(Class<T> serviceEndpointInterface).

JSR-170 (Java Content Repository)

La JSR-170 (ou JCR) vise à définir une API standard pour accéder aux « content repositories ». Tous dépôts conformes à cette spec présentent une vue hiérarchique des données et méta-données, offrent des services de versioning, d’import-export XML, ainsi qu’une gestion d’évènement permettant d’être notifié en temps réel des modifications. Les JCR sont également interrogeables au travers d’XPath.
Certains parlent de la JSR-170 comme du jdbc des CMS (Content Management System).
La question est donc de savoir si les JCR arriveront à s’imposer comme briques de bases de tous CMS qui se respectent. La réponse n’est pas évidente.
La JSR-170 est d’une manière ou d’une autre en concurrence avec JPA (Java Persistence API) ou plus généralement avec les ORM. La talon d’achille des JCR est, pour l’instant, l’absence d’outil de mapping Objet/JCR. Il existe bien un embryon de projet mais rien de comparable à Hibernate ou Toplink. Du coup, les gains de productivité dus aux services supplémentaires disponibles pourraient être perdus à développer le mapping objet.
Cependant, les choses pourraient changer assez rapidement, et des outils autour des JCR pourraient apparaître.
Enfin, on peut noter que la JSR-283 est sur les rails, elle corrige certains défauts de sa grande sœur ; par exemple, elle rajoute un type de node spécifique pour les metadata ce qui manque cruellement à la JSR-170.