I've learned how to dynamically load a ".class" file into my program, but if I run it on a tomcat id doesn't work. Here is the code:
package testPackage;
public class ModuleEngine {
public static void main(String pth, String name) {
ModuleLoader loader = new ModuleLoader(pth, ClassLoader.getSystemClassLoader());
try {
Class clazz = loader.loadClass(name);
Protocol execute = (Protocol)clazz.newInstance();
execute.run();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
public class ModuleLoader extends ClassLoader {
private String pathtobin;
public ModuleLoader(String pathtobin, ClassLoader parent) {
super(parent);
this.pathtobin = pathtobin;
}
@Override
public Class findClass(String className) throws ClassNotFoundException {
try {
byte b[]= fetchClassFromFS(pathtobin + className + ".class");
return defineClass(null, b, 0, b.length);
} catch (FileNotFoundException ex) {
return super.findClass(className);
} catch (IOException ex) {
return super.findClass(className);
}
}
}
I run main method in ModuleEngine class with path to subclass of the class Protocol. This subclass is placed in different package. So when I try to define it (defineClass) it tries to load the superclass (Protocol) but fails to do that. Here is the stack trace:
java.lang.ClassNotFoundException: testPackage.Protocol
at java.lang.ClassLoader.findClass(Unknown Source)
at testPackage.ModuleLoader.findClass(ModuleLoader.java:30)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at testPackage.ModuleLoader.findClass(ModuleLoader.java:28)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at testPackage.ModuleEngine.main(ModuleEngine.java:13)
at testPackage.HtmlPage.doGet(HtmlPage.java:27)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Instead of ClassLoader.getSystemClassLoader() try using ModuleEngine.class.getClassLoader (). This will return class loader that knows about classes sitting near ModuleEngine class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With