1

私のアプリケーションは、GUI に Standard Widget Toolkit (SWT) を使用しています。私の問題は、32 ビット SWT ライブラリが 64 ビット JVM で動作しないことです。しかし、私は、ソフトウェアを入手するときに人々に正しいアーキテクチャを選択させたくありません。そのため、32 ビットと 64 ビットの両方のライブラリをバンドルし、実行時にアーキテクチャを自動検出したいと考えています。次のように、JVMの正しいアーキテクチャを取得できることがわかりました。

if (System.getProperty("os.arch").contains("64")) {
    // ...
}

あとは、jar をロードするだけです。しかし問題は、私が見つけたすべての例では、クラスを使用する前に手動でクラスをロードする必要があることです。

Class.forName("MyClass", false, myClassLoader);

私の質問は、事前にクラスをロードする必要がないように、クラスローダーを「登録」することは可能ですか?


更新: の独自の子クラスを作成URLClassLoaderし、コマンド ライン引数を使用してデフォルトのクラス ローダーとして設定しました-Djava.system.class.loader。しかし、私はこのエラーが発生します:

Error occurred during initialization of VM
java.lang.Error: java.lang.NoSuchMethodException: com.program.LibraryLoader.<init>(java.lang.ClassLoader)
    at java.lang.ClassLoader.initSystemClassLoader(Unknown Source)
    at java.lang.ClassLoader.getSystemClassLoader(Unknown Source)

LibraryLoader.<init>コンストラクターを参照していると思います...しかし、そこにあります( public LibraryLoader(URI[] urls))。


更新 2: JVM が実行されるようになりました。このコンストラクターを追加して、機能させました。

public LibraryLoader(ClassLoader classLoader) {
    super(new URL[0], classLoader);
}

しかし、addPath()( file:lib/jars/swt.jar) で jar を追加した後は、NoClassDefFoundError. はい、ファイルが存在することを再確認しました。

4

2 に答える 2

1

「java.system.class.loader」プロパティ (ClassLoader#getSystemClassLoader を参照) を使用して、カスタム クラス ローダーの挿入を試みることができます。ただし、OSGi を使用して、フレームワークに複雑なことを任せることをお勧めします。

于 2011-04-26T20:30:21.683 に答える
0

カスタム ClassLoader のコンストラクターの一部として、目的の jar ファイルを指す URL を指定して、適切な情報を指定して definePackage を呼び出します。

この例は、swing からクラスをインスタンス化しようとすると、カスタム クラス ローダーが呼び出されることを示しています。これは、クラス ローダーをそのパッケージのローダーとして定義したためです。

import java.net.URL;

public class junk extends ClassLoader {

  byte[] dummy = new byte[0];

  public static void main(String[] args) throws Exception {
    new junk();

    new javax.swing.JPanel();

  }

  public junk() throws Exception {
    definePackage("javax.swing","","","","","","",new URL("file://junk.class"));
  }

  public Class<?> findClass(String s) throws java.lang.ClassNotFoundException{
    Class<?> retVal = super.findClass(s);

    System.out.println("delegated responsibility for "+s+" to superclass");

    return retVal;
  }

  public Package getPackage(String s) {
    Package retVal = super.getPackage(s);

    System.out.println("delegated responsibility for "+s+" to superclass");

    return retVal;
  }

}

結果:

javax.swing の責任をスーパークラスに委任

于 2011-04-26T20:52:41.193 に答える