Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions agent/agent_standalone_pkg/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,19 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js-community</artifactId>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
Expand Down
14 changes: 12 additions & 2 deletions agent/apiharness/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,18 @@
</dependency>

<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js-community</artifactId>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import com.intuit.tank.vm.common.LogicScriptUtil;
import com.intuit.tank.vm.common.TankConstants;

import javax.script.ScriptEngineManager;
import com.intuit.tank.tools.script.JsEngineFactory;

class LogicRunner implements Runner {
private static Logger LOG = LogManager.getLogger(LogicRunner.class);
Expand Down Expand Up @@ -60,7 +60,7 @@ public String execute() {
String scriptToRun = new LogicScriptUtil().buildScript(step.getScript());
try {
ScriptIOBean ioBean = new ScriptRunner().runScript(step.getName(), scriptToRun,
new ScriptEngineManager().getEngineByExtension("js"), inputs, outputLogger);
JsEngineFactory.createJsEngine(), inputs, outputLogger);
String action = (String) ioBean.getOutput("action");
if (action != null) {
ret = handleAction(action);
Expand Down
15 changes: 13 additions & 2 deletions agent/apiharness_pkg/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,19 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js-community</artifactId>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
Expand Down
5 changes: 5 additions & 0 deletions data_model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,10 @@
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>script-engine</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import jakarta.persistence.Table;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import com.intuit.tank.tools.script.JsEngineFactory;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

Expand Down Expand Up @@ -89,7 +90,11 @@ public void setProductName(String productName) {
}

public ScriptEngine getEngine() {
return new ScriptEngineManager().getEngineByExtension(FilenameUtils.getExtension(name));
String ext = FilenameUtils.getExtension(name);
if ("js".equalsIgnoreCase(ext)) {
return JsEngineFactory.createJsEngine();
}
return new ScriptEngineManager().getEngineByExtension(ext);
}

/**
Expand Down
17 changes: 14 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -744,9 +744,20 @@
<version>10.0.2.0</version>
</dependency>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>15.7</version>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<version>25.0.2</version>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js-community</artifactId>
<version>25.0.2</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>25.0.2</version>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class ConfiguredLanguage {

private static final String[][] data = {
{ "ECMAScript", SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT, "Javascript",
"com.sun.script.javascript.RhinoScriptEngineFactory", "js" },
"com.oracle.truffle.js.scriptengine.GraalJSScriptEngineFactory", "js" },
{ "ruby", SyntaxConstants.SYNTAX_STYLE_RUBY, "Ruby", "com.sun.script.jruby.JRubyScriptEngineFactory", "rb" },
{ "groovy", SyntaxConstants.SYNTAX_STYLE_GROOVY, "Groovy",
"org.codehaus.groovy.jsr223.GroovyScriptEngineFactory", "groovy" }
Expand Down
15 changes: 13 additions & 2 deletions tools/agent_debugger_pkg/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,19 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js-community</artifactId>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
Expand Down
32 changes: 31 additions & 1 deletion tools/script_engine/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,37 @@
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
</dependency>

<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js-community</artifactId>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.intuit.tank</groupId>
<artifactId>api</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.intuit.tank.tools.script;

import com.oracle.truffle.js.scriptengine.GraalJSScriptEngine;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.HostAccess;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.Set;

/**
* Factory for obtaining a JavaScript {@link ScriptEngine}.
*
* <p>When GraalVM JS is on the classpath a cached, thread-local engine is returned
* with host access restricted to Tank packages that scripts legitimately need.
* Falls back to whatever JSR-223 "js" engine the JVM provides.
*/
public final class JsEngineFactory {

/**
* Package prefixes that user-authored scripts are allowed to access via
* {@code Java.type()} / {@code importPackage()}. Anything outside this
* list is blocked to prevent arbitrary class access (e.g. Runtime, ProcessBuilder).
*/
private static final Set<String> ALLOWED_PACKAGE_PREFIXES = Set.of(
"com.intuit.tank.script.models.",
"java.util."
);

private static final boolean GRAALVM_AVAILABLE;

static {
boolean available;
try {
Class.forName("com.oracle.truffle.js.scriptengine.GraalJSScriptEngine");
available = true;
} catch (ClassNotFoundException e) {
available = false;
}
GRAALVM_AVAILABLE = available;
}

private JsEngineFactory() {}

static boolean isAllowedClass(String className) {
for (String prefix : ALLOWED_PACKAGE_PREFIXES) {
if (className.startsWith(prefix)) {
return true;
}
}
return false;
}

/**
* @return a JS {@link ScriptEngine} configured for restricted host access.
* A new engine is created per call because GraalVM contexts cannot
* be safely reused after script evaluation. Engine creation is fast
* once the GraalVM runtime is warmed up.
*/
public static ScriptEngine createJsEngine() {
if (GRAALVM_AVAILABLE) {
return GraalJSScriptEngine.create(null,
Context.newBuilder("js")
.allowExperimentalOptions(true)
.allowHostAccess(HostAccess.ALL)
.allowHostClassLookup(JsEngineFactory::isAllowedClass)
.option("js.ecmascript-version", "2025")
.option("js.nashorn-compat", "true"));
}
// GraalVM not on classpath — fall back to whatever JSR-223 provides
return new ScriptEngineManager().getEngineByExtension("js");
}
}
Loading
Loading