Groovy,嵌入Java,调用Java
我知道我必须做一些愚蠢至极的事情才能让它不起作用,但我现在的处境是,我想动态地将行为加载到正在运行的服务器中。我选择groovy作为我的工具来实现这一点。该行为将需要引用服务器类路径上的类,比如我的模型对象以及第三方库,比如Freemarker 我拼凑了这个愚蠢的POC来证明它的可行性。我无法让groovy脚本解析Java类“ThingyDoodle”和“Fooable”,尽管我将GroovyClassPath的父类路径设置为当前路径Groovy,嵌入Java,调用Java,java,groovy,classpath,Java,Groovy,Classpath,我知道我必须做一些愚蠢至极的事情才能让它不起作用,但我现在的处境是,我想动态地将行为加载到正在运行的服务器中。我选择groovy作为我的工具来实现这一点。该行为将需要引用服务器类路径上的类,比如我的模型对象以及第三方库,比如Freemarker 我拼凑了这个愚蠢的POC来证明它的可行性。我无法让groovy脚本解析Java类“ThingyDoodle”和“Fooable”,尽管我将GroovyClassPath的父类路径设置为当前路径 public class GroovyTest {
public class GroovyTest
{
public static void main ( String [ ] argv ) throws Throwable
{
// Setting parent classloader!
// also tried plain old "GroovyTest.class.getClassLoader()" as well
GroovyClassLoader gcl = new GroovyClassLoader ( Thread.currentThread().getContextClassLoader() ) ;
String src =
"class Arf implements Fooable {
public String foo ( ) {
return new ThingyDoodle().doStuff('Arf');}}" ;
Class clazz = gcl.parseClass(src, "AppleSauce.groovy");
Object aScript = clazz.newInstance();
Fooable myObject = (Fooable) aScript;
System.out.println ( myObject.foo() ) ;
}
public static interface Fooable { public String foo ( ) ; }
public static class ThingyDoodle
{
public String doStuff ( String input )
{
return "Hi Worlds" ;
}
}
}
我到底做错了什么
Exception in thread "main" org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
AppleSauce.groovy: 1: unable to resolve class Fooable
@ line 1, column 1.
class Arf implements Fooable { public String foo ( ) { return new ThingyDoodle().doStuff('Arf');}}
^
AppleSauce.groovy: 1: unable to resolve class ThingyDoodle
@ line 1, column 63.
ublic String foo ( ) { return new Thingy
^
不知道你是怎么编译的。。。我尝试了这个(作为构建工具使用),它很有效 /build.gradle
apply plugin:'application'
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.codehaus.groovy', name: 'groovy', version: '1.8.6'
}
mainClassName = 'org.timyates.GroovyTest'
./src/main/java/org/timyates/Fooable.java
package org.timyates ;
public interface Fooable {
public String foo() ;
}
./src/main/java/org/timyates/ThingyDoodle.java
package org.timyates ;
public class ThingyDoodle {
public String doStuff( String input ) {
return String.format( "Hi %s", input ) ;
}
}
./src/main/java/org/timyates/GroovyTest.java
package org.timyates ;
import groovy.lang.GroovyClassLoader ;
public class GroovyTest {
public static void main( String[] args ) throws Exception {
GroovyClassLoader gcl = new GroovyClassLoader( GroovyTest.class.getClassLoader() ) ;
String src = "import org.timyates.*\n" +
"class Arf implements Fooable {\n" +
" public String foo() {\n" +
" new ThingyDoodle().doStuff( 'tim' )\n" +
" }\n" +
"}" ;
Class clazz = gcl.parseClass( src, "AppleSauce.groovy" ) ;
Fooable myObject = (Fooable)clazz.newInstance() ;
System.out.println( myObject.foo() ) ;
}
}
然后,当我在命令行中输入gradlerun
时,我会得到以下输出:
$ gradle run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hi tim
BUILD SUCCESSFUL
代码中的问题是找不到Fooable接口和ThingyDoodle类,因为它们都是内部类,需要使用包含的类名限定,即GroovyTest。我在嵌入的脚本中限定了这两个名称(并修复了脚本周围的引号),它按预期运行
import groovy.lang.GroovyClassLoader;
public class GroovyTest
{
public static void main ( String [ ] argv ) throws Throwable
{
// Setting parent classloader!
// also tried plain old "GroovyTest.class.getClassLoader()" as well
GroovyClassLoader gcl = new GroovyClassLoader ( Thread.currentThread().getContextClassLoader() ) ;
String src =
"class Arf implements GroovyTest.Fooable { " +
"public String foo ( ) { " +
"return new GroovyTest.ThingyDoodle().doStuff('Arf');}}" ;
Class clazz = gcl.parseClass(src, "AppleSauce.groovy");
Object aScript = clazz.newInstance();
Fooable myObject = (Fooable) aScript;
System.out.println ( myObject.foo() ) ;
}
public static interface Fooable { public String foo ( ) ; }
public static class ThingyDoodle
{
public String doStuff ( String input )
{
return "Hi Worlds" ;
}
}
}
非常感谢你!这就是我需要的,别担心。我擅长发现别人的缺点,但对自己的缺点视而不见我在运行时在J2EE服务器中内联编译它。如果我使用gradle,它将无法达到此练习的目的。无论如何谢谢你!很公平,很高兴它被分类了:-)把这类信息放在问题中可能会节省下一次的时间;-)祝你好运!