Javet icon indicating copy to clipboard operation
Javet copied to clipboard

The Noderuntime update the current directory of a running app

Open BobBlandin opened this issue 2 years ago • 1 comments

I write this wrapper for my application to use the capability to running a node script, with the version v3.0.0

public static String runNodeScript(String scriptPath, String mainFunctionName) throws IOException {
		ApplicationProperties bean = SpringContext.getBean(ApplicationProperties.class);
		String nodeScriptsPath = bean.getNodeScriptsPath();

		try (JavetEnginePool<NodeRuntime> javetEnginePool = new JavetEnginePool<NodeRuntime>()) {
			javetEnginePool.getConfig().setJSRuntimeType(JSRuntimeType.Node);

			try (IJavetEngine<NodeRuntime> iJavetEngine = javetEnginePool.getEngine()) {
				NodeRuntime nodeRuntime = iJavetEngine.getV8Runtime();
				NodeModuleProcess nodeModule = nodeRuntime.getNodeModule(NodeModuleProcess.class);
				
				nodeRuntime.getExecutor(new File(nodeScriptsPath + "/" + scriptPath).getAbsoluteFile()).executeVoid();

				return nodeRuntime.getGlobalObject().invokeString(mainFunctionName);
			}
		} catch (JavetException e) {
			logger.error("Error while running node script", e);
			throw new IOException("Error while running node script", e);
		}
	}

The problem, when I ran this method, all code like this does not work anymore (it's trhow an error like "path is not found...")

File testFile = new File("test.txt");
testFile.createNewFile();

I found the cause, that in the library (from my code the "nodeRuntime.getExecutor") there is a "chdir" command executed, and the working directory is never back again. image

I have a simple workaround, it's to get the current directory before executing "getExecutor" and restore it after.

public static String runNodeScript(String scriptPath, String mainFunctionName) throws IOException {
		ApplicationProperties bean = SpringContext.getBean(ApplicationProperties.class);
		String nodeScriptsPath = bean.getNodeScriptsPath();

		try (JavetEnginePool<NodeRuntime> javetEnginePool = new JavetEnginePool<NodeRuntime>()) {
			javetEnginePool.getConfig().setJSRuntimeType(JSRuntimeType.Node);

			try (IJavetEngine<NodeRuntime> iJavetEngine = javetEnginePool.getEngine()) {
				NodeRuntime nodeRuntime = iJavetEngine.getV8Runtime();
				NodeModuleProcess nodeModule = nodeRuntime.getNodeModule(NodeModuleProcess.class);
				File currentWorkingDirectory = nodeModule.getWorkingDirectory();
				nodeRuntime.getExecutor(new File(nodeScriptsPath + "/" + scriptPath).getAbsoluteFile()).executeVoid();

				String result = nodeRuntime.getGlobalObject().invokeString(mainFunctionName);

				nodeModule.setWorkingDirectory(currentWorkingDirectory);

				return result;
			}
		} catch (JavetException e) {
			logger.error("Error while running node script", e);
			throw new IOException("Error while running node script", e);
		}
	}

BobBlandin avatar Oct 30 '23 12:10 BobBlandin

That's how Node.js works. It needs the working directory to be the one.

In your case, you may do whatever you want to do with the working directory afterwards.

caoccao avatar Oct 30 '23 14:10 caoccao