David G. David G. - 1 month ago 57
Java Question

How to get classloader visibility in Websphere Liberty Profile between jar in EAR and shared library

I'm trying to get some legacy code working in a Websphere Liberty Profile (latest version 16).

This code comes in form of an architectural set of libraries, which I have set up as shared libraries in WLP, plus applications, which come as EARs

I'm getting a problem where some code in on of the jar in one of the libraries tries to instantiate a class which is inside the EAR (in a jar in the lib folder).

I'm getting this stacktrace:

Caused by: java.lang.ClassNotFoundException: com.isb.holamu.fnegocio.ln.AAL_FNegocioFactory <-- This class (1) is inside a .jar inside the EAR
at com.ibm.ws.classloading.internal.AppClassLoader.findClassCommonLibraryClassLoaders(AppClassLoader.java:491)
at com.ibm.ws.classloading.internal.AppClassLoader.findClass(AppClassLoader.java:274)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.ibm.ws.classloading.internal.AppClassLoader.findOrDelegateLoadClass(AppClassLoader.java:469)
at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:441)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.isb.bs.bl.base.MetaFacadeFactory.createFactoryInstance(MetaFacadeFactory.java:74) <-- This class (2) is in the shared library in WLP.


And these are the relevant bits from the server.xml:

<!-- Server shared library -->

<library id="architecture" >
<fileset dir="${server.config.dir}/lib/jars" includes="*.jar" scanInterval="5s"/> <-- (2) is here

</library>

<enterpriseApplication autoStart="true" id="sample" location="sample.ear" name="sample"> <-- (1) is here
<classloader commonLibraryRef="architecture" delegation="parentFirst"/>
</enterpriseApplication>


It seems as if the EAR classes can access the shared library classloader and its classes, but the shared library classes can't find the ones inside the EAR.

Can anyone give any clue on how to get this working?

Thanks!

Answer

This will not work because common libraries use their own class loaders, not those of the apps that reference them.

To make this work, change your commonLibraryRef to a privateLibraryRef. This will effectively add the library content to the app's class path.

--joe