Penny
Penny

Reputation: 31

Dynamically loaded Class cannot access Applet loaded Class

My StartApplet is small to keep startup quick.

It then downloads various classes in various jars using (URLClassLoader)getSystemClassLoader().

The problem I am experiencing is that there are several interfaces defined in the StartApplet which are passed to the dynamically downloaded classes using method invoke. I always get class not defined.

It seems the system class loader does not contain any StartApplet loaded classes including the interfaces.

So, I try loading in the interfaces into the systemClassLoader using a downloaded jar but I still get class not defined and I guess this is because the same class has been loaded in twice using difference class loaders and therefore is seen as two difference classes.

I tried loading the downloaded jars using the classloader of one of the interfaces(StartApplet) but there were errors.

I tried forgetting about the system class loader and instead creating a new URLClassLoader using the classloader of the interfaces(StartApplet) as the parant class loader but again errors occurred.

I have tried loading the dynamic jars into Thread.currentThread().getContextClassLoader() but again errors occurred.

My question...

Is there a way to dynamically load classes in jars using (URLClassLoader)getSystemClassLoader() and allow them to see/access and use the classes that have already been loaded by the instantiating applet??

some code example would be really nice.

Many Thanks.

The crux is the system class loader doesnt reference the applet class loader. The applet cannot start with any external jars so whatever classes it passes have to be loaded in with the applet. I just need the dynamically loaded classes in the systemclassloader to be able to use the classes loaded with the applet. please help.

ps. here are some snipets...

private void addPath(String _path)
 {
 try{
  File f=new File(_path);
  if(!f.exists())return;
  if(!f.isDirectory())return;
  Method method=SYSTEM_CLASS_LOADER_CLASS.getDeclaredMethod("addURL",parameters);
  method.setAccessible(true);
  method.invoke(SYSTEM_CLASS_LOADER,new Object[]{f.toURI().toURL()});
  }catch(Throwable _t){
  handle(_t);
  disconnect();}
 }
private void addLibrary(String _name)
 {
 try{
  Method method=SYSTEM_CLASS_LOADER_CLASS.getDeclaredMethod("addURL",parameters);
  method.setAccessible(true);
  method.invoke(SYSTEM_CLASS_LOADER,new Object[]{ClassLoader.getSystemResource(_name)});
  }catch(Throwable _t){handle(_t);}
 }


SYSTEM_CLASS_LOADER=(URLClassLoader)ClassLoader.getSystemClassLoader(); // DOESNT WORK
SYSTEM_CLASS_LOADER=(URLClassLoader)MyInterface.class.getClassLoader(); // DOESNT WORK
SYSTEM_CLASS_LOADER=(URLClassLoader)Thread.currentThread().getContextClassLoader(); // DOESNT WORK

private void callWithInterface(MyInterface _myI)
 {
 Class<?> myClass=Class.forName("dynamic.MyClass",true,SYSTEM_CLASS_LOADER);
 Constructor<?> myConstructor=myClass.getConstructor();
 Object myInstance=myConstructor.newInstance();
 Method m=myClass.getMethod("MyTest",new Class<?>[]{MyInterface.class});
 String s=(String)m.invoke(myInstance,new Object[]{_myI});
 }

last line causes...

Thread=Thread[Thread-17,4,http://MyDomain/-threadGroup]
 java.lang.ClassNotFoundException: MyInterface
  java.net.URLClassLoader$1.run(-1)
   java.net.URLClassLoader$1.run(-1)
    java.security.AccessController.doPrivileged(-2)
     java.net.URLClassLoader.findClass(-1)
      java.lang.ClassLoader.loadClass(-1)
       sun.misc.Launcher$AppClassLoader.loadClass(-1)
        java.lang.ClassLoader.loadClass(-1)
         java.lang.Class.forName0(-2)
          java.lang.Class.forName(-1)
           StartApplet.run(23759)
            java.lang.Thread.run(-1)

Upvotes: 1

Views: 446

Answers (1)

Penny
Penny

Reputation: 31

I have figured it out..

The problem I had was caused by a jar name conflict causing the required classes to fail at loading. Once I realised this and corrected the problem I successfully enabled the dynamically loaded classes to access the applet loaded classes by loading the dynamically loaded classes using the applet class loader instead of the system class loader.

I modified my code using the following lines and other adjustments to suit...

MyDynamicClassLoader=new URLClassLoader(new URL[0],MyAppletLoadedInterface.class.getClassLoader());

method.invoke(MyDynamicClassLoader,new Object[]{MyDynamicClassLoader.getResource(DynamicJarName)});

MyDynamicClassLoader now holds references to all applet loaded classes and dynamically loaded classes with the ability to reference each other. For some reason the system class loader does not hold the applet loaded classes.

Regards Penny

Upvotes: 1

Related Questions