2012-04-25 75 views
4

我知道我必須做一些事情,只是腦死人愚蠢的這不起作用,但我在一個情況下,我想動態地加載到正在運行的服務器的行爲。我選擇groovy作爲我的工具來做到這一點。該行爲將需要引用服務器類路徑上的類,例如我的模型對象以及像Freemarker這樣的第三方庫。Groovy,嵌入到Java中,回撥到Java

我把這個愚蠢的POC扔在一起來展示可行性。儘管事實上我將GroovyClassPath的父類路徑設置爲當前,但我無法獲得groovy腳本來解決Java類「ThingyDoodle」和「Fooable」。

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 
            ^

回答

3

您的代碼中的問題是,Fooable接口和ThingyDoodle類無法找到,因爲它們都是內部l類,並需要使用包含類名稱進行限定,即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" ; 
     } 
    } 


} 
+0

好的,這是令人尷尬的:) – billmill 2012-04-26 12:30:19

+0

非常感謝!這是我需要的。 – billmill 2012-04-26 12:30:37

+2

不要出汗。我擅長在別人身上發現錯誤[bugs],但是對我自己的[bugs]一目瞭然...... :) – Nicholas 2012-04-26 14:47:01

2

不知道你是如何編譯它......我想這(使用Gradle作爲構建工具)和它的作品...

./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()) ; 
    } 
} 

然後,當我在命令行中輸入gradle run,我得到的輸出:

$ gradle run 
:compileJava 
:processResources UP-TO-DATE 
:classes 
:run 
Hi tim 

BUILD SUCCESSFUL 
+0

我在內部編譯它,在運行時,在J2EE服務器中。如果我使用gradle,它會挫敗這個練習的目的。不管怎麼說,還是要謝謝你! – billmill 2012-04-26 12:32:01

+0

夠公平的,很高興它被排序:-)把這樣的信息在這個問題可能會節省下次的時間;-)祝你好運! – 2012-04-26 12:33:58