Comme vous le savez, la première session des After-Works a été un très (trop ?) grand succès.
Nous pensions dans un premier temps n’avoir qu’au mieux une quinzaine de participants, nous nous sommes retrouvés à 3 jours de l’événement avec 70 inscrits…
Pour cette raison, nous avons du prendre plusieurs mesures afin d’être en mesure d’absorber la charge des participants :
- Nous avons doublé la session le soir de l’événement (encore merci à POG pour sa participation) et utilisé une deuxième salle plus grande,
- Nous avons décidé de créer une deuxième date dans le calendrier, et que cette deuxième devait avoir lieu au plus tôt pour ne pas perdre trop de monde en route.
Que nos amis “.netistes” se rassurent, nous ne les oublions pas, et nous allons replanifier la session initialement prévue en décembre sur Linq en début d’année 2009.
Merci à tous ceux qui ont participé à cet événement. Mention spéciale à Anthony, Pascal, notre équipe marketing et recrutement, et bien sur les personnes de Valtech Training qui nous ont aidé. Pour information, notre cellule recrutement/RH va commencer à rappeler nos visiteurs qui ont accepté de l’être dès aujourd’hui.
Article mis à jour lors de la seconde présentation Afterwork GWT
Lors de cette soirée, Pascal Ognibene (groupe avec les ordinateurs portables) et moi même (groupe dans la salle de formation) avons pu présenter la technologie GWT, en manipulant un peu.

La présentation s’est déroulée en 5 étapes :
- Présentation de GWT (historique, raisons de la création du projet, ce que çà fait, ne fait pas)
- Création d’un projet GWT à l’aide des scripts de génération fournis
- Création d’une application (partie cliente)
- Création d’une application (partie serveur, avec les appels asynchrones RPC)
- Conclusion
Certes s’il est vrai qu’il est difficile de pouvoir manipuler lors d’une présentation de 2h30, les participants (venus nombreux >50 en tout, de profil plutôt techniques , en tout cas dans mon groupe ) ont pu découvrir ce qu’il était possible de faire avec GWT, et dans quelles conditions (debugger, tout en java, dans eclipse, etc…)

