-
FEATURED COMPONENTS
First time here? Check out the FAQ!
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?
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.
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.
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)
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 :-)
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
Asked: 2010-06-15 04:51:02 +0800
Seen: 223 times
Last updated: Jun 15 '10