2016-06-22 50 views
2

Spring Boot 1.4.0M3에서 실행되는 내 응용 프로그램에서 이상한 문제가 발생합니다. 여기서는 공급자가 Redis 인 Spring 캐시 구현을 사용하고 있는데, 동일한 객체는 classCastException을받을 수 없습니다.java.lang.ClassCastException : DTOObject는 DTOObject로 캐스팅 될 수 없습니다.

내가 데이터베이스로 MongoDB를 사용하고를 주조하고 나는 느리게로드 객체 역할의 목록을 포함하고 역할은 내부적으로 권한

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

private boolean enabled = false; 

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

아래 내 역할 DTO는 다음과 같이처럼 객체가 포함되어 사용자 개체가 될 수

@Data 
@Document 
public class Role implements Serializable{ 
    private String roleName; 
    private String description; 
    @DBRef(lazy= true) 
    private List<Permission> permissions; 
} 

내 모든 MVC를로드하는 동안 모든 권한을 호출하는 중입니다. 반복적 인 작업이므로 결과를 캐싱하고 redis를 사용하여 역할 값을로드하는 동안 예외가 발생합니다.

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

이 오류를 극복하도록 도와주세요.

내 프로젝트에 source code를 부착하고 메뉴가 지금 클릭 나는 역할에서 다음 역할 메뉴를 응용 프로그램에 대한 해당 지역의 환경 로그인에 복제 및 권한 메뉴를 클릭하고 RoleController.java

의 91에서 오류가 발생 위의 오류가 발생합니다.

+1

클래스가 다른 클래스 로더에 의해 두 번로드되는 경우 jvm은 클래스가 부동 클래스로 간주됩니다. 나는 너에게 무슨 일이 일어나고 있는지 추측한다. – joshiste

+0

war 파일을 사용하는 것처럼 보입니다. 문제는 아마도 동일한 클래스의 여러 버전이로드 된 응용 프로그램 컨테이너에있는 것일 수 있습니다. – Magnus

+0

나는 ide에서 실행 중이며 한 버전의 권한 클래스 만 볼 수 있습니다. – 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

두 번째 링크는 예제가 있습니다. 실제로 응용 프로그램 클래스 로더의 캐시 라이브러리를 _include_해야합니다. 문제를 업데이트하겠습니다. –

+0

META-INF/spring-devtools.properties에서 restart.exclude.cache = jedis * .jar 등록 정보를 추가했지만 여전히 동일한 문제에 직면했습니다. 내가 생각하기에 직렬화를 수행하는 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의 재시작 기능을 거의 사용하지 않았기 때문에 실제로 이것은 나에게 좋은 접근 방법이었습니다.