Problème

Lorsque vous utilisez des bibliothèques tierces dans un regroupement OSGi, vous obtenez des problèmes de chargement de classe tels que les suivants :

Le mypackage.FooBar d'usine demandé est introuvable. Classloader =java.net.URLClassLoader@6aa8d01c

Note: cette erreur est juste un exemple de message d'erreur. Le problème réside dans le fait que les classes chargées par des bibliothèques tierces sont introuvables, même si la classe correspondante est définitivement importée.

Exemple réel.

Apache Axis2 pourrait lancer la trace d'appels (stacktrace) suivante, sans raison spécifique :

18.02.2010 17:04:30.153 *INFO* [10.43.97.19 [1266509048609] POST /path/to/servlet HTTP/1.1] org.apache.axis2.transport.http.HTTPSender Unable to sendViaPost to url[xy] org.apache.axis2.AxisFault: Requested factory com.ctc.wstx.stax.WstxOutputFactory cannot be located. Classloader =java.net.URLClassLoader@6aa8d01c at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:96) at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499) ...

Solution

Vous ne pouvez pas définir la façon dont les bibliothèques tierces chargent leurs classes. Dans la plupart des cas, cela fonctionne, si la bibliothèque tierce utilise le chargeur de classe normal du lot. Mais parfois une bibliothèque, comme Apache Axis2, peut tenter de charger une classe similaire à ce qui suit :
Thread.currentThread().getContextClassLoader().loadClass("mypackage.FooBar");
Par défaut, le chargeur de classes de contexte Thread ne connaît pas OSGi et ne voit donc aucune des classes importées dans le lot. C’est pourquoi le chargement de la classe échoue.

Dans votre code, avant que le code tiers ne soit exécuté, vous pouvez indiquer au thread en cours d'utiliser le chargeur de classe à partir du lot. Procédez ainsi temporairement pour le code tiers qui ne charge pas certaines classes :

ClassLoader tccl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); try { // execute 3rd party code } finally { Thread.currentThread().setContextClassLoader(tccl); }

 

S’applique à

CQ5.x, AEM6.x.

Ce produit est distribué sous licence Creative Commons Attribution - Pas d’utilisation commerciale - Partage à l’identique 3.0 non transposé  Les publications Twitter™ et Facebook ne sont pas couvertes par les dispositions Creative Commons.

Mentions légales   |   Politique de confidentialité en ligne