diff --git a/pom.xml b/pom.xml
index 122daf6..7033b0e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
pw.yumc
MiaoScript
- 0.22.0
+ 0.22.3
502647092
@@ -50,6 +50,7 @@
DEV
+ §622-05-25 §afeat: 兼容 1.7.10-1.18.2 版本;
§622-05-21 §afeat: 优化 框架加载逻辑;
§622-05-20 §afeat: 调整 require 主包逻辑;
§622-04-09 §afeat: 优化 引擎初始化逻辑;
@@ -196,7 +197,8 @@
org.projectlombok
lombok
- 1.18.22
+ 1.18.24
+ compile
org.kamranzafar
@@ -219,6 +221,7 @@
net.md-5
bungeecord-api
1.16-R0.4
+ compile
cn.nukkit
@@ -229,7 +232,7 @@
org.springframework
spring-websocket
- 5.3.18
+ 5.3.19
compile
@@ -238,10 +241,5 @@
9.0.35
compile
-
- com.zaxxer
- HikariCP
- 4.0.3
-
\ No newline at end of file
diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBukkit.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBukkit.java
index 7138be8..f6f0a20 100644
--- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBukkit.java
+++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBukkit.java
@@ -2,6 +2,7 @@ package pw.yumc.MiaoScript;
import lombok.SneakyThrows;
import org.bukkit.plugin.java.JavaPlugin;
+import pw.yumc.MiaoScript.api.MiaoScriptAPI;
import pw.yumc.MiaoScript.api.ScriptEngine;
/**
@@ -17,7 +18,7 @@ public class MiaoScriptBukkit extends JavaPlugin {
public MiaoScriptBukkit() {
ClassLoader origin = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClassLoader());
- engine = new ScriptEngine(getDataFolder().getCanonicalPath(), getLogger(), this);
+ engine = MiaoScriptAPI.createEngine(getDataFolder().getCanonicalPath(), getLogger(), this);
Thread.currentThread().setContextClassLoader(origin);
engine.loadEngine();
}
diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java
index 84579c3..15a9ed0 100644
--- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java
+++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java
@@ -2,6 +2,7 @@ package pw.yumc.MiaoScript;
import lombok.SneakyThrows;
import net.md_5.bungee.api.plugin.Plugin;
+import pw.yumc.MiaoScript.api.MiaoScriptAPI;
import pw.yumc.MiaoScript.api.ScriptEngine;
/**
@@ -16,7 +17,7 @@ public class MiaoScriptBungee extends Plugin {
@SneakyThrows
public MiaoScriptBungee() {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
- engine = new ScriptEngine(getDataFolder().getCanonicalPath(), getLogger(), this);
+ engine = MiaoScriptAPI.createEngine(getDataFolder().getCanonicalPath(), getLogger(), this);
engine.loadEngine();
}
diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java
index 6aa658c..97273f6 100644
--- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java
+++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java
@@ -2,6 +2,7 @@ package pw.yumc.MiaoScript;
import cn.nukkit.plugin.PluginBase;
import lombok.SneakyThrows;
+import pw.yumc.MiaoScript.api.MiaoScriptAPI;
import pw.yumc.MiaoScript.api.ScriptEngine;
/**
@@ -13,7 +14,7 @@ public class MiaoScriptNukkit extends PluginBase {
@SneakyThrows
public MiaoScriptNukkit() {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
- engine = new ScriptEngine(getDataFolder().getCanonicalPath(), super.getLogger(), this);
+ engine = MiaoScriptAPI.createEngine(getDataFolder().getCanonicalPath(), super.getLogger(), this);
engine.loadEngine();
}
diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java
index 1ba2ae4..7808d2a 100644
--- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java
+++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java
@@ -6,8 +6,8 @@ import org.slf4j.Logger;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.GameReloadEvent;
+import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
import org.spongepowered.api.event.game.state.GameStartedServerEvent;
-import org.spongepowered.api.event.game.state.GameStartingServerEvent;
import org.spongepowered.api.event.game.state.GameStoppingServerEvent;
import org.spongepowered.api.plugin.Plugin;
import pw.yumc.MiaoScript.api.MiaoScriptAPI;
@@ -33,14 +33,14 @@ public class MiaoScriptSponge {
@Listener
@SneakyThrows
- public void onStarting(GameStartingServerEvent event) {
- engine = new ScriptEngine(pluginConfigDir.getCanonicalPath(), logger, this);
+ public void onPreInitialization(GamePreInitializationEvent event) {
+ engine = MiaoScriptAPI.createEngine(pluginConfigDir.getCanonicalPath(), logger, this);
engine.loadEngine();
}
@Listener
@SneakyThrows
- public void onStart(GameStartedServerEvent event) {
+ public void onStarted(GameStartedServerEvent event) {
engine.enableEngine();
}
@@ -55,7 +55,7 @@ public class MiaoScriptSponge {
@SneakyThrows
public void reload(GameReloadEvent event) {
engine.disableEngine();
- engine = new ScriptEngine(pluginConfigDir.getCanonicalPath(), logger, this);
+ System.gc();
engine.loadEngine();
engine.enableEngine();
}
diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java
index 4f9abf3..64eb4ed 100644
--- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java
+++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java
@@ -6,6 +6,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+import pw.yumc.MiaoScript.api.MiaoScriptAPI;
import pw.yumc.MiaoScript.api.ScriptEngine;
import java.io.File;
@@ -16,7 +17,7 @@ public class MiaoScriptSpring {
@Bean
@SneakyThrows
public ScriptEngine buildScriptEngine(ApplicationContext applicationContext) {
- return new ScriptEngine(new File("MiaoScript").getCanonicalPath(), log, applicationContext);
+ return MiaoScriptAPI.createEngine(new File("MiaoScript").getCanonicalPath(), log, applicationContext);
}
@Bean
diff --git a/src/main/java/pw/yumc/MiaoScript/api/Base.java b/src/main/java/pw/yumc/MiaoScript/api/Base.java
index 3e78676..23c5f29 100644
--- a/src/main/java/pw/yumc/MiaoScript/api/Base.java
+++ b/src/main/java/pw/yumc/MiaoScript/api/Base.java
@@ -25,7 +25,15 @@ public class Base {
}
public Class> getClass(String name) throws ClassNotFoundException {
- return Class.forName(name);
+ try {
+ return Class.forName(name);
+ } catch (Throwable ignored) {
+ }
+ try {
+ return Class.forName(name, true, instance.getClass().getClassLoader());
+ } catch (Throwable ex) {
+ return Class.forName(name, true, instance.getClass().getClassLoader().getParent());
+ }
}
public Object getInstance() {
@@ -44,6 +52,14 @@ public class Base {
return MiaoScriptAPI.loadMavenDepend(groupId, artifactId, version);
}
+ public File[] loadMavenDepend(String groupId, String artifactId, String version, ClassLoader classLoader) {
+ return MiaoScriptAPI.loadMavenDepend(groupId, artifactId, version, classLoader);
+ }
+
+ public File[] parentLoadMavenDepend(String groupId, String artifactId, String version) {
+ return MiaoScriptAPI.parentLoadMavenDepend(groupId, artifactId, version);
+ }
+
public String read(String path) throws IOException {
return read(Paths.get(path));
}
diff --git a/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java b/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java
index 3bd0936..2eb3ccf 100644
--- a/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java
+++ b/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java
@@ -14,6 +14,11 @@ public class MiaoScriptAPI {
private static ScriptEngine scriptEngine;
private static PluginManager pluginManager;
+ public static ScriptEngine createEngine(String root, Object logger, Object instance) {
+ MiaoScriptAPI.scriptEngine = new ScriptEngine(root, logger, instance);
+ return MiaoScriptAPI.scriptEngine;
+ }
+
public static String getRoot() {
return root;
}
@@ -45,4 +50,18 @@ public class MiaoScriptAPI {
}
return MavenDependLoader.load(MiaoScriptAPI.libPath, groupId, artifactId, version);
}
+
+ public static File[] loadMavenDepend(String groupId, String artifactId, String version, ClassLoader classLoader) {
+ if (root == null || scriptEngine == null) {
+ throw new IllegalStateException("root can't be null before loadMavenDepend.");
+ }
+ return MavenDependLoader.load(MiaoScriptAPI.libPath, groupId, artifactId, version, classLoader);
+ }
+
+ public static File[] parentLoadMavenDepend(String groupId, String artifactId, String version) {
+ if (root == null || scriptEngine == null) {
+ throw new IllegalStateException("root can't be null before loadMavenDepend.");
+ }
+ return MavenDependLoader.parentLoad(MiaoScriptAPI.libPath, groupId, artifactId, version);
+ }
}
diff --git a/src/main/java/pw/yumc/MiaoScript/api/ScriptEngine.java b/src/main/java/pw/yumc/MiaoScript/api/ScriptEngine.java
index f296156..7107877 100644
--- a/src/main/java/pw/yumc/MiaoScript/api/ScriptEngine.java
+++ b/src/main/java/pw/yumc/MiaoScript/api/ScriptEngine.java
@@ -20,7 +20,7 @@ public class ScriptEngine {
private MiaoScriptEngine engine;
private Object future;
- public ScriptEngine(String root, Object logger, Object instance) {
+ ScriptEngine(String root, Object logger, Object instance) {
this.loader = Thread.currentThread().getContextClassLoader();
this.root = root;
this.logger = logger;
@@ -32,7 +32,7 @@ public class ScriptEngine {
public void createEngine() {
synchronized (logger) {
if (this.engine == null) {
- this.engine = new MiaoScriptEngine("nashorn", root);
+ this.engine = new MiaoScriptEngine(root);
this.engine.put("base", this.base);
this.engine.put("ScriptEngineContextHolder", this);
}
diff --git a/src/main/java/pw/yumc/MiaoScript/api/loader/JarLoader.java b/src/main/java/pw/yumc/MiaoScript/api/loader/JarLoader.java
index 7e68346..6c054ed 100644
--- a/src/main/java/pw/yumc/MiaoScript/api/loader/JarLoader.java
+++ b/src/main/java/pw/yumc/MiaoScript/api/loader/JarLoader.java
@@ -10,6 +10,9 @@ import java.lang.reflect.Method;
import java.net.URL;
public class JarLoader {
+ private static sun.misc.Unsafe unsafe;
+ private static long offset;
+ private static Object parentUcp;
private static Object ucp;
private static MethodHandle addURLMethodHandle;
@@ -23,12 +26,26 @@ public class JarLoader {
return file;
}
+ @SneakyThrows
+ public static File parentLoad(File file) {
+ if (parentUcp == null)
+ throw new IllegalStateException("parentUcp is null.");
+ addURLMethodHandle.invoke(parentUcp, file.toURI().toURL());
+ return file;
+ }
+
+ @SneakyThrows
+ public static File load(File file, ClassLoader loader) {
+ addURLMethodHandle.invoke(unsafe.getObject(loader, offset), file.toURI().toURL());
+ return file;
+ }
+
private static void initReflect() {
try {
- ClassLoader loader = ClassLoader.getSystemClassLoader();
+ ClassLoader loader = JarLoader.class.getClassLoader();
Field theUnsafe = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
- sun.misc.Unsafe unsafe = (sun.misc.Unsafe) theUnsafe.get(null);
+ unsafe = (sun.misc.Unsafe) theUnsafe.get(null);
Field field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
MethodHandles.Lookup lookup = (MethodHandles.Lookup) unsafe.getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));
Field ucpField;
@@ -37,11 +54,13 @@ public class JarLoader {
} catch (NoSuchFieldException e) {
ucpField = loader.getClass().getSuperclass().getDeclaredField("ucp");
}
- long offset = unsafe.objectFieldOffset(ucpField);
+ offset = unsafe.objectFieldOffset(ucpField);
ucp = unsafe.getObject(loader, offset);
Method method = ucp.getClass().getDeclaredMethod("addURL", URL.class);
addURLMethodHandle = lookup.unreflect(method);
- } catch (Exception e) {
+ if (loader.getParent() != null)
+ parentUcp = unsafe.getObject(loader.getParent(), offset);
+ } catch (Throwable e) {
throw new RuntimeException(e);
}
}
diff --git a/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java b/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java
index f4fcce8..5215564 100644
--- a/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java
+++ b/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java
@@ -14,7 +14,7 @@ import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
public class MavenDependLoader {
- private static final String MavenRepo = "https://maven.aliyun.com/repository/public";
+ public static final String MavenRepo = "https://maven.aliyun.com/repository/public";
public static File[] load(String libPath, String groupId, String artifactId, String version) {
return new File[]{
@@ -23,6 +23,20 @@ public class MavenDependLoader {
};
}
+ public static File[] parentLoad(String libPath, String groupId, String artifactId, String version) {
+ return new File[]{
+ downloadAndCheckSha1(libPath, groupId, artifactId, version, "pom"),
+ JarLoader.parentLoad(downloadAndCheckSha1(libPath, groupId, artifactId, version, "jar"))
+ };
+ }
+
+ public static File[] load(String libPath, String groupId, String artifactId, String version, ClassLoader loader) {
+ return new File[]{
+ downloadAndCheckSha1(libPath, groupId, artifactId, version, "pom"),
+ JarLoader.load(downloadAndCheckSha1(libPath, groupId, artifactId, version, "jar"), loader)
+ };
+ }
+
@SneakyThrows
public static File downloadAndCheckSha1(String libPath, String groupId, String artifactId, String version, String ext) {
File sha1 = getMavenFile(libPath, groupId, artifactId, version, ext + ".sha1");
diff --git a/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java b/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java
index 8193f7d..65a7c6c 100644
--- a/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java
+++ b/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java
@@ -5,12 +5,12 @@ import lombok.val;
import pw.yumc.MiaoScript.api.loader.JarLoader;
import pw.yumc.MiaoScript.api.loader.MavenDependLoader;
-import javax.script.ScriptEngine;
import javax.script.*;
import java.io.File;
import java.io.Reader;
import java.lang.reflect.Method;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.List;
/**
* 喵式脚本引擎
@@ -19,111 +19,143 @@ import java.util.HashMap;
* @since 2016年8月29日 上午7:51:43
*/
public class MiaoScriptEngine implements ScriptEngine, Invocable {
- private static MiaoScriptEngine DEFAULT;
- private static final ScriptEngineManager manager;
-
private ScriptEngine engine;
- static {
- manager = new ScriptEngineManager(ClassLoader.getSystemClassLoader());
- }
-
- public static void setBindings(Bindings bindings) {
- manager.setBindings(bindings);
- }
-
- public static Bindings getBindings() {
- return manager.getBindings();
- }
-
- public MiaoScriptEngine() {
- this("js");
- }
-
- public MiaoScriptEngine(final String engineType) {
- this(manager, engineType, null);
- }
-
- public MiaoScriptEngine(ScriptEngineManager engineManager) {
- this(engineManager, "js", null);
- }
-
- public MiaoScriptEngine(final String engineType, String engineRoot) {
- this(manager, engineType, engineRoot);
- }
-
- public MiaoScriptEngine(ScriptEngineManager engineManager, final String engineType, String engineRoot) {
- // JDK11 Polyfill 存在类效验问题 直接用OpenJDK的Nashorn
- if (System.getProperty("java.version").startsWith("11.") && engineRoot != null) {
- this.loadNetworkNashorn(engineRoot);
- if (engine == null)
- throw new UnsupportedOperationException("当前环境 JDK11 不支持 Nashorn 脚本类型!");
- return;
+ public MiaoScriptEngine(String engineRoot) {
+ if (new File(engineRoot, "debug").exists()) {
+ System.setProperty("nashorn.debug", "true");
}
- try {
- engine = engineManager.getEngineByName(engineType);
- } catch (final NullPointerException ignored) {
- }
- if (engine == null) {
- val extDirs = System.getProperty("java.ext.dirs");
- if (extDirs != null) {
- this.loadLocalNashorn(extDirs, engineType);
- } else if (engineRoot != null) {
- this.loadNetworkNashorn(engineRoot);
- }
+ if (getJavaVersion() > 15) {
+ this.loadGraalJS(engineRoot);
+ } else {
+ this.loadNashorn(engineRoot);
}
if (engine == null)
- throw new UnsupportedOperationException("当前环境不支持 " + engineType + " 脚本类型!");
+ throw new UnsupportedOperationException("当前环境不支持 Nashorn 或 GraalJS 脚本引擎.");
}
- private void loadLocalNashorn(String extDirs, String engineType) {
+ private void loadGraalJS(String engineRoot) {
+ this.engine = this.parentLoadNetworkNashorn(engineRoot);
+ if (this.engine == null) {
+ this.engine = this.loadNetworkGraalJS(engineRoot);
+ }
+ }
+
+ private void loadNashorn(String engineRoot) {
+ try {
+ this.createEngineByName();
+ } catch (final Throwable ex) {
+ ex.printStackTrace();
+ }
+ try {
+ val extDirs = System.getProperty("java.ext.dirs");
+ if (this.engine == null && extDirs != null) {
+ this.engine = this.loadLocalNashorn(extDirs);
+ }
+ } catch (final Throwable ex) {
+ ex.printStackTrace();
+ }
+ try {
+ if (this.engine == null && engineRoot != null) {
+ this.engine = this.loadNetworkNashorn(engineRoot);
+ }
+ } catch (final Throwable ex) {
+ ex.printStackTrace();
+ }
+ if (this.engine == null)
+ throw new UnsupportedOperationException("当前环境不支持 Nashorn 脚本引擎.");
+ }
+
+ private int getJavaVersion() {
+ String version = System.getProperty("java.version");
+ if (version.startsWith("1.")) {
+ version = version.substring(2, 3);
+ } else {
+ int dot = version.indexOf(".");
+ if (dot != -1) {
+ version = version.substring(0, dot);
+ }
+ }
+ return Integer.parseInt(version);
+ }
+
+ private ScriptEngine loadLocalNashorn(String extDirs) {
val dirs = extDirs.split(File.pathSeparator);
for (String dir : dirs) {
File nashorn = new File(dir, "nashorn.jar");
if (nashorn.exists()) {
JarLoader.load(nashorn);
- this.createEngineByName(engineType);
+ return this.createEngineByName();
}
}
+ return null;
}
@SneakyThrows
- private void loadNetworkNashorn(String engineRoot) {
+ private ScriptEngine loadNetworkNashorn(String engineRoot) {
File libRootFile = new File(engineRoot, "libs");
libRootFile.mkdirs();
String libRoot = libRootFile.getCanonicalPath();
- MavenDependLoader.load(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.3");
- MavenDependLoader.load(libRoot, "org.ow2.asm", "asm", "9.2");
- MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-commons", "9.2");
- MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-tree", "9.2");
- MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-util", "9.2");
- Class> NashornScriptEngineFactory = Class.forName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory");
- Method getScriptEngine = NashornScriptEngineFactory.getMethod("getScriptEngine");
- Object factory = NashornScriptEngineFactory.newInstance();
- engine = (ScriptEngine) getScriptEngine.invoke(factory);
+ MavenDependLoader.load(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.4");
+ MavenDependLoader.load(libRoot, "org.ow2.asm", "asm", "9.3");
+ MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-commons", "9.3");
+ MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-tree", "9.3");
+ MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-util", "9.3");
+ return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false);
}
- private void createEngineByName(String engineType) {
- try {
- engine = new ScriptEngineManager(Thread.currentThread().getContextClassLoader()).getEngineByName(engineType);
- } catch (NullPointerException ignored) {
+ @SneakyThrows
+ private ScriptEngine parentLoadNetworkNashorn(String engineRoot) {
+ File libRootFile = new File(engineRoot, "libs");
+ libRootFile.mkdirs();
+ String libRoot = libRootFile.getCanonicalPath();
+ MavenDependLoader.parentLoad(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.4");
+ MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm", "9.3");
+ MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-commons", "9.3");
+ MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-tree", "9.3");
+ MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-util", "9.3");
+ return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false);
+ }
+
+ @SneakyThrows
+ private ScriptEngine loadNetworkGraalJS(String engineRoot) {
+ File libRootFile = new File(engineRoot, "libs");
+ libRootFile.mkdirs();
+ String libRoot = libRootFile.getCanonicalPath();
+ MavenDependLoader.load(libRoot, "org.graalvm.js", "js", "22.1.0.1");
+ MavenDependLoader.load(libRoot, "org.graalvm.js", "js-scriptengine", "22.1.0.1");
+ MavenDependLoader.load(libRoot, "org.graalvm.regex", "regex", "22.1.0.1");
+ MavenDependLoader.load(libRoot, "org.graalvm.sdk", "graal-sdk", "22.1.0.1");
+ MavenDependLoader.load(libRoot, "org.graalvm.truffle", "truffle-api", "22.1.0.1");
+ return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false);
+ }
+
+ @SneakyThrows
+ private ScriptEngine createEngineByName() {
+ return createEngineByFactoryClassName("jdk.nashorn.api.scripting.NashornScriptEngineFactory", true);
+ }
+
+ @SneakyThrows
+ private ScriptEngine createEngineByFactoryClassName(String factoryClassName, boolean jdk) {
+ Class> NashornScriptEngineFactory = Class.forName(factoryClassName);
+ Method getScriptEngine = NashornScriptEngineFactory.getMethod("getScriptEngine", String[].class);
+ Object factory = NashornScriptEngineFactory.newInstance();
+ List engineArgs = new ArrayList<>();
+ engineArgs.add("--language=es5");
+ engineArgs.add("--optimistic-types=false");
+ if (getJavaVersion() >= 11 && jdk) {
+ engineArgs.add("--no-deprecation-warning");
}
+ return (ScriptEngine) getScriptEngine.invoke(factory, (Object) engineArgs.toArray(new String[]{}));
}
public ScriptEngine getEngine() {
return this.engine;
}
- public static MiaoScriptEngine getDefault() {
- if (DEFAULT == null) {
- DEFAULT = new MiaoScriptEngine();
- }
- return DEFAULT;
- }
-
@Override
public Bindings createBindings() {
- return new SimpleBindings(new HashMap<>(engine.getBindings(ScriptContext.GLOBAL_SCOPE)));
+ return engine.createBindings();
}
@Override
@@ -177,13 +209,13 @@ public class MiaoScriptEngine implements ScriptEngine, Invocable {
}
@Override
- public T getInterface(final Class clasz) {
- return ((Invocable) engine).getInterface(clasz);
+ public T getInterface(final Class cls) {
+ return ((Invocable) engine).getInterface(cls);
}
@Override
- public T getInterface(final Object thiz, final Class clasz) {
- return ((Invocable) engine).getInterface(thiz, clasz);
+ public T getInterface(final Object thiz, final Class cls) {
+ return ((Invocable) engine).getInterface(thiz, cls);
}
@Override
diff --git a/src/main/resources/core/require.js b/src/main/resources/core/require.js
index 75a3b2b..08004c6 100644
--- a/src/main/resources/core/require.js
+++ b/src/main/resources/core/require.js
@@ -28,9 +28,9 @@
// @ts-check
(
/**
- * @param {string} parent
+ * @param {string} root
*/
- function (parent) {
+ function (root) {
'use strict'
var System = Java.type('java.lang.System')
@@ -181,7 +181,7 @@
try {
var json = JSON.parse(base.read(_package))
if (json.main) {
- return resolveAsFile(json.main, dir)
+ return resolveAsFile(json.main, dir) || resolveAsFile('index.js', new File(dir, json.main))
}
} catch (error) {
throw __error('resolveAsDirectory ' + dir + ' package.json error ' + error)
@@ -239,18 +239,26 @@
if (!loader) {
throw __error('Unsupported module ' + filename + '. require loader not found.')
}
- console.trace('Loading module', name + '(' + id + ')', 'Optional', JSON.stringify(optional))
+ /**
+ * @type any
+ */
var module = {
id: id,
name: name,
ext: ext,
+ parent: optional.parent,
exports: {},
loaded: false,
loader: loader,
- require: getRequire(file.parentFile, id),
- __dirname: file.parentFile,
- __filename: file
+ path: _absolute(file.parentFile),
+ filename: _absolute(file),
+ children: []
}
+ module.require = getRequire(module)
+ if (module.parent && module.parent.children) {
+ module.parent.children.push(module)
+ }
+ console.trace('Loading module', name + '(' + id + ')', 'Optional', JSON.stringify(__assign(optional, { parent: undefined })))
cacheModules[id] = module
return loader(module, file, __assign(optional, { id: id }))
}
@@ -288,7 +296,7 @@
name: optional.id
})
compiledWrapper.apply(module.exports, [
- module, module.exports, module.require, module.__dirname, module.__filename
+ module, module.exports, module.require, module.path, module.filename
])
module.loaded = true
if (optional.afterCompile) {
@@ -467,7 +475,7 @@
* 检查缓存模块
*/
function checkCacheModule(optional) {
- return optional.local ? cacheModuleIds[optional.parentId] && cacheModuleIds[optional.parentId][optional.path] : cacheModuleIds[optional.path]
+ return optional.local ? cacheModuleIds[optional.parent.id] && cacheModuleIds[optional.parent.id][optional.path] : cacheModuleIds[optional.path]
}
/**
@@ -511,11 +519,11 @@
*/
function setCacheModule(file, optional) {
if (optional.local) {
- var parent = cacheModuleIds[optional.parentId]
+ var parent = cacheModuleIds[optional.parent.id]
if (!parent) {
- cacheModuleIds[optional.parentId] = {}
+ cacheModuleIds[optional.parent.id] = {}
}
- return cacheModuleIds[optional.parentId][optional.path] = _canonical(file)
+ return cacheModuleIds[optional.parent.id][optional.path] = _canonical(file)
}
return cacheModuleIds[optional.path] = _canonical(file)
}
@@ -527,11 +535,10 @@
/**
* 闭包方法
- * @param {string} parent 父目录
- * @param {string} parentId
+ * @param {any} parent 父模块
* @returns {Function}
*/
- function exports(parent, parentId) {
+ function exports(parent) {
/**
* @param {string} path
* @param {any} optional
@@ -540,13 +547,13 @@
if (!path) {
throw __error('require path can\'t be undefined or empty!')
}
- return _require(path, parent, __assign({
+ var optional = __assign({
cache: true,
- parentId: parentId,
parent: parent,
path: path,
local: path.startsWith('.') || path.startsWith('/')
- }, optional)).exports
+ }, optional)
+ return _require(path, parent.path, optional).exports
}
}
@@ -555,9 +562,8 @@
* @param {any} optional 附加选项
*/
function __DynamicResolve__(path, optional) {
- return _canonical(new File(resolve(path, parent, __assign({
+ return _canonical(new File(resolve(path, root, __assign({
cache: true,
- parent: parent,
local: path.startsWith('.') || path.startsWith('/')
}, optional))))
}
@@ -592,14 +598,13 @@
}
/**
- * @param {string} parent
- * @param {string} parentId
+ * @param {any} parent
*/
- function getRequire(parent, parentId) {
+ function getRequire(parent) {
/**
* @type {any} require
*/
- var require = exports(parent, parentId)
+ var require = exports(parent)
require.resolve = __DynamicResolve__
require.clear = __DynamicClear__
require.disable = __DynamicDisable__
@@ -643,8 +648,9 @@
function printRequireInfo() {
console.info('Initialization require module.')
- console.info('ParentDir:', _canonical(parent))
+ console.info('ParentDir:', root)
console.info('Require module env list:')
+ console.info('- JAVA_VERSION: ', System.getProperty("java.version"))
console.info('- MS_NODE_PATH:', MS_NODE_PATH.startsWith(root) ? MS_NODE_PATH.split(root)[1] : MS_NODE_PATH)
console.info('- MS_NODE_REGISTRY:', MS_NODE_REGISTRY)
console.info('- MS_FALLBACK_NODE_REGISTRY:', MS_FALLBACK_NODE_REGISTRY)
@@ -676,7 +682,11 @@
console.warn("无法获取到最新的版本锁定信息 使用默认配置.")
console.warn("InitVersionLock Error:", error)
console.debug(error)
- ModulesVersionLock = { "@babel/standalone": "7.12.18", "crypto-js": "3.3.0" }
+ ModulesVersionLock = {
+ "@babel/standalone": "7.12.18",
+ "crypto-js": "3.3.0",
+ "core-js": "3.19.3"
+ }
}
console.info('Lock module version List:')
for (var key in ModulesVersionLock) {
@@ -731,5 +741,8 @@
initCacheModuleIds()
initVersionLock()
- return initRequireLoader(getRequire(parent, ""))
+ return initRequireLoader(getRequire({
+ id: 'main',
+ path: root
+ }))
})