>>>>> "Allan" == Allan Stanley <[EMAIL PROTECTED]> writes:

  Allan> Excellent point Phil...

         Well thank you. Sadly its not!
 

  Allan> so Class.forName() is too heavy.  And
  Allan> the link phase could load (and initialize) other classes as
  Allan> well.  Gack!  We now resume our regularly scheduled
  Allan> program...

  >> There is one main advantage doing this which is that some classes
  >> have large static initialiser's (I have one for instance which
  >> takes about 1 minute to load!), and the Class.forName lookup
  >> would I think force this loading. By the nature of things this
  >> could happen accidentally if you're type had the same class name
  >> as one in another package.



     A brief examination shows a way around this. Take for instance
the following code

public class ClassLoading 
{

  public ClassLoading() throws Throwable
  {
    Class.forName( "phtfitdev.FeatureStore" );
    Class cl = Class.forName( "phtfitdev.FeatureStore", false, 
this.getClass().getClassLoader() );
    System.out.println ( cl);
  }
  

  
  public static void main( String args[] ) throws Throwable
  {
    ClassLoading a = new ClassLoading();
    System.exit( 0 );
  }
  
  
} // ClassLoading



   in this case the class phtfitdev.FeatureStore is one of my classes
which  takes a while to load. It also puts up a JProgressBar from a
static init block. Trust me I know when its loaded.


       This behaves prettty much as expected. The nifty bit is however
in the second class for name. This produces a valid Class object, but
the false means that it doesnt initilise. If I comment the first
Class.forName out then I still get a valid class object, but no class
loading.  If I modify the string to point to a non-class a
ClassNotFound is thrown so it works as expected.

          There are only two (minor) problems, which are that firstly
you have to specify the class loader. If you specify Null in 1.2 only
the bootstrapclass loader is used (so my code will load the
FeatureStore class and then give a ClassNotFoundException if the
second class for name specifies null. 

[ Diversion:- Incidentally this shows that a class in the JVM is not
the same thing as a java type. Im working on this because I think it
means I can load a new class def into a still running jvm without
removing the old. This would have implications for the JDE. For
instance the "implement interface" wizard autocodes the methods of a
given interface as the interface was when the wizard was first
used. Which is a pain if you change the interface definition. It
should be possible to work around this without restarting the
beanshell.]

        the result of this means you have to do two class name look
ups, one against the boot classe, one against the user classes.

        So the full code for doing this would be something like

        //check along non system class path
        Class.forName( "testpackage.testclass", false,
        this.getClass().getClassLoader() );
        
        //Check along the system class path
        Class.forName( "testpackage.testclass", false,
        null );
        
        Both have to throw a ClassNotFound to be sure that the
class doesnt exist. I think that this isnt necessary in 1.1 because
this.getClass().getClassLoader() will return null for any class
specified on the command line.


        The second problem is much smaller. You need a "this"
reference, so you cant do it in a static. You need an object. This is
not difficult, but a pain. 


          Phil


          

Reply via email to