簡體   English   中英

GroovyScriptEngine無法加載正在運行的groovy腳本的導入

[英]GroovyScriptEngine fails to load imports of running groovy script

背景 :

我最近開始玩Groovy,並試圖將groovy腳本引擎嵌入eclipse插件中,以使我的客戶在基於eclipse的產品中開發自己的GUI擴展。 這與codehaus網站上發布的成功故事非常相似。

問題

嘗試加載groovy類(“ SwtGuiBuilder”)時,由GroovyScriptEngine從eclipse插件運行的groovy腳本(我們稱其為“ main_eclipse.groovy”),具有以下錯誤:

BUG! 在已經迭代的同時排隊新資源。 排隊的源是“文件:/home/nicolas/workspace/groovy-test/src/gui/SwtGuiBuilder.groovy”

有人遇到過同樣的問題嗎? 如何解決? 任何幫助將不勝感激!

一些觀察:

  • 當使用groovy解釋器而不是GroovyScriptEngine java對象時,使用我的SwtGuiBuilder類沒有問題(請參見下面的腳本“ main_groovy”)。

  • 我的問題似乎不是類路徑問題,因為在拋出的異常中提到了包含Sw​​tGuiBuilder類的文件。

  • 在兩個報告的常規錯誤GRECLIPSE-429和GRECLIPSE-1037中提到了錯誤消息。 我沒有完全了解技術細節,但是這些錯誤似乎與加載許多類時的性能問題有關,這與我的情況無關。

細節

SampleView.java

public class SampleView
{
public SampleView() { super(); }

public void createPartControl(Composite parent) 
{
    String    groovyScript = null;
    String [] groovyPath   = null;

    boolean shall_exit = false;
    do
    {      // ask user for params
        GroovyLocationDialog groovyLocationDialog= new GroovyLocationDialog(parent.getShell() );
        int return_code = groovyLocationDialog.open();
        if ( return_code != Window.OK )
            shall_exit = true;
        else 
        {
            groovyScript= groovyLocationDialog.getInputScriptName();
            groovyPath  = groovyLocationDialog.getInputScriptPath();

            // run it
            ScriptConnector scriptConnector = new ScriptConnector(parent);
            try                 { scriptConnector.runGuiComponentScript( groovyPath, groovyScript); }
            catch (Exception e) { e.printStackTrace(); }
            System.out.println("script finished");
        }
    }
    while ( ! shall_exit );
}

ScriptConnector.java

public class ScriptConnector
{
    private String[]  roots;
    private Composite window;
    private Binding   binding;

    public ScriptConnector( Composite window )
    {
         this.window    = window;
         Binding  scriptenv = new Binding();    // A new Binding is created ...
         scriptenv.setVariable("SDE", this); 
         scriptenv.setVariable("WINDOW", this.window); // ref to current window

         this.binding = scriptenv;
    }

    public void runGuiComponentScript(final String[] groovyPath, final String scriptName) 
    {
        GroovyScriptEngine gse = null;
        this.roots     = groovyPath;
        try 
        {
            // instanciating the script engine with current classpath
            gse = new GroovyScriptEngine( roots, this.getClass().getClassLoader() );
            gse.run(scriptName, binding);      // ... and run specified script
        }
        catch (Exception e) { e.printStackTrace(); }
        catch (Throwable t) { t.printStackTrace(); }
    }
}

main_eclipse.groovy

package launcher;

import org.eclipse.swt.SWT
import org.eclipse.swt.widgets.*
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.RowLayout as Layout

// This import will fail...
import gui.SwtGuiBuilder;


WINDOW.layout = new Layout(SWT.VERTICAL);
def builder = new SwtGuiBuilder(WINDOW);
builder.Label ( style=SWT.NONE, text = 'Simple demo of Groovy and SWT')
builder.Button( style=SWT.PUSH, text = 'Click me' , action = { println "Click !" } )

SwtGuiBuilder.groovy

package gui;

import org.eclipse.swt.events.*
import org.eclipse.swt.widgets.Button
import org.eclipse.swt.widgets.Composite
import org.eclipse.swt.widgets.Label


class SwtGuiBuilder
{
    private Composite _parent

