Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Tricky class loading error

 
Kasper Pedersen
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys
Hope someone can help me out on this one. I spent 2 days experimenting and Googling with absolutely no positive results.


Background:
I have an webapplication that i use for a lot of different customers, containing a framework to handle customized plugins/codeunits. In order to make upgrades easy i wish to deploy the plugins outside the webapplication, so all customers can share the common webapplication and make updates easy (basically downloading new war files and leaving the plugins on the server).

Setup:
Got a webapplication, with an abstract class "CodeunitFormevents" (in a jar inside WEB-INF/lib).
I have deployed another jar file in the webservers "common/lib". This contains a class "TestPlugin" that extends the "CodeunitFormevents".
The TestPlugin is instaciated from the "CodeunitFormeventsFactory" within the webapplication.

Problem:
When creating a new instance i get an java.lang.NoClassDefFoundError (stacktrace below)
Note that the problem is with the superclass (CodeunitFormevents) - NOT the class (TestPlugin) itself !

Non-issues:
As long as the plugin jar is deployed inside "WEB-INF/lib" everything is fine.
Explicitly setting serialVersionUID had no effect.

Stacktrace:
java.lang.NoClassDefFoundError: dk/p2e/blanket/codeunit/CodeunitFormevents
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1350)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1209)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at dk.p2e.blanket.codeunit.CodeunitFormeventsFactory.getCodeunitFormevents(CodeunitFormeventsFactory.java:21)
 
Paul Clapham
Sheriff
Posts: 21416
33
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Classes in "common/lib" don't have access to classes in any of the web applications. And when you load a class, that causes its superclass to be loaded first. In this case the superclass is in one of the web applications, so it can't be loaded.

It doesn't make sense (to me, anyway) for a plugin which is to be common to all web applications to have a superclass which isn't also common to all web applications.
 
Kasper Pedersen
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:Classes in "common/lib" don't have access to classes in any of the web applications. And when you load a class, that causes its superclass to be loaded first. In this case the superclass is in one of the web applications, so it can't be loaded.

It doesn't make sense (to me, anyway) for a plugin which is to be common to all web applications to have a superclass which isn't also common to all web applications.


I see your point - thank you for clarifying.

Would it be possible to somehow deploy the codeunit classes outside the webapplication folder. I have looked into dynamic jar loading, but i am reluctant to use this approach (gets very installation specific). Finally i had considered storing the .jar in DB blobs, and writing the files til WEB-INF/lib at application boot time - i just fear that i have to degrade performance / cause classloader leaks by activating WatchedRessource.
 
David O'Meara
Rancher
Posts: 13459
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You could look at using a URLClassLoader so that they get the code from you and you can control which version each client gets.
You would still need to manage it from each client so that they periodically (or explicitly) check for updates and get a new URLClassLoader if the remote package changes.
Can't say I'm a fan of this though.
 
Kasper Pedersen
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The URL loader is actually fine - only annoyance is that i need to keep track of both the .jar name and the class name ... some naming convention comes to mind.

Thanks for help both of you
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic