Re: [tcljava-user] Using a custom classloader as default class loader in TclBlend
Brought to you by:
mdejong
From: Johann T. <jo...@da...> - 2007-08-22 20:07:48
|
> Shibu Cyriac wrote: >> Hi All, >> I need to use a custom classloader as the default classloader in my >> TclBlend application. > > I don't think there is an easy way to do that... > You don't really create a class loader and then tell the system to > use it instead of the default one. > (snip) If you've got your own thread to work with, telling the system you're going to use a new class loader is fairly simple: public class MyThread extends Thread { public MyThread () { this.setContextClassLoader ( new MyClassLoader () ); } } I don't use TclBlend, but this works well for a Jacl environment. Mind you mixing and matching ClassLoaders is very dangerous... For example, a String object that is loaded by the system class loader is NOT of the same class as a String loaded by your own class loader. This concept may seem obvious, but debugging can be quite painful! So as Mo suggested, setting the class loader before anything has really happened in your application is necessary if you share objects between threads, or if you're in a single-threaded environment. For example, rather than executing your app with "java x.y.z.MyClass", add a main () method to your MyClassLoader and execute the app with "java MyClassLoader". The main () method of MyClassLoader.java might look something like: import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; ... String my_class_name = "x.y.z.MyClass"; String [] my_args = new String [ 0 ]; try { // Create our own class loader. MyClassLoader my_class_loader = new MyClassLoader ( ClassLoader.getSystemClassLoader () ); // Load in some class "x.y.z.MyClass", so that we can // execute its main () method. Class cl = my_class_loader.loadClass ( my_class_name ); // Find the main () method of MyClass. A bit sloppy... Method [] methods = cl.getMethods (); Method mmain = null; for ( int m = 0; m < methods.length; m ++ ) { if ( methods [ m ].getName ().equals ( "main" ) ) { mmain = methods [ m ]; break; } } if ( mmain == null ) { throw new NoSuchMethodException ( "main" ); } // Start up the application: MyClass.main ( args ). mmain.invoke ( null, (Object) my_args ); } catch ( ClassNotFoundException e ) { e.printStackTrace (); } catch ( NoSuchMethodException e ) { e.printStackTrace (); } catch ( IllegalAccessException e ) { e.printStackTrace (); } catch ( InvocationTargetException e ) { e.printStackTrace (); } This forces all classes that will be used by the application to be loaded through the MyClassLoader, and might save you some time trying to figure out why a String is not a String (a subject better left to philosophers anyway). Hope this helps, Johann Tienhaara |