    public SwtGuiBuilder(Composite parent) { _parent = parent }

    public void Button( style = SWT.PUSH, text= null, action = null )
    {
        def btn = new Button(_parent, style)
        if ( text != null )
            btn.text = text
        if (action != null)
            btn.addSelectionListener( new SelectionAdapter() { void widgetSelected( SelectionEvent event ) { action(); } } );
    }

    public void Label( style = SWT.NONE, text = '' )
    {
        def lbl = new Label(_parent, style)
        lbl.text = text
    }
}

main_groovy.groovy

package launcher;

import org.eclipse.swt.SWT
import org.eclipse.swt.widgets.*
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.RowLayout as Layout

// ... But this import is handled properly !
import gui.SwtGuiBuilder;

def display = new Display()
def WINDOW = new Shell(display)
WINDOW.text = 'Groovy / SWT Test';

WINDOW.layout = new Layout(SWT.VERTICAL);
def builder = new SwtGuiBuilder(WINDOW);
builder.Label ( style=SWT.NONE, text = 'Simple demo of Groovy and SWT')
builder.Button( style=SWT.PUSH, text = 'Click me' , action = { println "Ya clicked me !" } )

WINDOW.pack();
WINDOW.open();

while (!WINDOW.disposed) {
    if (!WINDOW.display.readAndDispatch())
        WINDOW.display.sleep();
}

堆棧跟蹤

BUG! 在已經迭代的同時排隊新資源。 排隊的源是org.codehaus.groovy.control.CompilationUnit.addSource(CompilationUnit.java:460)的``file:/home/nicolas/workspace/groovy-test/src/gui/SwtGuiBuilder.groovy'' groovy.util.GroovyScriptEngine $ ScriptClassLoader $ 3.findClassNode(GroovyScriptEngine.java:195)的org.codehaus.groovy.control.ClassNodeResolver.resolveName(ClassNodeResolver.java:124)的.control.CompilationUnit.addSource(CompilationUnit.java:433)在org.codehaus.groovy.control.ResolveVisitor.resolveToOuter(ResolveVisitor.java:863)在org.codehaus.groovy.control.ResolveVisitor.resolve(ResolveVisitor.java:377)在org.codehaus.groovy.control.ResolveVisitor.visitClass (ResolveVisitor.java:1407)在org.codehaus.groovy.control.ResolveVisitor.startResolving(ResolveVisitor.java:202)在org.codehaus.groovy.control.CompilationUnit $ 1.call(CompilationUnit.java:713)在org.codehaus org.codehaus.groovy.control.CompilationUnit.doPha上的.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:1015) groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:279)上org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:596)上的seOperation(CompilationUnit.java:647)在groovy.lang.GroovyClassLoader.parseClass上(GroovyClassLoader.java:258)在groovy.util.GroovyScriptEngine $ ScriptClassLoader.doParseClass(GroovyScriptEngine.java:247)在groovy.util.GroovyScriptEngine $ ScriptClassLoader.parseClass(GroovyScriptEngine.java:229)在groovy.lang.GroovyClass在groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:202)處在Groovy.util.GroovyScriptEngine.loadScriptByName(GroovyScriptEngine.java:514)在groovy.util.GroovyScriptEngine.Engine Script(Groovy )在groovy.util.GroovyScriptEngine.run(GroovyScriptEngine.java:551)

我的配置:

  • Linux Ubuntu 14.04 x86

  • Groovy版本:2.3.2

  • 的JVM:1.7.0_55

  • Eclipse Kepler SR2-內部版本20140224-0627

  • Eclipse Groovy插件v2.0.7

我沒有使用GroovyShell類(下面的Groovy代碼,但是很容易更改回Java),而是使用GroovyShell類,CompilerConfiguration允許您指定類路徑。

    def config = new CompilerConfiguration(classpath: classpath)
    def binding = new Binding()

    def result = new GroovyShell(binding, config).evaluate("""
def foo='bar'
""")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM