2

カスタム クラス ローダーを作成しましたが、それを「登録」する方法がわかりません。

public static void main( String[] args ) throws Exception {
   File            jar   = new File( "Simple.jar" );
   FileInputStream fis   = new FileInputStream( jar );
   byte[]          bytes = new byte[(int)jar.length()];
   fis.read( bytes );
   fis.close();
   MemoryClassLoader cl = new MemoryClassLoader();
   cl.defineClasses( bytes );

   // 1: Following lines works well
   cl.findClass ( "help.Simple" )
      .getMethod( "main", new Class[]{ String[].class })
         .invoke( null, (Object)args );

   // 1: it works well
   cl.findClass ( "help.Simple" )
      .getMethod( "main", new Class[]{ String[].class })
         .invoke( null, (Object)args );

   // 2: it works well too
   Class.forName( "help.Simple", true, cl )
      .getMethod( "main", new Class[]{ String[].class })
         .invoke( null, (Object)args );

   // 3: it doesn't work
   Class.forName( "help.Simple" )
      .getMethod( "main", new Class[]{ String[].class })
         .invoke( null, (Object)args );
}

実際の MemoryClassloader はより複雑で、ここでは詳しく説明しません。

このプログラムは次を出力します。

Hello, world!
Hello, world!
Exception in thread "main" java.lang.ClassNotFoundException: help.Simple
   at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
   at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
   at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
   at java.lang.Class.forName0(Native Method)
   at java.lang.Class.forName(Class.java:186)
   at loader.MemoryClassLoader.main(MemoryClassLoader.java:76)

「こんにちは、世界!」というセリフ。によって印刷されhelp.Simple.main( String[] args )ます。クラス help.Simple は、クラス ローダーによって正しく読み込まれます。しかし、それを呼び出す 3 番目の方法はClass.forName()機能しません。カスタム クラス ローダーでロードしたクラスを、デフォルトのシステム クラス ローダーによってロードされた「標準」クラスのリストに追加する理由と方法を教えてください。

4

1 に答える 1

3

Class.forName はデフォルトで、現在のクラス (メイン メソッドを含むクラス) をロードしたクラスローダーを使用します。この場合に機能させる唯一の方法は、別のクラスローダーを受け入れるオーバーロードされたメソッドを使用することだと思います。

クラスローダーによってロードされる他のクラス内で使用すると、正常に動作するはずです。

Class.forName( "help.Simple", true, cl )
于 2013-02-15T10:02:20.667 に答える