You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sj...@apache.org on 2026/08/31 22:45:24 UTC
(maven-script-interpreter) branch master updated: Allow interpreters to target a specific bytecode version
This is an automated email from the ASF dual-hosted git repository.
slawekjaranowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-script-interpreter.git
The following commit(s) were added to refs/heads/master by this push:
new 15eabe2 Allow interpreters to target a specific bytecode version
15eabe2 is described below
commit 15eabe26b2dfc56009c016a3aa16b880d662cfbc
Author: adityaanikam <ad...@gmail.com>
AuthorDate: Wed Aug 5 23:44:12 2026 +0530
Allow interpreters to target a specific bytecode version
See apache/maven-invoker-plugin#742
Signed-off-by: adityaanikam <ad...@gmail.com>
---
.../scriptinterpreter/GroovyScriptInterpreter.java | 39 +++++++++++++++++++---
.../scriptinterpreter/ScriptInterpreter.java | 10 ++++++
.../shared/scriptinterpreter/ScriptRunner.java | 12 +++++++
.../GroovyScriptInterpreterTest.java | 20 +++++++++++
4 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreter.java b/src/main/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreter.java
index 3617572..abadea2 100644
--- a/src/main/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreter.java
+++ b/src/main/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreter.java
@@ -42,6 +42,8 @@ class GroovyScriptInterpreter implements ScriptInterpreter {
private final RootLoader childFirstLoader =
new RootLoader(new URL[] {}, Thread.currentThread().getContextClassLoader());
+ private String targetBytecode;
+
@Override
public void setClassPath(List<String> classPath) {
if (classPath == null || classPath.isEmpty()) {
@@ -51,6 +53,11 @@ class GroovyScriptInterpreter implements ScriptInterpreter {
classPath.stream().map(this::toUrl).forEach(childFirstLoader::addURL);
}
+ @Override
+ public void setTargetBytecode(String version) {
+ this.targetBytecode = version;
+ }
+
private URL toUrl(String path) {
try {
return new File(path).toURI().toURL();
@@ -59,6 +66,27 @@ class GroovyScriptInterpreter implements ScriptInterpreter {
}
}
+ /**
+ * Maps a Maven-style release value (for example <code>"8"</code>) to the version string Groovy's
+ * {@link CompilerConfiguration#setTargetBytecode(String)} expects (for example <code>"1.8"</code>). Groovy uses
+ * the <code>"1.x"</code> form for JDK 4 through 8, and bare version numbers from JDK 9 onward.
+ *
+ * @param version The Maven-style release value, must not be <code>null</code>.
+ * @return The Groovy-compatible bytecode version string.
+ */
+ static String normalizeTargetBytecode(String version) {
+ switch (version) {
+ case "4":
+ case "5":
+ case "6":
+ case "7":
+ case "8":
+ return "1." + version;
+ default:
+ return version;
+ }
+ }
+
/**
* {@inheritDoc}
*/
@@ -76,10 +104,13 @@ class GroovyScriptInterpreter implements ScriptInterpreter {
System.setOut(scriptOutput);
}
- GroovyShell interpreter = new GroovyShell(
- childFirstLoader,
- new Binding(globalVariables),
- new CompilerConfiguration(CompilerConfiguration.DEFAULT));
+ CompilerConfiguration compilerConfiguration = new CompilerConfiguration(CompilerConfiguration.DEFAULT);
+ if (targetBytecode != null) {
+ compilerConfiguration.setTargetBytecode(normalizeTargetBytecode(targetBytecode));
+ }
+
+ GroovyShell interpreter =
+ new GroovyShell(childFirstLoader, new Binding(globalVariables), compilerConfiguration);
Thread.currentThread().setContextClassLoader(childFirstLoader);
return interpreter.evaluate(script);
diff --git a/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptInterpreter.java b/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptInterpreter.java
index 01cc14d..3ddcff8 100644
--- a/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptInterpreter.java
+++ b/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptInterpreter.java
@@ -41,6 +41,16 @@ public interface ScriptInterpreter extends Closeable {
*/
void setClassPath(List<String> classPath);
+ /**
+ * Sets the target bytecode version for interpreters that support bytecode-level compilation. Interpreters
+ * that do not compile to a specific bytecode level (for example BeanShell) may ignore this.
+ *
+ * @param version The target bytecode version, may be <code>null</code> to use the interpreter's own default.
+ */
+ default void setTargetBytecode(String version) {
+ // no-op by default
+ }
+
/**
* Evaluates the specified script.
*
diff --git a/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java b/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
index a1ed3e8..2ef2f8e 100644
--- a/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
+++ b/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
@@ -104,6 +104,18 @@ public class ScriptRunner implements Closeable {
}
}
+ /**
+ * Sets the target bytecode version for the hook scripts, for interpreters that support bytecode-level
+ * compilation.
+ *
+ * @param version The target bytecode version, may be <code>null</code> to use each interpreter's own default.
+ */
+ public void setTargetBytecode(String version) {
+ if (version != null) {
+ scriptInterpreters.values().forEach(scriptInterpreter -> scriptInterpreter.setTargetBytecode(version));
+ }
+ }
+
/**
* Sets the file encoding of the hook scripts.
*
diff --git a/src/test/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreterTest.java b/src/test/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreterTest.java
index 3bee0fa..fa78fdb 100644
--- a/src/test/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreterTest.java
+++ b/src/test/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreterTest.java
@@ -96,4 +96,24 @@ class GroovyScriptInterpreterTest {
}
assertEquals("data", out.toString());
}
+
+ @Test
+ void evaluateScriptWithTargetBytecode() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (ScriptInterpreter interpreter = new GroovyScriptInterpreter()) {
+ interpreter.setTargetBytecode("8");
+ assertEquals(
+ Boolean.TRUE,
+ interpreter.evaluateScript("print \"Test\"\nreturn true", null, new PrintStream(out)));
+ }
+ assertEquals("Test", out.toString());
+ }
+
+ @Test
+ void normalizeTargetBytecodeMapsOldJdksToDotForm() {
+ assertEquals("1.4", GroovyScriptInterpreter.normalizeTargetBytecode("4"));
+ assertEquals("1.8", GroovyScriptInterpreter.normalizeTargetBytecode("8"));
+ assertEquals("9", GroovyScriptInterpreter.normalizeTargetBytecode("9"));
+ assertEquals("17", GroovyScriptInterpreter.normalizeTargetBytecode("17"));
+ }
}