4

特定のコンテキストIntegerMetaClassでのみカスタムを使用したいと思います。GroovyShell

その理由は、ランタイム全体を私の潜在的な 'disturbing' で汚染しないため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

GroovyClassLoaderMetaClass を「解析」するだけでなく、やらなければならないことがありませんか? どこか他の ?

アップデート1:

上記のようIntegerMetaClass.minutesに、Java ソースのクラスパスに直接配置すると、ルックアップが機能します。

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 ソースと元のターゲット クラスの間で一種の「マッピング」を維持して、より多くの機能をサポートする必要がありIntegerます。

4

1 に答える 1