2

このサイトと他の多くの投稿からの情報を組み合わせて、クラスを含むディレクトリを (実行時に) クラスパスに動的に追加し、そのディレクトリ内にクラスをロードする次のコードを取得しました。

私は OSGi バンドルを使用しており、Eclipse から「Eclipse アプリケーション」(実行構成の一種) を実行しています。

これは私が使用しているコードです:

ケース 1: (両方のケースは異なるものですが、同じことをしようとしました。)

File file = new File("/Users/alek/fastFIX/myJPass/"); 
URL url = file.toURI().toURL(); 
URL[] urls = new URL[]{url}; 
ClassLoader cl = new URLClassLoader(urls); 
Class  cls = cl.loadClass("GuiLauncher");    //the file GuiLauncher.class is in the /Users/alek/fastFIX/myJPass/ directory
Class[] argTypes = new Class[] { String[].class };
Method main = cls.getDeclaredMethod("main", argTypes); //trying to run the main class
main.invoke(null, (Object) args);

エラーは発生せず、何も起こりません。ロードされたクラスが他の(すでにロードされている)クラスと対話する必要があるため、次のことも試しました。

ケース 2:

ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {  new File("/Users/alek/fastFIX/myJPass/").toURL() }, currentThreadClassLoader);
Thread.currentThread().setContextClassLoader(urlClassLoader);

次に、次のようにロードします。

 Class<?> c = Class.forName("GuiLauncher");

またはこのように:

Class<?> c = Thread.currentThread().getContextClassLoader().loadClass("GuiLauncher");

次のようにメイン関数を呼び出してみてください。

Class[] argTypes = new Class[] { String[].class };
Method main = cls.getDeclaredMethod("main", argTypes); //trying to run the main class
main.invoke(null, (Object) args);

ここでも何も起こりません。

何が起こっているのか手がかりはありますか?ここで関連するすべての投稿を読みましたが、運が悪い他の多くの場所を読みました。

4

2 に答える 2

1

OSGI フレームワークでは、次のように OSGI クラスローダーを親として追加する必要があります: ... ClassLoader cl = new URLClassLoader(new URL[]{file.toURI().toURL()}, this.getClass() .getClassLoader()); ...

于 2014-04-04T14:27:22.260 に答える
0

ケース 1 では、GuiLauncher クラスが既にクラスパスにあると思われるため、デフォルトのクラスローダーによってロードされる可能性があります。動的クラスローダーをセットアップするClass.forName() 前に実行して、利用可能なクラスがないことを確認してください。Eclipse を使用している場合は、クラスが Eclipse クラスパスに含まれていないことに注意する必要があります。これは通常発生することです。一度コンパイルしてから、.java.classファイルを別の場所に移動して、Eclipse からそれらを隠す必要があるかもしれません!

ケース 2:

Class.forName("GuiLauncher");

これはシステムクラスローダーを使用するため、期待どおりには機能しません。これは失敗するはずなので、上記の疑いがあります。動的クラスローダーを指定するこのメソッドの別のバージョンを使用する必要があります。

Class.forName("GuiLauncher", true, urlClassLoader)

次のコードは私にとってはうまくいきます。

import java.net.*;
import java.lang.reflect.*;
import java.io.File;

public class Main{

public static void main(String[] args)
{
    try{
      Class  cls = Class.forName("Plugin");
    }
    catch(Exception e){
      System.out.println("Nothing there!");
    }

    try{
      File file = new File("plugin"); 
      ClassLoader cl = new URLClassLoader(new URL[]{file.toURI().toURL()}); 
      Class  cls = Class.forName("Plugin", true, cl);
      Method main = cls.getDeclaredMethod("main", new Class[] { String[].class });
      main.invoke(null, (Object) args);
    }
    catch(Exception e){
      e.printStackTrace();
    }
  }
}

クラスはサブフォルダーにPluginコンパイルされるため、最初の.pluginMainClass.forName()

public class Plugin{
  public static void main(String[] args)
  {
    System.out.println("Plugin was invoked!");
  }
}

そして出力します:

Nothing there! 
Plugin was invoked!
于 2012-10-03T18:19:15.293 に答える