現在、私が取り組んでいる小さなプロジェクトで問題が発生しています。このプロジェクトでは、構成文字列からクラスを動的に作成し、それを JVM にロードしようとしています。
「通常の」環境(単体テスト)でこれを行うと、すべて正常に動作します。しかし、OSGI 環境 (Apache Karaf) でクラスを作成しようとすると、"Illegal class name "Ljava/lang/String;" in class ..." というメッセージの ClassFormatError が表示されます。
簡単な調査の結果、Java/lang のクラスがシステム クラス ローダーによってロードされていない場合に、この問題が発生することがわかりましたが、Java、特に OSGi でのクラスのロードに関しては、私は専門家以外のすべてです。
defineClass
メソッドにアクセスする方法は、この問題にとって興味深い可能性があると思うので、次のとおりです。
PROTECTION_DOMAIN = (ProtectionDomain) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return RestEndpoint.class.getProtectionDomain();
}
});
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
Class loader = Class.forName("java.lang.ClassLoader");
DEFINE_CLASS = loader.getDeclaredMethod("defineClass",
new Class[]{ String.class,
byte[].class,
Integer.TYPE,
Integer.TYPE,
ProtectionDomain.class });
DEFINE_CLASS.setAccessible(true);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return null;
}
});
最後の (うまくいけば役に立つ) 情報は、OSGi バンドルでプロジェクトを実行するときに defineClass メソッドを呼び出す ClassLoader です。これは org.apache.felix.framework.BundleWiringImpl のインスタンスです。
誰かがここで私を助けてくれたら最高です!
こんにちは、パスカル
編集:プロジェクトで定型コードを避け、プログラムの一貫性を高めたいため、実行時にクラスを定義する必要があります。
より正確に言うと、私のプロジェクトは RESTful WebService になります。データの保存とプロセスの同期化に複数のテクノロジ (mongoDB、MySQL、activeMQ など) を使用しているため、Apache camel を使用してすべての異なるテクノロジを処理したいと考えています。問題は、REST で Camel を Java アプローチとうまく統合する可能性がないことです (HTTP リクエストへのメソッドとクラスのマッピング全体はアノテーションで行われます)。したがって、私にとって唯一の可能性は、要求のパラメーターを Camel の交換ヘッダーに配置し、それらをルートに送信するメソッドを作成することでした。これを回避するために、ルート定義から実行時にこれらのクラスを定義することで、このプロセスを自動化したいと考えました。