En tout cas, les premiers retours sur cette soirée sont positifs, que ce soit des participants ou des organisateurs (Valtech Technology Consulting Paris et Valtech Training) que je remercie pour leur temps et leur efficacité !
Par ailleurs, tous les inscrits n’ont pu participer à cette session par manque de place; pour ceux qui sont intéressés, vous pouvez réserver votre soirée du Mercredi 17 Décembre, et vous inscrire à la session supplémentaire AfterWork Valtech GWT.
Enfin, chose promise, chose dûe :
Voici ci dessous en animation Flash et en pièce jointe de ce post la présentation qui a été donnée lors de cette soirée.
after_work_gwt odp
after_work_gwt pdf
after_work_gwt power point
Le premier ‘Valtech After work‘ a eu lieu mardi dernier le 25 novembre.
Ce fut un succès. Des personnes très diverses sont venus librement et ont eu ce qu’elles étaient venues chercher: un aperçu clair et appliqué d’une des dernières technologies de Google. Ces développeurs ont appris par l’exemple ce que l’on peut attendre de GWT.
La session a été partagée en deux groupes pour différencier les personnes venues avec leur portable de celles qui ont pu utiliser les machines pré configurées des locaux de Valtech Training. C’était un bon moyen de faire découvrir comment les consultants Valtech ont la possibilité d’échanger régulièrement leurs connaissances ensemble autour des technologies, des pratiques ou de leurs expériences pendant les cours du soir internes Valtech.
En discutant avec les participants, on pouvait aussi ressentir l’intérêt de ces développeurs pour les pratiques agiles.
Anthony, à l’initiative du sujet, mettra prochainement à disposition ici le contenu du cours.
Le prochain évènement sera la session sur Linq. N’hésitez pas à vous inscrire afin de découvrir à votre tour l’ambiance et la technologie Microsoft avec Sadek dans le prochain Valtech After work le 3 décembre.
Edit: Finalement, le prochain Valtech After work sera à nouveau une session sur GWT pour satisfaire les personnes qui n’ont pas pu assister à celle-ci. Elle se tiendra le 17 décembre toujours dans les locaux de Valtech Training: comment venir ?. Inscrivez-vous !
Le cours du soir de la semaine prochaine sera assuré par Anthony (qui a décidément des choses à partager!) et Pascal Ognibene. Il s’agit d’une présentation de GWT, avec des vrais TPs à réaliser vous-mêmes (pensez à apporter vos ordinateurs).
Vous pouvez vous inscrire en ligne, mais dépêchez-vous: nous avons déjà reçu énormément d’inscriptions.
Voici le programme prévu:
- L’environnement de développement GWT
- Les Widgets GWT
- Les panels dans GWT
- Étendre GWT : plugins GWT, création d’un Widget
- Appels distants via RPC : l’application GWT se connecte à une servlet de services
- forces et positionnement de GWT
Il ya de celà un mois, j’ai présenté à mes camarades de Valtech le framework GWT (Google Web Toolikt); après avoir suivi une formation dessus chez Valtech Training (dispensée par Sami Jaber).
Je vous invite à télécharger cette présentation,(certes largement inspirée de celle de Sami) où vous découvrirez :
* présentation de GWT
* mise en place d’un environnement de développement GWT, création du workspace
* (TP) votre premier module GWT, “Salut Monde” !
* (TP) présentation d’une dizaine de widgets GWT (non exhaustif) à travers des manipulations (Label, TextBox, SuggestBox, etc…)
* (TP) les panels dans GWT
* présentation d’extensions GWT (GXT, GWT Ext, etc…)
* (TP) création d’un widget
* (TP) appels distants via RPC : notre application GWT se connecte à une servlet de services
Vous n’oublierez pas de télécharger aussi l’archive contenant les TPs en fin d’article !
Bon GWT !
![Creative Commons License]()
Présentation GWT Valtech by Anthony Dahanne est mis à disposition selon les termes de la licence Creative Commons Paternité-Pas d’Utilisation Commerciale-Partage des Conditions Initiales à l’Identique 2.0 France.
workspace_gwt
cours_du_soir_gwt
Depuis deux semaines, la communauté Open-Source en général et GWT en particulier ne parlent plus que de ça : le changement de licence ExtJS et par extension celui de MyGWT.
L’idée ici n’est pas de raconter une nouvelle cette histoire: d’autres articles l’ont déjà fait et bien fait (cf. l’excellent billet de Sami, dont je partage entièrement l’avis sur l’inélégance et l’embarras suscité par ce changement de licence), et y revenir n’apporterait pas grand-chose.
Maintenant que le fracas des échanges passionnés commence à s’estomper, cet épisode m’inspire plusieurs sentiments mitigés concernant l’écosystème GWT.
Le premier élément de réflexion est l’évidente fragilité de la plateforme. Ainsi, il suffit d’un seul changement, décidé par un seul homme, non salarié de Google qui plus est, pour faire trembler l’édifice tout entier et remettre en cause nombre de développements GWT en cours. Ce simple constant me semble édifiant, et à vrai dire, assez inquiétant.
L’élément central de cette fragilité n’est sans doute pas à chercher bien loin : du fait de l’incomplétude de GWT est née la notion d’écosystème. En effet, le noyau fourni par Google se limite essentiellement à un (excellent) compilateur Java -> Javascript, qui permet de s’affranchir de l’enfer des moteurs Javascript des différents navigateurs, et au hosted mode permettant le debug en Java du code GWT.
Pourtant, en dehors de ce compilateur, pas grand-chose : peu de composants graphiques, pas de micro-architecture MVC à la Cairngorm, une intégration avec les serveurs et technologies existantes réduites au plus strict minimum…
Le manque le plus criant concerne bien entendu les composants graphiques « natifs », dont la pauvreté est clairement rédhibitoire dans une comparaison avec Flex ou une autre plateforme Ajax. Il ne fournit pas de vrai data-grid, ni aucun composant réellement avancé…
Ainsi, pour combler les différents manques de GWT, plusieurs librairies ont vu le jour : MyGWT, GWT-Ext pour la partie graphique, GWT-SL pour l’intégration avec Spring, Gwittir, etc…
Développer une application GWT devient donc un puzzle, consistant à assembler différentes librairies Open-Source, généralement développées par des individuels, certes talentueux mais qui n’apportent pas les garanties de pérennité nécessaire à un développement commercial.
A titre de comparaison, imaginez un monde où Sun ne fournirait que le compilateur et quelques classes de base et que Swing, les servlets, RMI n’étant que des librairies fournies par de simples ingénieurs, qui pourraient tout abandonner du jour au lendemain… Effrayant, n’est-ce pas ?
Sur ce point, Flex se distingue assez nettement de la philosophie GWT : les librairies Open-Source incontournables (BlazeDS, FlexUnit, Cairngorm…) sont validées et hébergées par Adobe, ce qui assure une stabilité du framework dans son entier.
C’est d’ailleurs, à mon humble avis, de ce comportement dont devrait maintenant s’inspirer Google : fédérer les librairies jugées « indispensables », les intégrer au framework afin de l’enrichir et d’assurer la pérennité de ces briques nécessaires à tout développement.
Soyons clair : je pense toujours que GWT est un framework intéressant et riche en potentiel, avec de vrais atouts dans la bataille RIA en cours. Mais sans unification, sans stabilisation de l’écosystème, tout développement reste à la merci d’un revirement individuel, ce qui est clairement peu acceptable dans un environnement industriel où les investissements se chiffrent en dizaines voire centaines de millier d’euros.
A suivre…
Foreword
I am currently working on a EJB3 / Flex3 project and face a very familiar issue.
BlazeDS is an open-source library, published by Adobe, to send messages from Flex code to java one (and vice-versa). The source code is an extract of LiveCycle Data Services, its commercial ancestor, still alive and handling more functionalities.
One of the most missing features of BlazeDS is an adapter to send Hibernate beans from a Java server to the Flex/Action Script client side, whereas this adapter is available in LiveCycle DataService (but it costs a lot of $$$, including runtime fees).
Hibernate4GWT ?
Hibernate4GWT is a open-source library I am working on since more than one year now to allow sharing Hibernate beans from server to GWT client side. But, despites of its name, the core of the library is really independent of GWT (don’t worry, you won’t have to add GWT libraries to your Flex project
):
- The ‘clone’ operation consists of converting Hibernate beans to pure, regular beans. Proxies are removed, and Persistent collections converted to their classic counterparts. Of course, persistence information handled by proxies and persistent collections are stored to be reused when the POJO comes back.
- The ‘merge’ operation takes the neutral bean and merges it back to a Hibernate bean. Proxies and persistent collections are regenerated accordingly to what was undone by the clone operation.
Defining your own adapter
It is pretty simple, and well documented here.
So here is the code:
/**
* Hibernate adapter for BlazeDS
* It is based on hibernate4gwt core and delegates Hibernate beans management to it.
* @author bruno.marchesson
*
*/
public class HibernateAdapter extends JavaAdapter
{
/**
* The Hibernate bean manager
*/
private HibernateBeanManager _beanManager;
//————————————————————————-
// Java adapter override
//————————————————————————-
/**
* Adapter initialisation
*/
@Override
public void initialize(String name, ConfigMap config)
{
// Call base method
//
super.start();
// Get EntityManagerFactory
//
Object entityManagerFactory = getEntityManagerFactory();
// Create hibernate bean manager
//
_beanManager = new HibernateBeanManager();
_beanManager.setEntityManagerFactory(entityManagerFactory);
}
/**
* Invoke adapter
*/
@Override
public Object invoke(Message message)
{
RemotingMessage remotingMessage = (RemotingMessage) message;
// Merge input arguments
//
List mergedParameters = (List) _beanManager.merge(remotingMessage.getParameters());
remotingMessage.setParameters(mergedParameters);
// Call Java adapter
//
Object result = super.invoke(message);
// Clone result
//
return _beanManager.clone(result);
}
//————————————————————————-
// Internal methods
//————————————————————————-
/**
* @return the Entity Manager Factory
*/
protected Object getEntityManagerFactory()
{
// JNDI Lookup for Entity Manager Factory
//
Context context = new InitialContext();
Object entityManagerFactory = context.lookup(“your_emf_jndi_name”);
if (entityManagerFactory == null)
{
throw new RuntimeException(“Unable to find EntityManagerFactory”);
}
return entityManagerFactory;
}
}
It is pretty straightforward: the only difficulty is to set the Hibernate session factory or the entityManagerFactory to the HibernateBeanManager. In our case, we use the JNDI name of the EntityManagerFactory (declared in the EJB3 “persistence.xml” file), but you can inject easily it in another way depending on your code.
The “invoke” method is the heart of the adapter: before server call, the input arguments are merged to Hibernate entities, and the result of the process call is cloned before going to the server side.
Stateful/Stateless mode
Previously, I mentioned that the persistence information hold by proxies and collections is stored in the ‘clone’ operation and reused in the ‘merge’ one.
Basically, Hibernate4GWT provides 2 ways of storing such information: on the server (the stateful mode) or on the pojo (stateless mode).
Stateful mode:
The proxy is stored in the HTTP session. As a consequence, your entity beans do not have any technical inheritance. Magic, isn’t it
?
To make it work, just edit the Hibernate Adapter below as follows :
- In the ‘init’ method, add the following line:
_beanManager.setPojoStore(new HttpSessionPojoStore());
- At the very beginning of the ‘invoke’ method, put the following line :
HttpSessionPojoStore.setHttpSession(FlexContext.getHttpRequest().getSession(true));
Stateless mode:
The entity beans store minimal persistence information, by inheriting from LazyPojo abstract class. No information is stored on server, which can be very helpful in clustered environments.
First, your entities must inherit from net.sf.hibernate4gwt.pojo.LazyPojo:
public class MyPojo extends LazyPojo
{…}
And here is the LazyPojo class in ActionScript (your value objects have to inherits from it, in a symmetric way to your entity hierarchy) :
package com.mypackage.client.vo
{
import com.adobe.cairngorm.vo.IValueObject;
import mx.collections.ArrayCollection;
[RemoteClass(alias="net.sf.hibernate4gwt.pojo.LazyPojo")]
public class LazyPojo implements IValueObject
{
/**
* The internal lazy properties collection
*/
private var _lazyProperties:ArrayCollection;
/**
* Constructor of Lazy Pojo abstract class.
*/
public function LazyPojo()
{
_lazyProperties = new ArrayCollection();
}
/**
* Getter for lazy properties collection
*/
public function get lazyProperties():ArrayCollection
{
return _lazyProperties;
}
/**
* Setter for lazy properties collection
*/
public function set lazyProperties(value:ArrayCollection):void
{
_lazyProperties = value;
}
}
}
The future
BlazeDS is not currently supported by Hibernate4GWT : it means that it as not been tested in different configurations (remoting, messaging, etc…), and there is no dedicated distribution or documentation for Flex applications.
Nevertheless, Hibernate4GWT is currently under heavy refactoring : the code has been split in different jars, and an official new distribution and documentation is scheduled for the end of Q2. It will include GWT new tutorial, some more functionality… and probably BlazeDS support 
Stay tuned !
Everybody seems to agree that GWT is great. However, one point that has long been considered a problem is its lack of compatibility with JDK 1.5 (though many people did not really understand that GWT actually still works fine in many cases).
Anyway, I just heard from the JavaPosse Boys that GWT beta has finally been released, and is now compatible with JDK 1.5! Rejoice! If you are starting a project with GWT, this is a great time to deploy the beta version (otherwise, you might want to wait for a more stable version).
I read a lot of GWT blogs, and one common mistake about Hibernate cohabitation is to believe that it is just a syntax issue. People thinks : “GWT only support Java 1.4 syntax, that’s why I cannot send my annotated Hibernate POJO to the client side”, and to conclude : “when GWT 1.5 will be out, Java5 syntax will be supported and I will be able to send my Hibernate beans to the presentation layer”.
This is wrong, absolutely wrong!
The reason is quite simple: Hibernate POJO are not real POJO. The persistence library adds a lot of needed information, such as session factory, by creating a dynamic proxy (with CGLIB or Javassist) around your instance. When you manipulate an Hibernate POJO, you do not do it with an instance of your class, but with a instrumented, derived one!
The second step is that GWT can only serialize (to Javascript) only a subset of the JRE (basically, the java.lang and the java.util packages). That means two things:
- Hibernate classes, such as session factory, are not defined if the GWT supported JRE, so they cannot be serialized
- Derived classes are not Javascript serializable, even if the base class belongs to the supported JRE. That means that even if java.util.Date is supported and serializable, java.sql.Timestamp is not. Furthermore, Hibernate defines its own implementation of the Java collections (PersistentList, PersistentSet and PersistentMap), of course not supported by GWT serialization process.
This is why Javascript serialization of your Hibernate instrumented beans will always fail!
I think that will be one of the big issue of the next GWT release, because only serialization will fail, not compilation. Indeed, your Domain classes are perfectly valid for GWT serialization, but not the associated Hibernate instances.
Hopefully, solutions do exist. You can use Dozer or Beanlib to clone your Domain class (replacing Hibernate collections with their pure Java counterpart) before sending them to the GWT client side, but take care of lazy loading (clone process cause property loading by calling the associated getter).
Or you can have a look to hibernate4gwt, that will do it seamlessly for you!
Génération de proxy coté serveur : un classique
La génération dynamique de proxy en Java est un mécanisme relativement nouveau, même si la notion même de proxy est standardisée depuis Java 1.4. L’émergence de CGLIB tout d’abord, puis de Javassist, a permet le développement de nombreuses librairies manipulant de simples POJO (donc sans héritage technique). En fait, l’astuce consiste pour ces librairies a modifier votre POJO, par héritage, en lui ajoutant dynamiquement les propriétés nécessaires au bon fonctionnement de la librairie:

