![](/img/trans.png)
[英]How to load a string input(groovy script) using GroovyScriptEngine from Java
[英]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”)。
我的问题似乎不是类路径问题,因为在抛出的异常中提到了包含SwtGuiBuilder类的文件。
在两个报告的常规错误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.