4

Spring と Jetty を使用して単純な Web アプリケーションを作成し、DataNucleus と DB4O を使用して Hello World JDO テストを作成しています。

クラスを問題なく永続化できますが、クラスのクエリを実行すると、 が取得され、ClassCastExceptionにキャストできませa.b.c.MyClassa.b.c.MyClass

作成したオリジナルオブジェクトのクラスローダを調べると[WebAppClassLoader@1592226291]、当然SpringsのWebAppクラスローダです。

同じサーブレット メソッドで永続化操作とクエリ操作の両方を実行しています。単純なクエリを使用して DB からオブジェクトを再読み込みすると、DB から abcMyClass オブジェクトのセットが返されますが、クラスローダーは[sun.misc.Launcher$AppClassLoader@5acac268]. .

ここの DataNucleus ドキュメントに従ってください http://www.datanucleus.org/extensions/classloader_resolver.html

...JDO2 クラスローディング メカニズムは 3 つのクラス ローダーを使用し
ます * PersistenceManagerFactory を作成するときに、クラス ローダーを指定できます。指定されている場合は、これが最初に使用されます
。 * 2 番目に試行されるクラス ローダーは、現在のスレッドのクラス ローダーです。
* 3 番目に試すクラス ローダーは、PMF コンテキストのクラス ローダーです。

文書化された最初の 2 つのオプションについて説明WebAppClassLoaderし、サーブレットで次のデバッグ手順を実行して、クラスローダーがサーブレットにあることを確認しました。

Thread.currentThread().getContextClassLoader().toString()
((JDOPersistenceManagerFactory)pm.getPersistenceManagerFactory()).getPrimaryClassLoader().toString()

どちらも[WebAppClassLoader@1592226291]クラスローダーとして生成されます。

ここでどこが間違っているのかわかりません。

4

1 に答える 1

1

答えとしての私の以前のコメント:

この例外は、クラス ローダーの問題であることを示しています。オブジェクトのクラスローダーとキャストに使用しているクラスを比較してください。

ClassLoader loaderOfObject = theObject.getClass().getClassLoader();
ClassLoader loaderOfLocalClass = MyClass.getClassLoader();
// have to be the same.
assert loaderOfObject.equals(loaderOfLocalClass);

ところで: db4o が間違ったクラスローダーを使用している場合。class-loader を明示的に設定することで、これを変更できます。

    EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration();
    JdkReflector reflector = new JdkReflector(Thread.currentThread().getContextClassLoader());
    configuration.common().reflectWith(reflector);
    ObjectContainer container = Db4oEmbedded.openFile(configuration, "database.db4o");

単一のクラス・ローダーでは不十分な場合: クラス・ローダーの代わりに db4o-interface JdkLoader のインスタンスを渡すこともできます。そこでは、任意のクラス検索メソッドを実装できます。たとえば、複数のクラスローダーを検索します。

于 2010-10-25T16:40:28.880 に答える