OpenLiberty / open-liberty

Open Liberty is a highly composable, fast to start, dynamic application server runtime environment
https://openliberty.io
Eclipse Public License 2.0
1.15k stars 590 forks source link

Enterprise application classloader using resource adapter not working anymore. #23620

Open tschurins opened 1 year ago

tschurins commented 1 year ago

We have a resource adapter defined like this in the configuration:

<resourceAdapter id="kafkara" location="/rar/kafka-jms-rar.rar">
    <classloader commonLibraryRef="libext"/>
    <properties.kafkara
            brokerVersion="${kafka.image.version}"/>
</resourceAdapter>

Then, we have an enterprise application that has a dependency on it:

<enterpriseApplication id="kafka-samples-ear" location="/ears/kafka-samples-ear.ear" name="kafka-samples-ear">
    <!-- In the sample, we also use the kafka client directly. Hence we need the same class loader. -->
    <classloader classProviderRef="kafkara"/>
</enterpriseApplication>

I'm using OpenLiberty 19.0.0.9 and all is fine. The application can use the classes from the resource adapter. Here is what is in the configuration (https://localhost:9443/ibm/api/config):

{
  "configElementName": "enterpriseApplication",
  "uid": "kafka-samples-ear",
  "id": "kafka-samples-ear",
  "autoStart": true,
  "classloader": [
     {
        "configElementName": "classloader",
        "uid": "enterpriseApplication[kafka-samples-ear]/classloader[default-0]",
        "apiTypeVisibility": "spec,ibm-api,api,stable",
        "classProviderRef": [
           {
              "configElementName": "resourceAdapter",
              "uid": "kafkara",
              "id": "kafkara",
              "location": "/rar/kafka-jms-rar.rar"
           }
        ],
        "delegation": "parentFirst"
     }
  ],
  "location": "/ears/kafka-samples-ear.ear",
  "name": "kafka-samples-ear"
},

Now, as this version is quite old, I want to migrate to a newer version (22.0.0.4), but then, it does not work any more. The application has issue finding the classes from the adapter:

[12/7/22 9:26:17:552 GMT] 00000038 id=         com.ibm.ws.webcontainer.servlet.ServletWrapper               E init SRVE0271E: Uncaught init() exception created by servlet [kafka-sample-control-servlet] in application [kafka-samples-ear]: java.lang.NoClassDefFoundError: org.apache.kafka.clients.producer.Callback
    at com.company.jca.kafka.sample.servlet.SampleControlServlet.init(SampleControlServlet.java:43)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:299)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadOnStartupCheck(ServletWrapper.java:1401)
    at com.ibm.ws.webcontainer.webapp.WebApp.doLoadOnStartupActions(WebApp.java:1211)
    at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationFinally(WebApp.java:1179)
    at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:1077)
    at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:6685)
    at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApp(DynamicVirtualHost.java:472)
    at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApplication(DynamicVirtualHost.java:467)
    at com.ibm.ws.webcontainer.osgi.WebContainer.startWebApplication(WebContainer.java:1188)
    at com.ibm.ws.webcontainer.osgi.WebContainer.access$100(WebContainer.java:111)
    at com.ibm.ws.webcontainer.osgi.WebContainer$3.run(WebContainer.java:985)
    at com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:245)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:823)
Caused by: java.lang.ClassNotFoundException: org.apache.kafka.clients.producer.Callback
    at com.ibm.ws.classloading.internal.AppClassLoader.findClassCommonLibraryClassLoaders(AppClassLoader.java:748)
    at com.ibm.ws.classloading.internal.AppClassLoader.findClass(AppClassLoader.java:319)
    at com.ibm.ws.classloading.internal.AppClassLoader.findOrDelegateLoadClass(AppClassLoader.java:720)
    at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:592)
    at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:559)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:879)
    ... 19 more

Here is what is in the configuration (https://localhost:9443/ibm/api/config):

   {
      "configElementName": "enterpriseApplication",
      "uid": "kafka-samples-ear",
      "id": "kafka-samples-ear",
      "autoStart": true,
      "classloader": {
         "configElementName": "classloader",
         "uid": "enterpriseApplication[kafka-samples-ear]/classloader[default-0]",
         "apiTypeVisibility": "spec,ibm-api,api,stable",
         "classProviderRef": [
         ],
         "delegation": "parentFirst"
      },
      "location": "/ears/kafka-samples-ear.ear",
      "name": "kafka-samples-ear"
   },
brenthdaniel commented 1 year ago

Are there any errors in the messages.log file? I'm wondering specifically about any feature conflicts that prevent JCA from loading.

tschurins commented 1 year ago

No other error in the logs. There is even a line about the resource adapter being installed successfully.

tschurins commented 1 year ago

I've also tested a few other versions:

So I guess that there has been a change between 20.0.0.3 and 20.0.0.9 that breaks the classloader link between the application and the resource adapter.

rowland66 commented 9 months ago

Has any progress been made on this bug? Are there workarounds available? Makes using RAR's rather challenging?

tschurins commented 9 months ago

I've seen no progress. The only workaround that I'm aware of is to define a feature with the library(ies) which should be common to the resource-adapter and the application: the feature allows to share its classes on the default classpath, and will be available for both application and rar.