简体   繁体   中英

Java, problems with custom classloader

i'm writing a custom class loader to load some of my classes (not all).

Class loader are very simple:

public Class loadClass(String className, boolean resolve) throws ClassNotFoundException {
    Class cls=findLoadedClass(className);
    if(cls!=null) {
        return cls;
    }
    // Search first for encrypted classes
    cls=decryptClass(className);
    if(cls==null) {
        // Then try with default system classloader
        cls=super.loadClass(className, resolve);
    }
    return cls;
}

And this is how i use it:

// In my Launcher class
public static void main(String[] args) {
    MyClassLoader loader=new MyClassLoader();
    try {
        final Class main=loader.loadClass("com.MyAppMain");
        Method toInvoke=main.getMethod("main", args.getClass());
        toInvoke.invoke(main, new Object[]{args});
    }
    catch(Exception ex) {
    }
}

All seem to be fine in my small test project, but when i use this loader in my big project(client-server application that use spring+hibernate and IoC) doesn't work. I have not a particolar exception in my classloader, but for example, new Socket instance throw a "java.net.ConnectException: Connection refused" without a real reason...

Other problems is my main form does not become visible... and other strange problems like this.

So, the question, are these problems caused by my classloader that load in different way a different kind of classes?


Edit 1

My project use spring, so i use @Autowired or sometimes

springApplicationContext.getBean(clazz);

to inject a bean.

The problem is spring cannot find my beans if these classes are encrypted(so they need to be loaded by my classloader). There is a workaround for this mistake? Thanks.


Edit 2

I have set my classloader in spring ClassPathXmlApplicationContext and now i notice that spring uses my classloader to load beans class, but despite this it throws an org.springframework.beans.factory.NoSuchBeanDefinitionException becouse it cannot find beans... what can i do? Thanks

I see two things that may be worth investigating:

  • The code makes the class loader parent-last. There is always a risk that this causes subtle class loading issues.
  • Maybe it is just the thread context class loader that is not set properly.

I'm not very good at class loaders, but from you code it's only possible to assume, that in case your class loader can't find a class, it will redirect to system class loader. It may work fine when you run application standalone, like in your sample, but if it's a web application that is run on application server it will fail.

Application servers usually create a big hierarchy of class loaders and has a separate class loader used to load your application classes. In this case, system class loader knows nothing about your Spring related classes and thus can't load them.

You must keep in mind, that same class may be loaded by several class loaders and if you try to compare same class from different class loaders it will fail.

In your case I would set parent class loader in MyClassLoader constructor. As a parent class loader you can use MyClassLoader.class.getClassLoader() I think.

public class MyClassLoader extends ClassLoader
{
    public MyClassLoader()
    {
       super(MyClassLoader.class.getClassLoader());
    }

    // other code
}

Hope this may help :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM