| 
| [plugin classloader] IllegalArgument: class not visible [message #147999] | Wed, 10 March 2004 03:16 |  | 
| Eclipse User  |  |  |  |  | Hi newsgroup, 
 I have a serious problem creating a library plugins. I can not
 encapsulate
 the com.mockobjects libraries. Here is why:
 
 Considering you have added a library-plugin providing the mock libraries.
 A mock is created by:
 
 Mock mock=new Mock(MyInterface.class);
 
 Where Mock is the class com.mockobjects.dynamic.Mock and is provided
 by the library plugin.
 
 Creating a new plugin (lets call it 'test')depending on the library you will
 get the following behaviour:
 It can be compiled, It can be run as a normal application. But if this
 little code
 runs as a plugin, an Exception is thrown informing about a visiblility
 problem.
 The exception reads like:
 java.lang.IllegalArgumentException: interface pack.age.MyInterface is not
 visible from class loader.
 
 The error is caused (exception is thrown) by the following java code:
 
 Class java.lang.reflect.Proxy.getProxyClass(
 ClassLoader classLoader, Class [] interfaces) {
 [...]
 Class interfaceClass = null;
 try {
 interfaceClass =
 Class.forName(interfaces[i].getName(), false, loader);
 } catch (ClassNotFoundException e) {
 }
 if (interfaceClass != interfaces[i]) {  //this fails
 throw new IllegalArgumentException(   //thrown here
 interfaces[i] + " is not visible from class loader");
 }
 [...]
 }
 
 So Class.forName("pack.age.MyInterface",false,loader) is still successfull
 using the provided class loader but the Class instance returned by
 the class loader by looking for pack.age.MyInterface is a diffrent one.
 
 The class loader is provided by the Mock class by calling:
 Mock(Class clazz (which is MyInterface.class)) {
 Class proxy=Proxy.getProxyClass(getClass().getClassLoader(),
 new Class[] {clazz});
 }
 
 So you can see that the class loader which had loaded the Mock class
 is used. The fun is, this class loader finds MyInterface but it is creating
 a diffrent Class object instead of providing the class object still exists.
 
 I dont know why it is doing so, so I need help.
 
 Since the library is not an owner of the MyInterface.class (it's the test
 plugin), the classloader of the Mock class should ask the class loader
 following the PP|S order (enabled OSGi but normal classloader
 behaviour also fails). But it seams that I dont understand how loading
 a class which is owned by a plugin depending on a given library plugin
 is loaded by the classloader of the plugin (which is surly used in this
 case).
 
 Obviously we need to redirect the new Mock(...).getClass().getClassLoader()
 to returning the ClassLoader instance of the test plugin rather then
 returning
 the ClassLoader of the library plugin. To be able to do this, we have to
 ensure that calling new Mock(...).getClass() returns a class created by
 the test plugin class loader. Therefore we simply extend the Mock using
 class MyMock extends Mock {
 MyMock(Class clazz) {
 super(clazz);
 }
 }
 
 Since MyMock belongs to the test plugin, the class is loaded by the
 test plugin. Testing this, well it works! But still it isn't funny! It feels
 like
 a hack. So I would like if someone knows, how I can avoid this
 mix up and correct class loading.
 
 
 Thanks,
 
 Martin (Kersten)
 |  |  |  | 
Powered by 
FUDForum. Page generated in 0.58757 seconds