diff --git a/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptEvaluator.java b/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptEvaluator.java
index 3bcf53f08bd..e94b9d400ad 100644
--- a/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptEvaluator.java
+++ b/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptEvaluator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,8 @@ import java.util.Map;
import groovy.lang.Binding;
import groovy.lang.GroovyRuntimeException;
import groovy.lang.GroovyShell;
+import org.codehaus.groovy.control.CompilerConfiguration;
+import org.codehaus.groovy.control.customizers.CompilationCustomizer;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.scripting.ScriptCompilationException;
@@ -40,6 +42,8 @@ public class GroovyScriptEvaluator implements ScriptEvaluator, BeanClassLoaderAw
private ClassLoader classLoader;
+ private CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
+
/**
* Construct a new GroovyScriptEvaluator.
@@ -56,6 +60,35 @@ public class GroovyScriptEvaluator implements ScriptEvaluator, BeanClassLoaderAw
}
+ /**
+ * Set a custom compiler configuration for this evaluator.
+ * @since 4.3.3
+ * @see #setCompilationCustomizers
+ */
+ public void setCompilerConfiguration(CompilerConfiguration compilerConfiguration) {
+ this.compilerConfiguration =
+ (compilerConfiguration != null ? compilerConfiguration : new CompilerConfiguration());
+ }
+
+ /**
+ * Return this evaluator's compiler configuration (never {@code null}).
+ * @since 4.3.3
+ * @see #setCompilerConfiguration
+ */
+ public CompilerConfiguration getCompilerConfiguration() {
+ return this.compilerConfiguration;
+ }
+
+ /**
+ * Set one or more customizers to be applied to this evaluator's compiler configuration.
+ *
Note that this modifies the shared compiler configuration held by this evaluator.
+ * @since 4.3.3
+ * @see #setCompilerConfiguration
+ */
+ public void setCompilationCustomizers(CompilationCustomizer... compilationCustomizers) {
+ this.compilerConfiguration.addCompilationCustomizers(compilationCustomizers);
+ }
+
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
@@ -69,7 +102,8 @@ public class GroovyScriptEvaluator implements ScriptEvaluator, BeanClassLoaderAw
@Override
public Object evaluate(ScriptSource script, Map arguments) {
- GroovyShell groovyShell = new GroovyShell(this.classLoader, new Binding(arguments));
+ GroovyShell groovyShell = new GroovyShell(
+ this.classLoader, new Binding(arguments), this.compilerConfiguration);
try {
String filename = (script instanceof ResourceScriptSource ?
((ResourceScriptSource) script).getResource().getFilename() : null);
diff --git a/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java b/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java
index cbade53fbbe..4155b3f986b 100644
--- a/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java
+++ b/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java
@@ -36,6 +36,7 @@ import org.springframework.scripting.ScriptFactory;
import org.springframework.scripting.ScriptSource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
+import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
/**
@@ -104,23 +105,39 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
this.groovyObjectCustomizer = groovyObjectCustomizer;
}
+ /**
+ * Create a new GroovyScriptFactory for the given script source,
+ * specifying a strategy interface that can create a custom MetaClass
+ * to supply missing methods and otherwise change the behavior of the object.
+ * @param scriptSourceLocator a locator that points to the source of the script.
+ * Interpreted by the post-processor that actually creates the script.
+ * @param compilerConfiguration a custom compiler configuration to be applied
+ * to the GroovyClassLoader (may be {@code null})
+ * @since 4.3.3
+ * @see GroovyClassLoader#GroovyClassLoader(ClassLoader, CompilerConfiguration)
+ */
+ public GroovyScriptFactory(String scriptSourceLocator, CompilerConfiguration compilerConfiguration) {
+ this(scriptSourceLocator);
+ this.compilerConfiguration = compilerConfiguration;
+ }
+
/**
* Create a new GroovyScriptFactory for the given script source,
* specifying a strategy interface that can customize Groovy's compilation
* process within the underlying GroovyClassLoader.
* @param scriptSourceLocator a locator that points to the source of the script.
* Interpreted by the post-processor that actually creates the script.
- * @param compilationCustomizer a customizer to be applied to the GroovyClassLoader
- * compiler configuration (may be {@code null})
+ * @param compilationCustomizers one or more customizers to be applied to the
+ * GroovyClassLoader compiler configuration
* @since 4.3.3
* @see CompilerConfiguration#addCompilationCustomizers
* @see org.codehaus.groovy.control.customizers.ImportCustomizer
*/
- public GroovyScriptFactory(String scriptSourceLocator, CompilationCustomizer compilationCustomizer) {
+ public GroovyScriptFactory(String scriptSourceLocator, CompilationCustomizer... compilationCustomizers) {
this(scriptSourceLocator);
- if (compilationCustomizer != null) {
+ if (!ObjectUtils.isEmpty(compilationCustomizers)) {
this.compilerConfiguration = new CompilerConfiguration();
- this.compilerConfiguration.addCompilationCustomizers(compilationCustomizer);
+ this.compilerConfiguration.addCompilationCustomizers(compilationCustomizers);
}
}
diff --git a/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptEvaluatorTests.java b/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptEvaluatorTests.java
index 615458c7702..6e6b6511ce2 100644
--- a/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptEvaluatorTests.java
+++ b/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptEvaluatorTests.java
@@ -19,6 +19,7 @@ package org.springframework.scripting.groovy;
import java.util.HashMap;
import java.util.Map;
+import org.codehaus.groovy.control.customizers.ImportCustomizer;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
@@ -58,6 +59,26 @@ public class GroovyScriptEvaluatorTests {
assertEquals(6, result);
}
+ @Test
+ public void testGroovyScriptWithCompilerConfiguration() {
+ GroovyScriptEvaluator evaluator = new GroovyScriptEvaluator();
+ MyBytecodeProcessor processor = new MyBytecodeProcessor();
+ evaluator.getCompilerConfiguration().setBytecodePostprocessor(processor);
+ Object result = evaluator.evaluate(new StaticScriptSource("return 3 * 2"));
+ assertEquals(6, result);
+ assertTrue(processor.processed.contains("Script1"));
+ }
+
+ @Test
+ public void testGroovyScriptWithImportCustomizer() {
+ GroovyScriptEvaluator evaluator = new GroovyScriptEvaluator();
+ ImportCustomizer importCustomizer = new ImportCustomizer();
+ importCustomizer.addStarImports("org.springframework.util");
+ evaluator.setCompilationCustomizers(importCustomizer);
+ Object result = evaluator.evaluate(new StaticScriptSource("return ResourceUtils.CLASSPATH_URL_PREFIX"));
+ assertEquals("classpath:", result);
+ }
+
@Test
public void testGroovyScriptFromStringUsingJsr223() {
StandardScriptEvaluator evaluator = new StandardScriptEvaluator();
diff --git a/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java b/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java
index ec2214629e8..24ef4c75378 100644
--- a/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java
+++ b/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java
@@ -470,6 +470,8 @@ public class GroovyScriptFactoryTests {
ApplicationContext ctx = new ClassPathXmlApplicationContext("groovy-with-xsd.xml", getClass());
Map, Messenger> beans = ctx.getBeansOfType(Messenger.class);
assertEquals(4, beans.size());
+ assertTrue(ctx.getBean(MyBytecodeProcessor.class).processed.contains(
+ "org.springframework.scripting.groovy.GroovyMessenger2"));
}
@Test
diff --git a/spring-context/src/test/java/org/springframework/scripting/groovy/MyBytecodeProcessor.java b/spring-context/src/test/java/org/springframework/scripting/groovy/MyBytecodeProcessor.java
new file mode 100644
index 00000000000..12a99139a37
--- /dev/null
+++ b/spring-context/src/test/java/org/springframework/scripting/groovy/MyBytecodeProcessor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2002-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.scripting.groovy;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.codehaus.groovy.control.BytecodeProcessor;
+
+/**
+ * @author Juergen Hoeller
+ */
+public class MyBytecodeProcessor implements BytecodeProcessor {
+
+ public final Set processed = new HashSet();
+
+ @Override
+ public byte[] processBytecode(String name, byte[] original) {
+ this.processed.add(name);
+ return original;
+ }
+
+}
diff --git a/spring-context/src/test/resources/org/springframework/scripting/groovy/groovy-with-xsd.xml b/spring-context/src/test/resources/org/springframework/scripting/groovy/groovy-with-xsd.xml
index 648464cceca..070a64d03fe 100644
--- a/spring-context/src/test/resources/org/springframework/scripting/groovy/groovy-with-xsd.xml
+++ b/spring-context/src/test/resources/org/springframework/scripting/groovy/groovy-with-xsd.xml
@@ -39,8 +39,8 @@ class GroovyCalculator implements Calculator {
@@ -53,8 +53,15 @@ public class TestCustomizer implements GroovyObjectCustomizer {
-
+
+
+
+
+
+
+