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;
}
}

View File

@@ -67,7 +67,7 @@ public class Jsr223RefreshTests {
private static class CycleResource extends AbstractResource {
private int count = -1;
private String[] scripts = {"\"ruby-#{$payload}-0\"", "\"ruby-#{$payload}-1\""};
private String[] scripts = {"\"ruby-#{payload}-0\"", "\"ruby-#{payload}-1\""};
public String getDescription() {
return "CycleResource";

View File

@@ -33,7 +33,7 @@
<service-activator input-channel="inlineScriptInput">
<script:script lang="ruby">
<![CDATA[
"inline-#{$payload}"
"inline-#{payload}"
]]>
</script:script>
</service-activator>

View File

@@ -10,7 +10,7 @@
<service-activator input-channel="inlineScriptInput">
<script:script lang="ruby">
<![CDATA[
return "inline-#{$payload}-" + "#{$foo}" + " - " + $bar + " - " + $date
return "inline-#{payload}-" + "#{foo}" + " - " + bar + " - " + date
]]>
<script:variable name="foo" value="foo"/>
<script:variable name="bar" value="bar"/>

View File

@@ -1 +1 @@
"ruby-#{$payload}-#{$foo} - #{$bar} - #{$date}"
"ruby-#{payload}-#{foo} - #{bar} - #{date}"

View File

@@ -2,7 +2,6 @@ class Transformer
def transform(payload)
"ruby-#{payload}"
end
end
Transformer.new.transform($payload)
Transformer.new.transform(payload)

View File

@@ -1,12 +1,12 @@
include Java
require "java"
include_class 'java.util.Date'
#payload and headers a global variable
if $payload
$payload = $payload+" modified #{Date.new}"
if payload
payload = payload+" modified #{Date.new}"
end
puts $payload
if $headers
$headers.each {|key, value| puts "#{key} is #{value}" }
puts payload
if headers
headers.each {|key, value| puts "#{key} is #{value}" }
end
puts "#{$one} #{$two} #{$three}"
$payload
payload