Problema

Cuando se utilizan bibliotecas de terceros en un paquete OSGi, resulta en problemas de carga de clases como los siguientes:

La factoría mypackage.FooBar solicitada no se puede localizar. Classloader =java.net.URLClassLoader@6aa8d01c

Nota: Este error es solo un ejemplo de mensaje de error. El problema es que no se encuentran las clases cargadas por bibliotecas de terceros, aunque la clase correspondiente sea definitivamente importada.

Ejemplo de la vida real

Apache Axis2 podría iniciar la siguiente traza de llamada sin ninguna razón:

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: com.ctc.wstx.stax.WstxOutputFactory solicitada no puede localizarse. 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) ...

Solución

La forma en que las bibliotecas de terceros cargan sus clases está fuera de su control. En la mayoría de los casos está bien si la biblioteca de terceros utiliza el cargador de clases normal del paquete. No obstante, a veces, una biblioteca, como Apache Axis2, podría intentar cargar una clase como la siguiente:
Thread.currentThread().getContextClassLoader().loadClass("mypackage.FooBar");
De forma predeterminada, el gestor de clases de contexto de subprocesos no es consciente de OSGi y, por lo tanto, no ve ninguna de las clases importadas en el paquete. Por ello, la carga de la clase da error.

En su código, antes de que se ejecute el código de terceros, puede decirle al subproceso actual que use el cargador de clases del paquete. Haga esto temporalmente para el código de terceros que no carga algunas clases:

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

 

Se aplica a

CQ5.x, AEM 6.x

Esta obra está autorizada con arreglo a la licencia de Reconocimiento-NoComercial-CompartirIgual 3.0 Unported de Creative Commons.  Los términos de Creative Commons no cubren las publicaciones en Twitter™ y Facebook.

Avisos legales   |   Política de privacidad en línea