Corrected concurrency issues with JRuby

This commit is contained in:
David Turanski
2011-09-27 21:23:04 -04:00
committed by Mark Fisher
parent f78d6021a8
commit a5ac75ea43
7 changed files with 70 additions and 78 deletions

View File

@@ -13,95 +13,88 @@
package org.springframework.integration.scripting.jsr223;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;
import javax.script.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.scripting.ScriptExecutor;
import org.springframework.scripting.ScriptSource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Executes Jsr223 scripts
* Executes JSR223 scripts
*
* @author David Turanski
* @since 2.1
*/
public class DefaultScriptExecutor implements ScriptExecutor {
static {
if (ClassUtils.isPresent("org.jruby.embed.jsr223.JRubyEngine", System.class.getClassLoader())) {
System.setProperty("org.jruby.embed.localvariable.behavior", "transient");
System.setProperty("org.jruby.embed.localcontext.scope", "threadsafe");
}
}
private static Log log = LogFactory.getLog(DefaultScriptExecutor.class);
private final ScriptEngine scriptEngine;
/**
* Set the engine name (language)
* Set the language name (JSR233 alias)
* @param language
*/
public DefaultScriptExecutor(String language) {
ScriptEngineManager manager = new ScriptEngineManager();
if (log.isDebugEnabled()){
for (ScriptEngineFactory factory: manager.getEngineFactories()) {
log.debug(factory.getNames());
}
}
scriptEngine = manager.getEngineByName(language);
Assert.notNull(scriptEngine,"JVM cannot create a script engine for name [" + language + "]");
}
/*
* (non-Javadoc)
*
* @see
* com.dturanski.test.jruby.ScriptExecutor#executeScript(org.springframework
* .scripting.ScriptSource)
*/
public Object executeScript(ScriptSource scriptSource) {
return this.executeScript(scriptSource,null);
}
/*
* (non-Javadoc)
*
* @see
* com.dturanski.test.jruby.ScriptExecutor#bindVariable(java.lang.String,
* java.lang.Object)
*/
private void bindVariable(String variableName, Object value) {
scriptEngine.put(variableName, value);
}
/* (non-Javadoc)
* @see org.springframework.integration.jsr233.ScriptExecutor#executeScript(org.springframework.scripting.ScriptSource, java.util.Map)
*/
public Object executeScript(ScriptSource scriptSource, Map<String, Object> variables) {
Assert.notNull(scriptSource, "scriptSource must not be null");
synchronized (this) {
Object obj = null;
try {
scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE).clear();
if (variables != null ) {
for (Entry<String, Object> entry: variables.entrySet()){
bindVariable(entry.getKey(), entry.getValue());
}
}
obj = scriptEngine.eval(scriptSource.getScriptAsString());
}
catch (ScriptException e) {
throw new RuntimeException(e);
}
catch (IOException e) {
throw new RuntimeException(e);
}
return obj;
if (log.isDebugEnabled()) {
log.debug("using script engine : " + scriptEngine.getFactory().getEngineName());
}
}
public Object executeScript(ScriptSource scriptSource) {
return this.executeScript(scriptSource, null);
}
public synchronized Object executeScript(ScriptSource scriptSource, Map<String, Object> variables) {
Object obj = null;
try {
if (variables != null) {
for (Entry<String, Object> entry : variables.entrySet()) {
scriptEngine.put(entry.getKey(), entry.getValue());
}
}
String script = scriptSource.getScriptAsString();
Date start = new Date();
if (log.isDebugEnabled()) {
log.debug("executing script: " + script);
}
obj = scriptEngine.eval(script);
if (log.isDebugEnabled()) {
log.debug("script executed in " + (new Date().getTime() - start.getTime()) + " ms");
}
}
catch (IOException e) {
throw new RuntimeException(e);
}
catch (ScriptException e) {
throw new RuntimeException(e);
}
return obj;
}
}