2

I want to create some plugin example for android, so I have 3 projects for it:

ExternalLibInterface - contains IExternalLib, and builds to externallibinterface.jar file

  package com.example.externallibinterface;    
  public interface IExternalLib {
    public String someMethod( String param );
  }

ExternalLib - contains externallibinterface.jar and SomeClass implements IExternalLib, builds to externallib.apk

   package com.example.externallib;
   import com.example.externallibinterface.IExternalLib;
   public class SomeClass implements IExternalLib {
       public String someMethod(String arg0) {
           return arg0;
       }
   }

SomeApp - contains externallibinterface.jar and class for activity - application where I load external apk and class from it.

   import com.example.externallibinterface.IExternalLib;    
   import dalvik.system.PathClassLoader;

   public class MainActivity extends Activity {

       @Override
       public void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);

           String apkToLoad = null;

           String externalPackagePath = "com.example.externallib";
           String externalClassPath = "com.example.externallib.SomeClass";

           try {
               apkToLoad = getPackageManager()
                    .getApplicationInfo( externalPackagePath, MODE_PRIVATE ).sourceDir;
           } catch ( PackageManager.NameNotFoundException e ) {
               e.printStackTrace();
           }

           PathClassLoader pathClassLoader = 
                   new PathClassLoader( apkToLoad, 
                ClassLoader.getSystemClassLoader() );

           try {
               Class<?> c = Class.forName( externalClassPath, true, pathClassLoader );

               Object someClassInstance = c.newInstance();
                       //exception ClassCastException here
               IExternalLib i = (IExternalLib) someClassInstance;
               i.someMethod( "some string" );               
           } catch (ClassNotFoundException e1) {            
            e1.printStackTrace();
           } catch (InstantiationException e) {
            e.printStackTrace();
           } catch (IllegalAccessException e) {         
            e.printStackTrace();
           } catch ( ClassCastException e ) {
            e.printStackTrace();
           }
       }
   }

But when I cast Object someClassInstance to IExternalLib I get ClassCastException. Why? IExternalLib is defined in 3rd place (in externallibinterface.jar).

Marko
  • 20,385
  • 13
  • 48
  • 64
rdbmsa
  • 296
  • 3
  • 14

2 Answers2

2

Try the following:

Class<? extends IExternalLib> l_clazz; // our expected class
Class<?> clazz = Class.forName("com.example.externallib.SomeClass"); // our unknown class

// check if our unknown class can be cast to our expected class
if ((l_clazz = clazz.asSubclass(IExternalLib.class)) != null) {
    IExternalLib i = l_clazz.newInstance();
    i.someMethod( "some string" );
}
epoch
  • 16,396
  • 4
  • 43
  • 71
  • `if ((l_clazz = clazz.asSubclass(IExternalLib.class)) != null)` gives ClassCastException – rdbmsa Sep 12 '12 at 08:05
  • then your class cannot be cast to `IExternalLib`, can you print out the classname before that line? `clazz.getName()`, there must be some other problem – epoch Sep 12 '12 at 08:07
  • `clazz.getName()` returns _com.example.externallib.SomeClass_. So, I load right class, but can't cast his object to interface, which implemented in this class – rdbmsa Sep 12 '12 at 08:15
  • I understand the problem, just trying to help debug. are you sure there are not multiple `com.example.externallib.SomeClass`s on the classpath, try it with a new class in your main project and see if it still occurs – epoch Sep 12 '12 at 08:37
1

It could happen when different class loaders are loading the class. Make sure to build the whole setup at once so that only one class loader is responsible for loading the classes. It happens frequently when you are just re-deploying a particular .war file onto a existing system. Please see this for more insight can't cast to implemented interface

Community
  • 1
  • 1
m3th0d
  • 56
  • 3