【问题标题】:How to call java file from different directory using nodejs child process如何使用nodejs子进程从不同目录调用java文件
【发布时间】:2022-01-28 13:20:12
【问题描述】:

我正在尝试从不同的目录运行 java 类文件。但是,它总是给出错误“Could not find or load main class {dirpath}

我的项目目录如下:

  - NodeProject
    - code
      - Main.java
      - javaClasses
    - index.js

“code”文件夹包含 java src 文件,我将其作为候选人/用户的输入并将其保存为 filename.java 和文件夹“javaClasses”,其中应包含 .class 文件编译后。
index.js 是我通过 npm start

运行的入口点

我的 index.js 代码如下:

const spawnSync = require("child_process").spawnSync;
const { exec } = require("child_process")
const path = require('path');


let filepath = path.join(__dirname, "code", "Main.java");
let dirpath = path.join(__dirname, "code", "javaClasses");
let folderPath = path.join(__dirname, "code");

const run = async (command, args) => {
    let options = "";


    let output = spawnSync("javac", ["-d", dirpath, filepath]); /// creates Main.class file in javaClasses folder

    exec(`${command} "${args}" | java -cp ${dirpath} Main`, (error, stdout, stderr) =>{
      if (error) {
          console.error(`exec error: ${error}`);
          return;
        }
        console.log(`stdout: ${stdout}`);
        console.error(`stderr: ${stderr}`);
      });

    
    
    
}

let s ="22"
run("printf", [s]);

.class 文件编译成功,exec 命令报错。
我尝试将 dirpath 替换为实际 src 文件所在的 folderpath,但无济于事。
我在某个地方看到了尝试 cd {path} & java Main 但它仍然不起作用并给出相同的错误。

另外,我的 src 文件没有像 package code 那样的任何包导入,因为我从用户输入中获取了整个 src 文件。

任何帮助将不胜感激!

【问题讨论】:

    标签: java node.js classpath child-process spawn


    【解决方案1】:

    我不确定我是否正确理解了您的问题,但我会尝试一下。

    如果 Main.java 的内容是这样的:

    public class Main {
        public static void main(String[] a) {
            System.out.println("Hello World");
        }
     }
    

    使用您提供的代码运行它没有任何问题。

    如果我将 Main.java 修改为如下所示,问题就开始了:

    public class Main {
        public static void main(String[] a) {
            Echoer e = new Echoer();
            e.setReq("Hello world!");
            System.out.println(e.getRes());
        }
     }
    

    Echoer.java:

    public class Echoer {
        private String req = null;
        private String res = null;
        public void setReq(String r) {
           req = new String(r);
           char[] a = r.toCharArray();
           int n = a.length;
           for (int i=0; i<n/2; i++) {
              char t = a[i];
              a[i] = a[n-1-i];
              a[n-i-1] = t;
           }
           res = new String(a);
        }
        public String getRes() {
           return res;
        }
     }
    

    我确实收到错误“无法找到或加载主类 Main”,它应该等于您提供的消息,因为 dirpath 设置为

    let filepath = path.join(__dirname, "code", "Main.java");
    

    我假设您想调用 Main.java 中的一些方法,这些方法在另一个 Java 文件中定义。为此,我们需要告诉 Java 编译器编译所有存在的 Java 文件。我将 index.js 文件修改为如下所示

    const spawnSync = require("child_process").spawnSync;
    const { exec } = require("child_process")
    const path = require('path');
    
    
    let filepath = path.join(__dirname, "code", "*.java");
    let dirpath = path.join(__dirname, "code", "javaClasses");
    let folderPath = path.join(__dirname, "code");
    
    const run = async (command, args) => {
    
    
        let options = "";
    
    
        exec(`javac -d ${dirpath} ${filepath}`, (error, stdout, stderr) =>{
            if (error) {
                console.error(`exec error: ${error}`);
                return;
              }
              console.log(`stdout: ${stdout}`);
              console.error(`stderr: ${stderr}`);
              exec(`${command} "${args}" | java -cp ${dirpath} Main`, (error, stdout, stderr) =>{
                if (error) {
                    console.error(`exec error: ${error}`);
                    return;
                  }
                  console.log(`stdout: ${stdout}`);
                  console.error(`stderr: ${stderr}`);
                });
            });
    }
    
    let s ="22"
    run("printf", [s]);
    

    现在可以使用任意数量的 .java 文件。

    注意 1:我确实在每次运行后删除了 .class 文件

    注意 2:我没有让它与 spawnSync 一起使用

    【讨论】:

    • 您好!谢谢您的回答。实际上,即使对于像“Hello World”这样的简单打印语句,我的代码也不起作用。它给出了相同的错误无法找到或加载主类用户/../NodeProject/code/javaClasses。我尝试了您的解决方案,但现在它给出了错误 command failed: javac -d {dirpath} {filepath}, error: invalid flag {dirpath}。我实际上在做什么,我只需要编译通过文件名控制的特定文件,并且 java src 文件不会从任何其他类导入,但它将包含扫描仪/缓冲区读取器方法来接收用户输入。因此我使用的是“printf”。
    • 这看起来很奇怪,您的代码对我有用,首先尝试使用简单的“Hello World”Java 文件。当您在终端中手动执行此操作时是否有效?如果不是,我相信问题出在您的环境或 Java 文件中,而不是 JavaScript 代码。我有一个问题,我的 CodeEditor 有时只会将“包代码”添加到我的 Java 文件中,然后就会发生错误。也许你有同样的问题?我的“npm start”是一个简单的“node index.js”。节点版本:14.18.1
    • 是的,即使我不明白为什么即使是简单的“Hello World”也不起作用。我尝试通过首先进入代码目录从终端手动运行它,它运行良好。只是无法使其与我的代码一起使用。
    • 这就是我解决这个问题的方法,我将我的 exec() 命令更改为 exec(${command} ${args} | java Main, {cwd : dirpath} , (error, stdout, stdin) =&gt; {console.log(stdout)}) 现在它按预期工作。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    相关资源
    最近更新 更多