Web application hosted in OpenLiberty cannot find classes through system class loader

1.3k Views Asked by At

I have hosted a web application in open liberty and I am trying to class load some third party java classes which are in a jar. I added the folder as a library which contain the jar file and added that library as a class loader. but i am getting a class not found exception when i try to load it.

Also when I use URLClassLoader it works perfectly fine. But i want to change the URLClassLoader to System ClassLoader

My server.xml contains below lines.

 <application location="${application.name}"
               type="war"
               id="${application.name}"
               name="${application.name}" context-root="<URL>">
    <classloader apiTypeVisibility="spec, ibm-api, api, stable, third-party" commonLibraryRef="Lib"/>
  </application>

  <library id="Lib" apiTypeVisibility="spec, ibm-api, api, stable, third-party">
    <folder dir="${wlp.install.dir}/../custom-java/" />
  </library>

Any help regarding this highly appreciated.

2

There are 2 best solutions below

4
On

If you have a jar file, you need to use <file> or <fileset> instead of <folder>.

For a single jar:

<library id="Lib" apiTypeVisibility="spec, ibm-api, api, stable, third-party">
  <file name="${wlp.install.dir}/../custom-java/myjar.jar" />
</library>

For a directory with multiple jars:

<library id="Lib" apiTypeVisibility="spec, ibm-api, api, stable, third-party">
  <fileset dir="${wlp.install.dir}/../custom-java/" includes="*.jar" scanInterval="5s" />
</library>

I believe <folder> is only used when you have a folder of files you want to load with Class.getResource(), or if you have a directory structure of .class files which aren't in a jar.

For more details, see the Knowledge Center

Update: When you've added a library to your application like this, you should be able to access the classes in the library just like you access classes in your application.

For example, these should work:

  • new MyLibraryObject()
  • Class.forName("com.example.MyLibraryObject")
  • Thread.currentThread().getContextClassLoader().loadClass("com.example.MyLibraryObject")

However, using the system classloader specifically still won't work.

In OpenLiberty, the system classloader loads a minimal set of classes. Liberty internals are loaded using OSGi which has its own set of classloaders and application classes are loaded by a special application classloader which can load the application classes, API classes and shared libraries, but doesn't have access to load any liberty internal classes.

0
On

After lot of fiddling around came up with the answer. The problem was how I defined the class loader. I changed my class loader to use the Application class loader (this is what mentioned in the Azquelt reply) instead of the the system class loader.

also just adding a library path was enough. no need to specify in the class loader in the server.xml

thank you for your input @Azquelt