0

I am trying to force some of the classes to be loaded using my custom class loader, the problem is after the loading the calling class still doesn't know about the class definition and tries to load it again, of course after that we have two different definitions of the class and assigning one to the other results in class cast exception. Any pointers or ideas how this can be fixed?

This is the calling class:

 CustomClassLoader loader = new CustomClassLoader(this.getPackageCodePath());
 Class<?> midletClass = loader.loadClass(className);
 midletClass.getMethod("InitEngine", Class.forName("android.app.Activity")).invoke(null, this);
 ms_MIDlet = (MIDlet)midletClass.newInstance();//ClassCastException

And this is the class loader itself

public class CustomClassLoader extends PathClassLoader
{
    public CustomClassLoader(String path)
    {
         super(path, getSystemClassLoader());//we set the parent to be the system class loader so the loading gets done in this class
    }

    @Override
    public InputStream getResourceAsStream(String resName)
    {
        //...do some resource loading here
    }
}

1 Answer 1

1

The calling class is running in some ClassLoader A. This classloader knows where to find and load MIDlet.class. Otherwise line 4 would produce a ClassNotFoundException for the cast.

You also use an instance of CustomClassLoader to load the Midlet.class.

On line 4 this blows up because you are casting the Midlet instance loaded by CustomClassLoader to a Midlet instances loaded by the ClassLoader A.

One solution is to make the CustomClassLoader logic delegate to ClassLoader A before loading a class itself. Something along the lines of first delegating a loadClass call to parentLoader.loadClass or getResourceAsStream to parentLoader.getResourceAsStream. If those calls fail then you can do your custom resource lookup.

This approach will make sure that all Midlet.class'es are actually loaded by the same classloader. You can check the delegation example at Java ClassLoader delegation model?

Sign up to request clarification or add additional context in comments.

4 Comments

When I pass the Activity class to the midget class everything works even though they have different class loaders. The exception is thrown on the next line when I try to cast the midletClass to the local MIDlet. What I am doing now is save the returned object in an Object variable and make sure all the calls are done using the midletClass instance.
You do all invocations on the ms_MIDlet via reflection because you are unable to cast?
Yes, it is not a huge problem as in reality ms_MIDlet is not used in the activity so much, I just use the activity to bootstrap the midget execution and then just forward any state changes to it when they happen (pause, resume, quit etc.)
Ok. You might see other problems in the future that stem from the fact of them being from different classloaders, for example IllegalAccessException. I'll mention an approach in my answer on how to remedy your situation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.