caoccao/Javet

java.io.File not working

Opened this issue · 11 comments

When using a node instance the java.io.File class doesn't work

its specifically the File.exists() method that doesn't work

Please leave more info for the troubleshooting. OS, CPU arch, source code, etc.

its for a Minecraft plugin

public class Grakkit extends JavaPlugin implements CommandExecutor {

    V8Runtime runtime;
    JavetJVMInterceptor interceptor;
    @Override
    public void onEnable() {
        try {
            saveDefaultConfig();
            reloadConfig();
            String main = getConfig().getString("main", "index.js");
            String mode = getConfig().getString("mode", "js");
            if (mode.equalsIgnoreCase("node")){
                runtime = V8Host.getNodeInstance().createV8Runtime();
            } else {
                runtime = V8Host.getV8Instance().createV8Runtime();
            }
            runtime.setConverter(new JavetProxyConverter());
            interceptor = new JavetJVMInterceptor(runtime);
            interceptor.register(runtime.getGlobalObject());
            runtime.setV8ModuleResolver(new IV8ModuleResolver() {

                private Path DEFAULT = getDataFolder().toPath();
                private Path LAST = getDataFolder().toPath();

                @Override
                public IV8Module resolve(V8Runtime v8Runtime, String file, IV8Module iv8Module) throws JavetException {
                    try {
                        String filename = file.endsWith(".js") ? file : file + ".js";
                        Path f = LAST.resolve(filename);
                        if (Files.exists(f)) {
                            LAST = f.getParent();
                            V8Module module = v8Runtime.getExecutor(Files.lines(f).collect(Collectors.joining("\n"))).setResourceName(f.toFile().getAbsolutePath()).compileV8Module();
                            return module;
                        } else {
                            LAST = DEFAULT;

                            f = LAST.resolve(filename);
                            if (Files.exists(f)) {
                                LAST = f.getParent();
                                V8Module module = v8Runtime.getExecutor(Files.lines(f).collect(Collectors.joining("\n"))).setResourceName(f.toFile().getAbsolutePath()).compileV8Module();
                                return module;
                            }
                            return null;
                        }
                    } catch (Exception e){
                        e.printStackTrace();
                    }
                    return null;
                }
            });
            runtime.allowEval(true);
            runtime.getGlobalObject().set("Class", Class.class);
            runtime.getGlobalObject().set("Logger", getLogger());
            File file = new File(getDataFolder(), main);
            if (!file.exists()){
                file.getParentFile().mkdirs();
                file.createNewFile();
            }
            V8StringExecutor stringExecutor = (V8StringExecutor) runtime.getExecutor(Files.lines(file.toPath()).collect(Collectors.joining("\n")));
            stringExecutor.setModule(true);
            stringExecutor.setResourceName(file.getAbsolutePath());
            stringExecutor.execute();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void onDisable() {
        if (runtime != null){
            try {
                runtime.await();
                interceptor.unregister(runtime.getGlobalObject());
                runtime.close();
                System.gc();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

}
``` when using normal v8 runtime there is no issues but when using node i get this error when trying to use java.io.File 

java.io.IOException: Den angivne sti blev ikke fundet
at java.io.WinNTFileSystem.createFileExclusively(Native Method) ~[?:1.8.0_412-412]
at java.io.File.createTempFile(File.java:2063) ~[?:1.8.0_412-412]
at net.minecraft.server.v1_16_R2.Convertable$ConversionSession.a(Convertable.java:303) ~[spigot.jar:git-Spigot-b5a13e6-0d8350a]
at net.minecraft.server.v1_16_R2.WorldServer.save(WorldServer.java:768) ~[spigot.jar:git-Spigot-b5a13e6-0d8350a]
at net.minecraft.server.v1_16_R2.MinecraftServer.saveChunks(MinecraftServer.java:674) ~[spigot.jar:git-Spigot-b5a13e6-0d8350a]
at net.minecraft.server.v1_16_R2.MinecraftServer.stop(MinecraftServer.java:741) ~[spigot.jar:git-Spigot-b5a13e6-0d8350a]
at net.minecraft.server.v1_16_R2.DedicatedServer.stop(DedicatedServer.java:647) ~[spigot.jar:git-Spigot-b5a13e6-0d8350a]
at net.minecraft.server.v1_16_R2.MinecraftServer.w(MinecraftServer.java:887) ~[spigot.jar:git-Spigot-b5a13e6-0d8350a]
at net.minecraft.server.v1_16_R2.MinecraftServer.lambda$0(MinecraftServer.java:164) ~[spigot.jar:git-Spigot-b5a13e6-0d8350a]

It seems to be a permission issue?

It only happens when using the node runtime, doesn't happen when using v8 runtime

Well, I don't play Minecraft. Here are some ideas for your reference.

  • Create a regular Java app with the same code, deploy that app to the same env to see if things break.
  • Call File API in Java to see if it works.

使用节点实例时,java.io.File 类不起作用

If you write Spigot/Fabric/Forge plugins or mods, you can embed the Rhino engine, otherwise the plugins will be very large, and my suggestion is to use them more widely for embedded apps.

好吧,我不玩 Minecraft。以下是一些想法供您参考。

  • 使用相同的代码创建一个常规的 Java 应用程序,将该应用程序部署到同一个环境,看看是否有问题。
  • 在 Java 中调用 API 以查看它是否有效。File

Pls what happened to the problem that the engine of 3.1.2 does not work, I still can't run, no code has been changed, 3.1.1 is working normally.

after alot of trial and error the issue seems to come from the setResourceName method on the executor

You may workaround it if it causes issues at your end. Please refer to this commit for detail.

It's now surrounded by a try-catch clause so that that error can be omitted and logged.