C’est bien entendu le mécanisme utilisé par Hibernate par exemple pour instrumentaliser vos POJO et y ajouter les infos dont il a besoin.
Tentative d’évasion
Si astucieux soit-il, ce mécanisme est source de graves ennuis dès qu’il s’agit de quitter la JVM sur laquelle a été généré le proxy. Essayer par exemple d’envoyer un objet Hibernate par JMS : si le lecteur ne possède pas l’archive Hibernate dans son classpath, c’est l’erreur de désérialisation assurée…
Le problème se pose donc pour GWT, que l’on peut assimiler _ entre autre _ à une JVM Javascript. Imaginons une classe ‘Message’ que nous souhaitons instrumenter afin d’y ajouter des informations de débug, de sécurité, etc…
Pour cela, il faut étendre la classe Message en MessageProxy, grâce à Javassist par exemple :
ClassPool pool = ClassPool.getDefault();
CtClass proxyClass = pool.makeClass("MessageProxy");
proxyClass.setSuperclass(pool.get("Message"));
...
return proxyClass.toClass(getClassLoader());
Tant que la classe reste coté serveur, pas de souci. Par contre, toute tentative d’envoyer cette classe sur la lune… euh, coté client
se heurtera à une erreur de sérialisation :
com.google.gwt.user.client.rpc.SerializationException: Type ‘<Proxy>’ was not included in the set of types which can be serialized by this SerializationPolicy. For security purposes, this
type will not be serialized.
Serialization Policy : vos papiers…
En effet, en GWT 1.4, la politique de sérialisation a changé. Afin d’éviter un héritage technique hideux avec IsSerializable, l’option a été prise de lister à la compilation les classes sérialisables (contenues dans les fichiers gwt.rpc générés). D’où un conflit évident avec la génération dynamique de proxy…
De plus, le processus de sérialisation GWT est foncièrement statique. Même si la politique de sérialisation n’empêchait pas l’envoi de proxy, les données supplémentaires du Proxy ne seraient tout simplement pas envoyées sur le client, car la classe Javascript ne contient pas les champs correspondant à ces données.

