주어진 GroovyShell
컨텍스트에서만 사용자 정의 IntegerMetaClass
을 사용하고 싶습니다.GroovyShell에 IntegerMetaClass를 동적으로 추가하기
이유는 전체 런타임을 잠재적으로 '방해가되는'것으로 오염시키지 않는 이유입니다. IntegerMetaClass
.
내 IntegerMetaClass.java 구현을 마법 패키지 groovy.runtime.metaclass.java.lang
에 넣으면 매력적으로 작동합니다. 하지만 중간 GroovyClassLoader에 수동으로 추가하려고하면 작업이 중단됩니다.
// Pseudo-code without try catch, etc
// Within my eval factory
GroovyClassLoader gcl = new GroovyClassLoader(getClass().getClassLoader());
URL url = getClass().getClassLoader().getResource("groovy/runtime/metaclass/java/lang/IntegerMetaClass.groovy"); // I rename it to .groovy file
GroovyCodeSource gcs = new GroovyCodeSource(url);
Class<?> clazz = gcl.parseClass(gcs);
// clazz is not null here and equals to what I expect:
// Class<groovy.runtime.metaclass.java.lang.IntegerMetaClass>
// Now trying to use it in a groovy shell
GroovyShell gs = new GroovyShell(gcl);
gs.evaluate("10.minutes"); // Where .minutes is part of my IntegerMetaClass
// Fail with an NoSuchProperty exception
난 그냥 메타 클래스를 '분석'보다 더
GroovyClassLoader
에 할 수있는 뭔가를 그리워합니까? 다른 곳 ?
갱신 1 : 내 자바 소스 클래스 경로에 직접 넣을 때 위에서 언급 한 바와 같이
는 IntegerMetaClass.minutes
조회 노력하고 있습니다.
package groovy.runtime.metaclass.java.lang;
import groovy.lang.DelegatingMetaClass;
import groovy.lang.MetaClass;
public class IntegerMetaClass extends DelegatingMetaClass {
public IntegerMetaClass(Class<Integer> delegate) {
super(delegate);
}
public IntegerMetaClass(MetaClass delegate) {
super(delegate);
}
@Override
public Object getProperty(Object object, String property) {
if ("minutes".equals(property)) {
Integer q = (Integer) object;
return new Minutes(q);
}
return super.getProperty(object, property);
}
}
갱신 2 :
가능한하지만 만족하지 솔루션 : 추가
다음 바로 gcl.parseClass
호출 후
Constructor<?> constructor = clazz.getConstructor(Class.class);
DelegatingMetaClass dmc = (DelegatingMetaClass) constructor.newInstance(Integer.class);
dmc.initialize();
InvokerHelper.getMetaRegistry().setMetaClass(Integer.class, dmc);
그러나이 솔루션은 일종의을 유지한다이상을 지원하기 위해 MetaClass 소스와 원래의 대상 클래스 간의 '매핑' IntegerMetaClass
는 끝내 파일 때 나는 java.lang.IncompatibleClassChangeError
을 가지고 있지만, 자바는 아무 문제 없을 때 :
GroovyShell gs = new GroovyShell()
gs.loader.loadClass('groovy.runtime.metaclass.java.lang.IntegerMetaClass')
gs.evaluate("10.minutes")
참고 : 0 ...
'IntegerMetaClass' 소스를 게시 할 수 있습니까? – Will
관련 항목 : http://stackoverflow.com/questions/25974525/scope-of-groovys-metaclass –
문제는 내가 평가 한 그루비 스크립트를 쓰는 사용자가 '메타 설정'클래스를 사용하기 전에 걱정하지 않기를 바란다. . –