2009-10-23 2 views
8

,GroovyShell을 실행 한 후 메타 클래스 변경 사항을 실행 취소하려면 어떻게해야합니까? 나는 방법 foo는()를 추가하는 문자열 메타 클래스를 수정하는 그루비 스크립트를 실행하면 나는 그 후 새로운 쉘을 작성하고 실행할 때 예를 들어

GroovyShell shell1 = new GroovyShell(); 
shell1.evaluate("String.metaClass.foo = {-> delegate.toUpperCase()}"); 

, 변경이 여전히

있습니다
GroovyShell shell2 = new GroovyShell(); 
Object result = shell2.evaluate("'a'.foo()"); 

GroovyShell 실행 후 모든 메타 클래스 변경 사항을 실행 취소 할 수 있습니까? 나는

shell1.getClassLoader().clearCache(); 

shell1.resetLoadedClasses(); 

을 시도하지만 변화하지 않았다.

+0

일부 클래스 로더를 망쳐 놓고이 작업을 수행 할 수 있습니까? – cretzel

답변

11

당신은 문자열의 메타 클래스에 모든 변경 사항을 되돌릴 수

GroovySystem.metaClassRegistry.removeMetaClass(String.class); 

를 사용할 수 있습니다.

또는 특정 String 인스턴스의 메타 클래스 만 변경할 수 있으므로 모든 String 인스턴스가 영향을받지는 않습니다.

+1

감사합니다. 하지만 메타 클래스 변경 사항이 무엇인지 알지 못한다면 어떨까요? 다른 사용자가 Groovy 스크립트를 실행하는 Groovy 웹 콘솔과 같은 응용 프로그램을 생각해보십시오. 나는이 사용자들이 간섭하지 않기를 바란다. – cretzel

+0

아래에서 내 대답을 참조하십시오. 어떤 메타 클래스가 변경되었는지 모르는 문제를 해결합니다. –

0

나는이 질문이 다소 오래되었다는 것을 알고 있지만, 정확히 동일한 문제를 검색 할 때 Google에서의 첫 번째 결과입니다.

내가 선택한 솔루션은 새로운 클래스 로더 (plexus-classworlds 사용)에 groovy를 넣는 것이므로 스크립트가 끝나면 클래스 로더가 삭제되고 따라서 메타 클래스의 변경 사항도 삭제됩니다.

+0

코드 예제가 있습니까? –

+0

@JohnMercier가 도움을받지 못했습니다. –

2

MetaClassRegistryCleaner도 사용할 수 있습니다. 당신은 그들이 이전에 있었던 상태로 메타 클래스 변경을 재설정 할 때

일부 메타 클래스 변경을 수행하기 전에, 당신은

MetaClassRegistryCleaner registryCleaner = MetaClassRegistryCleaner.createAndRegister() 
GroovySystem.metaClassRegistry.addMetaClassRegistryChangeEventListener(registryCleaner) 

을 할 수 있습니다.

당신은

registryCleaner.clean() 
GroovySystem.metaClassRegistry.removeMetaClassRegistryChangeEventListener(registryCleaner) 

당신이 기간 중에 모든 메타 클래스 변경을 재설정 할 수 있습니다이 방법을 수행 할 수 있습니다.

관련 문제