【问题标题】:error occur when I call execvp to run java当我调用 execvp 运行 java 时发生错误
【发布时间】:2020-12-30 17:09:03
【问题描述】:

我用chdir()切换目录,然后用execvp()执行“java Main”。我确定有 Main.class,但是出了点问题。我想知道为什么。

#include <cstdio>
#include <unistd.h>
using namespace std;
int main(){
    char buf[80];
    getcwd(buf,sizeof(buf));
    printf("current working directory: %s\n", buf);
    chdir("/home/keane/Judge/temp");
    getcwd(buf,sizeof(buf));
    printf("current working directory: %s\n", buf);
    char *array[3];
    array[0] = "java";
    array[1] = "Main";
    array[2] = NULL;
    execvp("java", array);
    return 0;
}

错误是 could not find the main class ,我可以在该目录中运行 java Main

让我抓狂的是我不能使用system("java Main"),而错误是Error: Could not find or load main class Main,而且在我的电脑上就是这样

更新:

#include <unistd.h>
#include <cstdlib>
int main(){
    chdir("/home/keane/Judge/temp");
    system("pwd");
    system("ls");
    system("java Main");
    return 0;
}

控制台的输出是:

/home/keane/Judge/temp
1.out  3.out  5.out   Main.class  stdout_spj.txt
2.out  4.out  ce.txt  Main.java
Error: Could not find or load the main class Main

我的最终解决方案是重新启动计算机并将-cp . 添加到 java 命令。 虽然我不知道为什么是必要的。 谢谢大家!

【问题讨论】:

  • 难道java 不应该得到一个包含Main 类的.jar 文件吗?我不是Java专家,所以如果我不确切知道,请忽略我的无知。但也请把错误信息也放在你的问题中,否则很难诊断出每个人的情况。
  • @πάνταῥεῖ 不,java Main 将运行 main 方法的 Main.class 包含完全限定的类名 Main
  • @AnttiHaapala .jar 或默认取自哪里?
  • @πάνταῥεῖ 没有“默认罐子”......无论如何。 Main.class 需要是该目录中的文件。 javac Main.java; java Main
  • 您也可以尝试添加 Peter 建议的 -cp .,尽管没有类似的方法一直对我有用。

标签: c++ linux system execvp


【解决方案1】:

这在我的系统上按预期工作,也许您需要将 -cp . 添加到您的 java 调用中。

编辑:详细说明:-cp (for classpath) 告诉 java 在哪里寻找用户提供的 .class 文件。默认情况下,这不一定包括当前工作目录。

【讨论】:

  • 问题出在代码上,也许有时它可以工作,但它不应该因为函数execvp的工作原理。
  • @cdecompilador:你的回答完全没有意义,为什么仅仅因为当前进程被java替换,输出就不可见了?
  • 这就是函数execvp 的工作原理,就我所知,它会影响进程,但它是非阻塞的
  • @cdecompilador:这不是真的,它完全替换当前进程。如果 execvp 成功,则不会执行 execvp 调用之后的任何代码。参见例如man7.org/linux/man-pages/man3/exec.3.html
【解决方案2】:

execvp() 的执行是非阻塞的,并且拥有调用者的所有权,这意味着如果程序结束得太快,当它开始时你永远不会能够看到结果,为了解决这个问题,我使用了 fork()。等待只是为了避免使用我在开始时使用的睡眠。一切尽在掌握。

#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char** argv){
    char buf[80];
    getcwd(buf,sizeof(buf));
    printf("current working directory: %s\n", buf);
    chdir("/home/");
    getcwd(buf,sizeof(buf));
    printf("current working directory: %s\n", buf);
    char *array[3] = {"java", "Main", NULL};
    if(fork() == 0) {
        if(execvp("java", array) < 0) {
            fprintf(stderr, "Error spawning command: %s\n", strerror(errno));
        }
    } else {
        printf("Command spawned\n");
        wait(NULL); // Wait to the forked process to end (avoid using sleep)
    }
    return 0;
}

【讨论】:

  • 我很困惑。我完全复制了你的代码,只修改了 Main.class 的目录。但是错误仍然存​​在。不知道是不是我的java环境问题,但是我可以在这个路径下运行“java Main”。
  • 它显示了某种错误?如果命令失败,它应该显示类似于Error spawning command: &lt;reason&gt; 的内容。这适用于我的系统
  • 不,只显示“错误:找不到主类。”
  • 我更改了 chdir() 函数,因为它可以在我的系统上运行
  • 我知道了,我把参数改成我的Main.class的路径
【解决方案3】:

我认为您不能运行 .class 文件。你应该寻找.jar。这基本上是'java-executable'。它通常应该在您编译 java 项目时出现。

【讨论】:

  • 但我可以在目录中运行“java Main”
  • 是的,他可以直接使用 java 命令运行类文件,您可以将 jar 文件视为该命令的“快捷方式”
  • 您的回答指出了一些事实,但在技术上是不正确的。可以只使用.class 文件(单个或多个文件)来执行java 程序。 .jar 是一种将多个 .class 文件打包到一个存档中的便捷方式,这使得下载/移动文件时更容易。如果您将程序的所有必要文件包装在一个 .jar 中以及适当的配置以指向要用作主类的类,那么是的,您可以将其视为“Java 可执行文件”,但您可以有没有这个主类说明符的 JAR。
猜你喜欢
  • 2012-09-08
  • 2022-11-29
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 2021-11-26
  • 1970-01-01
  • 2022-01-11
相关资源
最近更新 更多