1

ソースファイルを動的にロードすることで、ユーザーがプラグインをメインの Groovy アプリケーションに提供する方法を考え出そうとしています。しかし、彼らのグルーヴィーなファイルには import ステートメントが含まれており、明らかに適切なクラスパスでもそれらを機能させる方法がわかりません。

主なアプリケーションは、シェル スクリプト bin/top.sh です。

#!/bin/bash
groovy-2.4.1/bin/groovy -cp lib lib/Top.groovy

lib/Top.groovy クラス:

public class Top {
  public static void main(String[] args) {
    ClassLoader parent = getClass().getClassLoader()
    GroovyClassLoader loader = new GroovyClassLoader(parent)
    Class groovyClass = loader.parseClass(new File("UserPlugin.groovy"))
    GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance()
    groovyObject.invokeMethod("run",args)
  } 
}

ユーザークラス UserPlugin.groovy:

// The following import can be found in the classpath
// passed by the shell script (under lib/, next to Top.groovy)
import Lib

class UserPlugin {
  def UserPlugin() {
    Lib lib = new Lib()
  }
  def run(String [] args) {
    println("Running with: "+args)
  }
}

そして lib/Lib.groovy:

class Lib {
  def Lib() {
    println("Lib")
  }
}

で実行するとbin/top.sh、次のようになります。UserPlugin.groovy: 3: unable to resolve class Lib

libそのようにクラスローダーに追加すると、loader.addClasspath('lib')かなり壊滅的です:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during class generation: java.lang.NoClassDefFoundError: groovy/lang/GroovyObject

java.lang.RuntimeException: java.lang.NoClassDefFoundError: groovy/lang/GroovyObject
    at org.codehaus.groovy.control.CompilationUnit.convertUncaughtExceptionToCompilationError(CompilationUnit.java:1088)

すべてをスクリプト化してコンパイルせずに維持しながら、これをどのように機能させることができますか? これは可能ですか?

4

1 に答える 1

0

申し訳ありませんが、バグを見つける時間がありませんが、問題はコンテキスト クラスローダーの設定にあると思います。GroovyShell.run がそれを処理してくれるので、そのコードを複製するよりもお勧めします。

Top.groovy

    public class Top {
        public static void main(String[] args) {
            new GroovyShell().run(new File("UserPlugin.groovy"), args)
        }
    }

Top.groovy をクラスではなくスクリプトにしたい場合は、次のようにします。

Top.groovy

    run(new File("UserPlugin.groovy"), args)

UserPlugin.groovy は、標準の Groovy 呼び出しロジックを使用するクラス (メイン メソッドを含む) またはスクリプトのいずれかである必要があります。

于 2015-02-27T02:53:37.593 に答える