• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Tricky class loading error

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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)
 
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
Rancher
Posts: 13459
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
 
reply
    Bookmark Topic Watch Topic
  • New Topic