1

GroovyClassLoader.parseClass(src) を使用して単一の Groovy ソース モジュールを「その場で」コンパイルしましたが、すべて問題ありません。

しかし問題は、このソース モジュールが他のクラスをインポートするときに、これらがまだコンパイルされていないことです。1 つのソースのコンパイルを開始すると、従来のコンパイルが必要になり、ソース パス上で準備ができている他のソースもコンパイルされます。

GroovyClassLoader をターゲットで使用して、他のすべての必要なソースを FILESYSYSTEM からではなくコンパイルするにはどうすればよいですか。私のソースは、たとえばデータベース、URI 経由のリモート http などにあります。

4

1 に答える 1

4

重要なのは、カスタム URL 処理を作成することです。URLStreamHandlerURLConnectionを実装する必要があります。

グーグルで検索すると、ストリーム ハンドラと接続クラスの実装方法に関する優れたドキュメントがいくつかありますが、実際に必要なのはダミーの実装だけです。

ブートストラップ用のソース コードを次に示します。これは、ピースを接続する方法を示しています。lookupScriptCodeWithJDBCorWhatever の実装を提供すれば、問題ありません。

import groovy.lang.GroovyResourceLoader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;

public class CustomGroovyResourceLoader implements GroovyResourceLoader {

    private final GroovyResourceLoader parentLoader;

    public CustomGroovyResourceLoader(GroovyResourceLoader parentLoader) {
        this.parentLoader = parentLoader;
    }

    @Override
    public URL loadGroovySource(String filename) throws MalformedURLException {
        URL resourceURL = null;

        if (parentLoader != null) {
            resourceURL = parentLoader.loadGroovySource(filename);
        }

        if (resourceURL == null) {
            resourceURL = createURL(filename);
        }

        return resourceURL;
    }

    public URL createURL(String resourceName) throws MalformedURLException {

        String scriptSourceCode = lookupScriptCodeWithJDBCorWhatever(resourceName);

        return new URL(null, "groovy:///" + resourceName,
                new GroovyResourceStreamHandler(scriptSourceCode));

    }

    private String lookupScriptCodeWithJDBCorWhatever(String resourceName) {

        //TODO: blah blah blah
        return null;
    }

    class GroovyResourceConnection extends URLConnection {

        private final String urlData;

        protected GroovyResourceConnection(URL url, String logic) {
            super(url);
            this.urlData = logic;
        }

        @Override
        public void connect() throws IOException {}

        @Override
        public InputStream getInputStream() throws IOException {
            return new ByteArrayInputStream(urlData.getBytes());
        }
    }

    class GroovyResourceStreamHandler extends URLStreamHandler {

        private final String scriptSource;

        public GroovyResourceStreamHandler(String scriptSource) {
            this.scriptSource = scriptSource;
        }

        @Override
        protected URLConnection openConnection(URL u) throws IOException {
            GroovyResourceConnection connection = new GroovyResourceConnection(u, scriptSource);
            return connection;

        }
    }

}

次に、次のようなコードを使用してこれをインストールします。

GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
groovyClassLoader.setResourceLoader( new CustomGroovyResourceLoader( groovyClassLoader.getResourceLoader() ) );
于 2015-08-19T16:33:53.607 に答える