2016-06-22 6 views
2

Spring Boot 1.4.0M3で動作する私のアプリケーションで奇妙な問題に直面しています。Springのキャッシュ実装を使用しています。ここで、プロバイダはRedisです。classCastExceptionは同じオブジェクト私は、データベースとしてのMongoDBを使用していると私はロールのリストが含まれているユーザオブジェクトを持つjava.lang.ClassCastException:DTOObjectをDTOObjectにキャストすることができません

をキャストすることレイジーと役割ロードされたオブジェクトは、内部権限が私の役割DTOは

以下の通りである

@Document 
@Data 
public class User implements Serializable{ 
private String passwordResetToken; 

private boolean enabled = false; 

@DBRef(lazy= true) 
private List<Role> roleList; 
} 

の下のようなオブジェクトが含まれ

私はすべてのロールをロードしている間に私のすべてのロールをロードしています。これは反復的な操作ですから結果をキャッシュし、redisを使用し、

raised java.lang.ClassCastException: com.learning.securedapp.domain.Permission cannot be cast to com.learning.securedapp.domain.Permission 

このエラーを解決するにはどうすればよいですか。

私は私のプロジェクトにsource codeを装着していると私は、アプリケーションにローカル環境のログインで複製およびアクセス許可メニューとその後、役割のメニューをクリックし、[役割]メニューINにRoleController.java

の線91でエラーが発生する今をクリック上記のエラーが表示されます。

+1

クラスが異なるクラスローダーによって2回ロードされた場合、jvmはそれらが等しくないとみなします。私はあなたに何が起こっているのかと思います。 – joshiste

+0

warファイルを使用しているようですので、アプリケーションクラスに複数のバージョンの同じクラスがロードされている可能性があります。 – Magnus

+0

私はideから実行していますが、私は1つのバージョンのパーミッションクラスしか見ていません。 – rajadilipkolli

答えて

3

DevToolsをキャッシュに使用する場合は、this limitationに注意する必要があります。

オブジェクトをキャッシュにシリアライズすると、アプリケーションクラスローダはC1になります。次に、コード/設定を変更すると、devtoolsは自動的にコンテキストを再起動し、新しいクラスローダー(C2)を作成します。そのキャッシュメソッドをヒットすると、キャッシュ抽象化はキャッシュ内のエントリを見つけ、それをストアから逆シリアル化します。キャッシュライブラリがコンテキストクラスローダーを考慮しない場合、そのオブジェクトには間違ったクラスローダーが添付されます(これは奇妙な例外A cannot be cast to Aを説明しています)。

TL;DRキャッシュライブラリがコンテキストクラスローダーを使用していない場合、devtoolsでクラスをシリアライズしないでください。またはあなたのキャッシュライブラリin the application classloaderを置く:

restart.include.yourcache=/my-cache-lib-[\\w-]+\.jar 
+0

@nicollに感謝します。アプリケーションクラスローダーでキャッシュライブラリを除外する方法のサンプルを教えてください。 – rajadilipkolli

+0

2番目のリンクには例があります。実際には、アプリケーションクラスローダーのキャッシュライブラリを_include_する必要があります。問題を更新します。 –

+0

META-INF/spring-devtools.propertiesのrestart.exclude.cache = jedis * .jarプロパティを追加しましたが、私はまだ同じ問題に直面しています。私はキャッシュ・プロバイダーとしてredisを使用しているので、jedisを追加しました – rajadilipkolli

1

は、私が実際に運と提案された解決策(およびその多くのバリエーション)を試してみました。例えば、これは問題の発生を停止していない:

restart.include.cache=/spring-data-redis-.*.jar 

は、私が使用した特定のバージョンをコールアウトするには、上記を更新し、それはまだ動作しませんでした。

私がやったのは、spring-boot-devtoolsを私のプロジェクトから除外したことです。私はMavenを使用しているので、注釈はこれでした:

<dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-devtools</artifactId> 
     <version>[1.5.9,)</version> 
     <scope>provided</scope> 
    </dependency> 

これは、1.5.9以上のバージョンがロードされないようにします。上記を含めた後、すべてが期待通りに機能しました。私はこれがすべてにとって理想的な解決策ではないことを知っていますが、devtoolsの再起動機能をほとんど使いませんでしたので、これは実際は私にとっては良いアプローチでした。

関連する問題