0

NoClassDefFoundError when loading an external class

asked 2010-06-15 04:51:02 +0800

efm gravatar image efm
183 1

updated 2010-06-15 05:00:33 +0800

Hello,
I have a ZUL which uses a class "com.exponentum.expf.controller.Main". Inside that class, I put a routine to load another
class in external jar, as below:

File file = new File(Executions.getCurrent().getDesktop().getWebApp().getRealPath(Executions.getCurrent().toAbsoluteURI("/plugins/MeasurementUnit.jar", false)).toString());
URL url = new URL("jar:file://" + file.getAbsolutePath() + "!/");
URLClassLoader ucl = new URLClassLoader(new URL[] { url });
Class<?> c = ucl.loadClass("com.exponentum.expf.plugin.MeasurementUnit.MeasurementUnitController");

in that external jar, I have one class MeasurementUnitController with content like this one:

package com.exponentum.expf.plugin.MeasurementUnit;

import org.zkoss.zul.Window;

public class MeasurementUnitController extends Window {
	public void onCreate() {
	}
	public void initPlugin() {
		System.out.println("This is Plugin");
	}	
}

and here is the error when running the main class:

java.lang.NoClassDefFoundError: org/zkoss/zul/Window
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
	at com.exponentum.expf.controller.Main.onCreate(Main.java:18)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.zkoss.zk.ui.impl.EventProcessor.process0(EventProcessor.java:208)
	at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:140)
	at org.zkoss.zk.ui.impl.UiEngineImpl.processEvent(UiEngineImpl.java:1485)
	at org.zkoss.zk.ui.impl.UiEngineImpl.process(UiEngineImpl.java:1269)
	at org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage0(UiEngineImpl.java:425)
	at org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage(UiEngineImpl.java:294)
	at org.zkoss.zk.ui.http.DHtmlLayoutServlet.process(DHtmlLayoutServlet.java:238)
	at org.zkoss.zk.ui.http.DHtmlLayoutServlet.doGet(DHtmlLayoutServlet.java:159)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.ClassNotFoundException: org.zkoss.zul.Window
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
	... 38 more
15.06.2010 17:00:06 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet zkLoader threw exception
java.lang.ClassNotFoundException: org.zkoss.zul.Window
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
	at com.exponentum.expf.controller.Main.onCreate(Main.java:18)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.zkoss.zk.ui.impl.EventProcessor.process0(EventProcessor.java:208)
	at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:140)
	at org.zkoss.zk.ui.impl.UiEngineImpl.processEvent(UiEngineImpl.java:1485)
	at org.zkoss.zk.ui.impl.UiEngineImpl.process(UiEngineImpl.java:1269)
	at org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage0(UiEngineImpl.java:425)
	at org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage(UiEngineImpl.java:294)
	at org.zkoss.zk.ui.http.DHtmlLayoutServlet.process(DHtmlLayoutServlet.java:238)
	at org.zkoss.zk.ui.http.DHtmlLayoutServlet.doGet(DHtmlLayoutServlet.java:159)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:619)

The needed library (zul.jar) is already imported to build path for the main class.

What could possibly wrong here?

delete flag offensive retag edit

5 Replies

Sort by » oldest newest

answered 2010-06-15 05:24:21 +0800

Arsen gravatar image Arsen
384 5

Your UrlClass loader should wrapping standat context ClassLoader (something like URLClassLoader = new URLClassLoader(defaultClassLoader)), and mechanism of loading class should be as followed:
1. Ask defaultClassLoader to load class (it checks if class is already loaded, and if not, then looks for class definition in standart repository).
2. If default class cloader can't load class, only then youк classloader should try to load the class.

link publish delete flag offensive edit

answered 2010-06-15 05:30:53 +0800

Arsen gravatar image Arsen
384 5

I've had these such task with external jar's, and after some investigations and tryings I've decided that it is bad idea to use External class loaders. It works only if you can define your classloader as default for entire application before it starts (I could not find how to do this in Glassfish). Otherwise you'll have problems with multi-threading and resources in external jars.
The best way, from my point of view, is to put this external jars into WEB-INF/lib or <application server>/lib, so they can be loaded by default classloader.

link publish delete flag offensive edit

answered 2010-06-15 05:46:23 +0800

efm gravatar image efm
183 1

hi Arsen,
so if I want to create a plugin-based application, I have to put that plugin in WEB-INF/lib and then restart the application (from application server)?
btw, this is not happening in common java project (non Web Application/ZK)

link publish delete flag offensive edit

answered 2010-06-15 06:10:27 +0800

Arsen gravatar image Arsen
384 5

You can create plugin-based application as you want, but you should application server, which allows you to use your own ClassLoader for web application. You should not create new ClassLoader inside application code. Custom classloader should be defined somewhere in application server's descriptors.
Glassfish does not allow this, may be your application server does - look for documentation.
This are results of my investigation, may be more experinced friends correct me :-)

link publish delete flag offensive edit

answered 2010-06-15 06:27:42 +0800

SimonPai gravatar image SimonPai
1696 1

Hi efm,

I second Arsen's comment. A container of web applications uses its own ClassLoaders, so when you create a new ClassLoader in a thread in your web app, it's on the top of some ClassLoader used by the container, and the side effects are uncertain. As far as I know, as JEE Web spec does not define how custom ClassLoader should be handled, it really depends on the implementation of your container.

Regards,
Simon

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2010-06-15 04:51:02 +0800

Seen: 223 times

Last updated: Jun 15 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More