Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically load a class on tomcat?

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)
like image 303
Kirill Kosolapov Avatar asked Dec 03 '25 18:12

Kirill Kosolapov


1 Answers

Instead of ClassLoader.getSystemClassLoader() try using ModuleEngine.class.getClassLoader (). This will return class loader that knows about classes sitting near ModuleEngine class.

like image 150
Mikhail Vladimirov Avatar answered Dec 06 '25 06:12

Mikhail Vladimirov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!