Il faut donc générer une classe Javascript qui soit le pendant de notre proxy. Pour cela, GWT a une solution : les Generator. Ce mécanisme, relativement peu documenté, s’appuie sur le principe de deferred binding utilisé notamment par l’internationalisation de la librairie.
Pour faire court, la mise en place de generators nécessite 3 éléments :
- Le générateur de code proprement dit : il s’agit d’une classe héritant de Generator qui manipule et enrichit les métadonnées de classe :
...
ClassSourceFileComposerFactory composerFactory =
new ClassSourceFileComposerFactory("", "MessageProxy");
composerFactory.setSuperclass("Message");
SourceWriter sourceWriter =
composerFactory.createSourceWriter(context, printWriter)
...
sourceWriter.commit(logger);
- La déclaration du générateur dans le fichier XML de GWT (exemple) : elle associe le générateur à une ou plusieurs classes, voire à toutes celles assignables pour une classe abstraite ou interface donnée. Ce qui signifie entre autres que toutes vos classes « proxyfiables » doivent soit être explicitement et individuellement nommées dans le fichier de configuration XML de GWT, soit implémenter une interface vide qui sert de marqueur :
<generate-with class="net.sf.hibernate4gwt.rebind.GwtProxyGenerator">
<when-type-assignable class="net.sf.hibernate4gwt.proxy.IProxy" />
</generate-with>
- Un appel explicite à “GWT.create(Message.class)” dans le code de l’application cliente. Ce dernier point est particulièrement important car le compilateur GWT est particulièrement bien optimisé : sans appel à la méthode de création susdite, il en déduit que la génération du proxy est inutile et donc votre générateur n’est pas appelé. Un bon moyen de vérifier est de surveiller la console de lancement GWT : les classes instrumentalisées y apparaissent explicitement

