Payara icon indicating copy to clipboard operation
Payara copied to clipboard

Bug Report: ClassNotFoundException when using the provided Yasson library /FISH-5656

Open CarlosMOGoncalves opened this issue 3 years ago • 1 comments

Description


Hello!

Whenever I need to use a class from the Yasson library provided by the server it fails because it cannot find it in the classloader.

This happens only in the Server version and works fine in Payara Micro (i.e. in Micro it will find the class in its classloader).

Expected Outcome

Correctly load whichever class from the provided Yasson library I need to develop application code.

Current Outcome

When some application code needs a Yasson specific class it will simply blow with a ClassNotFoundException.

java.lang.ClassNotFoundException: org.eclipse.yasson.internal.model.customization.Customization
	at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1787)
	at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1628)
	at pt.test.jsonb.JsonbConverter.init(JsonbConverter.java:26)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.jboss.weld.interceptor.reader.SimpleInterceptorInvocation$SimpleMethodInvocation.invoke(SimpleInterceptorInvocation.java:76)
	at org.jboss.weld.interceptor.proxy.WeldInvocationContextImpl.invokeNext(WeldInvocationContextImpl.java:94)
	at org.jboss.weld.interceptor.proxy.WeldInvocationContextImpl.proceed(WeldInvocationContextImpl.java:124)
	at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeLifecycleInterception(InterceptorMethodHandler.java:78)
	at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeInterception(InterceptorMethodHandler.java:74)
	at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.invoke(InterceptorMethodHandler.java:48)
	at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:84)
	at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:61)
	at pt.test.jsonb.JsonbConverter$Proxy$_$$_WeldSubclass.lifecycle_mixin_$$_postConstruct(Unknown Source)
	at org.jboss.weld.interceptor.util.InterceptionUtils.executePostConstruct(InterceptionUtils.java:44)

	(... ommitted the rest)

Steps to reproduce

  1. In a pom.xml declare a provided dependency to yasson
  2. Somewhere in the application flow invoke a yasson-specific class (e.g. org.eclipse.yasson.internal.model.customization.Customization)
  3. Exception should be thrown

I have two sample projects that can be used to test this out payara-test-ear and payara-test-war.

payara-test-ear is an .ear packaged application with some modules (I use this to test some potential bugs in Payara). It has a module called webservices that contains a @RequestScoped bean called JsonbConverter which initializes a JsonbConfig object. The yasson library is requested in pom.xml as provided. There is a UserResource that has some JAX-RS endpoints. When invoking the GET, it will construct the bean and, when trying to build a special Serializer called PairSerializer it will end in the above exception.

payara-test-war is a .war application that is packaged as an uber jar with Payara Micro. It has the exact same configuration as above, although the resource class is different. The yasson library is requested in pom.xml as provided. The resource is called EventResource and has a JAX-RS GET endpoint that when invoked with the exact same code, will find the right class, instantiate the JsonbConverter bean and do what it has to do. No failure is expected.

Now, I did some light digging and it seems that when deployed on a Payara Server, it fails because the classloader cannot find the yasson jar that was requested as provided. On Micro that is not the case, it will find it in one of the classloaders. I noticed that the classloader hierarchy (delegates I think) is a lot different from the Server to Micro, which is expected, I suppose.

If the library is requested as compile, it will find it and work just fine, because it is included in the lib folder of the respective package.

I also tried to simply deploy a .war into the server to check whether it had something to do with the packaging (maybe some bug in the EarClassLoader or similar) but it also fails that way. This can also be tested by removing a .war from the .ear plugin and deploying it directly to a running server.

I didn't pursue it further because I am really not familiar with the Payara code and I think this might be a good head start for you.

Hope this is useful

Environment

  • Distribution: Server Full - Community Edition version 5.2020.6 to 5.2021.4
  • JDK Version: 1.8.0_282 - AdoptOpenJDK
  • Operating System: Windows 10

CarlosMOGoncalves avatar Jul 15 '21 16:07 CarlosMOGoncalves

Hi @CarlosMOGoncalves,

I am able to reproduce this issue. I have raised an internal issue with JIRA FISH-5656. Thanks. It may take a while to fix the issue. You are free to submit a PR to fix this issue if you feel confident to do so.

shub8968 avatar Jul 28 '21 16:07 shub8968