Pour plus de détails sur la mise en place de générateurs, je vous renvoie directement au billet correspondant de l’excellent blog Timepedia ou au non moins l’excellent « GWT in action » qui traitent du sujet en profondeur.
Generator coté serveur : une mauvaise idée
J’avoue avoir essayé de récupérer le proxy généré par GWT dans mon code Java. Après tout, en hosted-mode, ma classe est bien instanciée en Java, non ?
En fait, les Generator GWT sont une technologie clairement orienté couche cliente. Un appel à GWT.create coté serveur soulève une automatiquement une exception, et hacker le hosted-mode pour récupérer la classe Java impliquerait que l’application embarque le moteur Tomcat embarqué utilisé dans ce mode. Quand je vous disais que c’était une mauvaise idée 
Faisons le point…
Donc pour envoyer un proxy serveur coté client en GWT, il faut donc :
- Créer le proxy coté serveur (avec Javassist par exemple)
- Créer ce même proxy coté client avec un Generator GWT
- Forcer la création des proxys coté client en appelant explicitement GWT.create
Bien entendu, il est fortement conseillé de factoriser la génération de proxy dans une même classe, la cohérence du proxy coté serveur et client étant cruciale pour le passage d’une JVM (classique) à l’autre (Javascript).
Quelques détails d’implémentation
Sur le papier, les étapes ci-dessus devraient suffire à faire créer des proxy dynamiques. En pratique, il reste un dernier petit détail à régler…
Vous vous souvenez de la SerializationPolicy dont j’ai parlé il y a quelques lignes ? Depuis la version 1.4, le compilateur génère une liste de classes autorisées à être envoyées par RPC (et donc sérialisées en Javascript), stockés dans un fichier ‘gwt.rpc’.
Première constatation : les proxys créés par notre Generator y apparaissent explicitement s’ils font partie de la signature des méthodes de notre RemoteService, ce qui est assez surprenant pour une technologie orientée cliente !
Deuxième constatation, plus désagréable celle-ci : l’implémentation de SerialializationPolicy génère sa « white-list » au premier appel. Pour cela, elle tente d’instancier toutes les classes contenues dans ses fichiers ‘gwt.rpc’ associé. Il faut donc créer les proxy avant cette vérification, sous peine de faire systématiquement échouer l’appel à cause d’une ClassNotFoundException sur celui-ci…
Là aussi, il existe plusieurs solutions :
- Générer au lancement coté serveur tous les proxys nécessaires. Dans le cas d’une interface marqueur, cela pose différents problèmes (cf. ici par exemple) assez délicats à gérer.
- Plus simplement, j’ai développé un ClassLoader qui wrappe le ClassLoader par défaut et qui génère mes proxy à la première demande de chargement.
public Class loadClass(String name) throws ClassNotFoundException
{
if (isProxy(name))
{
// Get source class name
//
String sourceClassName = getSourceClassName(name);
Class sourceClass = _wrappedClassLoader.loadClass(sourceClassName);
// Generate proxy
//
return generateProxyClass(sourceClass);
}
else
{
// Load class
//
return _wrappedClassLoader.loadClass(name);
}
}
Et ça marche…
J’ai fait plusieurs tests (en fait, j’utilise cette technique pour remplacer un héritage technique d’hibernate4gwt par une simple interface de marquage) et cela semble fonctionner dans le cas qui m’intéresse.
Par contre, il existe quelques points à améliorer avant de rendre un tel mécanisme réellement transparent, à cause notamment des appels explicites à GWT.create (je n’ai pas encore réussi à berner le compilateur GWT
) et de l’enrobage nécessaire du ClassLoader.
Avis aux amateurs !