无法使用execl()启动jar [英] Unable to launch jar with execl()

查看:202
本文介绍了无法使用execl()启动jar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到一个 decrypt.jar encrypt.jar 文件,用于在传输之前准备文件。



当我启动终端并输入:

  / usr / bin / java -jar /path/to/jar/decrypt.jar 

 未指定输入文件

这是OK!瓶子工作。现在在我的代码中,当我用execl()启动jar,我得到这个作为输出:

 错误:找不到或加载主类util.decrypt.jar 
解密器退出与0

请注意,问题这里是java试图启动类,这实际上是路径的jar(路径是util / decrypt.jar,并执行它作为一个类util.decrypt.jar)



我的代码:

  bool decrypt_file(const std :: string& file){
int result ;
int pipefd [2];
FILE * cmd_output;
char buf [1024];
int status;

result = pipe(pipefd);
if(result< 0){
throwpipe error!;
}

pid_t pid = fork(); / *创建一个子进程* /
const std :: string decryptJar =util / decrypt.jar;
int ex;
if(!fileExists(decryptJar))throw文件解密器不存在! fork()失败!

switch(pid){
case -1:/ *错误* /
#ifdef _DEBUG
std :: cout< \\\
;
#endif
return false;
case 0:/ *子进程* /
dup2(pipefd [1],STDOUT_FILENO); / *重复写入结束到stdout * /
close(pipefd [0]);
close(pipefd [1]);

// getJava()返回/ usr / bin / java
ex = execl(Config :: getInstance().getJava()。c_str(),-jar decryptJar.c_str(),file.c_str(),NULL); / *执行程序* /
#ifdef _DEBUG
std :: cout< execl()failed!returned<< ex<<,errno =<< errno<<\ n / * execl不返回除非有错误* /
// todo如果errno是2,java在系统上没有找到,让用户知道!
#endif
return false;
默认值:/ *父进程* /
int status;
close(pipefd [1]); / *关闭写管道结束* /
cmd_output = fdopen(pipefd [0],r);
#ifdef _DEBUG
if(fgets(buf,sizeof buf,cmd_output)){
std :: string str(buf);
std :: cout<<OUTPUT:<< str<<\\\
;
}
#endif
while(!WIFEXITED(status)){
waitpid(pid,& status,0); / *等待进程完成* /
}

#ifdef _DEBUG
std :: cout<< 解密器退出与< WEXITSTATUS(status)<< \\\
;
#endif
return true;
}
}

jar中的manifest是正确的by eclipse):

  Manifest-Version:1.0 
Class-Path:。
Main-Class:com。{...}。解密



尝试将路径更改为jar的绝对路径没有解决问题。

  const std :: string decryptJar = workingDir()+/util/decrypt.jar; 


解决方案

已解决



从我身边的愚蠢的错误,第一个参数应该按照惯例总是可执行文件的路径。



  ex = execl(Config :: getInstance()。getJava()。c_str(),-jar,decryptJar。 c_str(),file.c_str(),NULL); / *执行程序* / 

应为

  ex = execl(Config :: getInstance()。getJava()。c_str(),decrypt.jar.c_str(),-jar,decryptJar.c_str c_str(),NULL); / *执行程序* / 



发生了什么事情是java以-jar因此我的命令实际上是

  java pathToJar input 

而不是

  java -jar pathToJar input 

编辑:修正后的程式码片段:

  bool decrypt_file(const std :: string& javaPath,const std :: string& file){
int result,status;
int pipefd [2];
FILE * cmd_output;
char buf [1024];
int ex;
const std :: string decryptJar = workingDir()+/util/decrypt.jar;

result = pipe(pipefd);
if(result< 0){
throwpipe error!;
}

pid_t pid = fork(); / *创建子进程* /
if(!fileExists(decryptJar))throw文件解密器不存在! fork()失败!

switch(pid){
case -1:/ * Error * /
#ifdef _DEBUG
std :: cout< \\\
;
#endif
return false;
case 0:/ *子进程* /
dup2(pipefd [1],STDOUT_FILENO); / *重复写入结束到stdout * /
close(pipefd [0]);
close(pipefd [1]);

ex = execl(javaPath.c_str(),decrypt.jar.c_str(),-jar,decryptJar.c_str(),file.c_str(),NULL); / *执行程序* /
#ifdef _DEBUG
std :: cout< execl()failed!returned<< ex<<,errno =<< errno<<\ n / * execl不返回除非有错误* /
#endif
if(errno == 2){
std :: cout<<JAVA NOT FOUND!和/或如果配置文件中的路径指向正确的java安装!\\\
\\\
;
}
return false;
default:/ *父进程* /
close(pipefd [1]); / *关闭写管道结束* /
cmd_output = fdopen(pipefd [0],r);
#ifdef _DEBUG
if(fgets(buf,sizeof buf,cmd_output)){
std :: string str(buf);
if(str!=OK)
std :: cout<<--- DECRYPT OUTPUT:<< str<<\\\

}
#endif
while(!WIFEXITED(status)){
waitpid(pid,& status,0); / *等待进程完成* /
}

#ifdef _DEBUG
std :: cout<< 解密器退出与< WEXITSTATUS(status)<< \\\
;
#endif
return true;
}
}


I was given a decrypt.jar and encrypt.jar file, which are used to prepare files before transmitting.

When I launch the terminal and type:

/usr/bin/java -jar /path/to/jar/decrypt.jar

I get the output:

No input file specified

Which is OK! The jar works. Now in my code, when I launch the jar with execl(), I get this as output:

Error: Could not find or load main class util.decrypt.jar
Decryptor exited with 0

Notice that the issue here is that java tried to launch the class which is actually the path to the jar (the path is util/decrypt.jar, and it executed it as a class util.decrypt.jar)

My code:

bool decrypt_file(const std::string& file) {
    int result;
    int pipefd[2];
    FILE *cmd_output;
    char buf[1024];
    int status;

    result = pipe(pipefd);
    if (result < 0) {
        throw "pipe error!";
    }

    pid_t pid = fork(); /* Create a child process */
    const std::string decryptJar = "util/decrypt.jar";
    int ex;
    if ( !fileExists(decryptJar) ) throw "File decryptor does not exist!";

    switch (pid) {
        case -1: /* Error */
#ifdef _DEBUG
            std::cout<<"fork() failed!\n";
#endif
            return false;
        case 0: /* Child process */
            dup2(pipefd[1], STDOUT_FILENO); /* Duplicate writing end to stdout */
            close(pipefd[0]);
            close(pipefd[1]);

            //getJava() returns "/usr/bin/java"
            ex = execl(Config::getInstance().getJava().c_str(), "-jar", decryptJar.c_str(), file.c_str(), NULL); /* Execute the program */
#ifdef _DEBUG
            std::cout << "execl() failed! returned "<<ex<<", errno = "<<errno<<"\n"; /* execl doesn't return unless there's an error */
            //todo if errno is 2, java was not found on the system, let the user know!
#endif
            return false;
        default: /* Parent process */
            int status;
            close(pipefd[1]); /* Close writing end of pipe */
            cmd_output = fdopen(pipefd[0], "r");
#ifdef _DEBUG
            if (fgets(buf, sizeof buf, cmd_output)) {
                std::string str(buf);
                std::cout<<"OUTPUT: "<<str<<"\n";
            }
#endif
            while (!WIFEXITED(status)) {
                waitpid(pid, &status, 0); /* Wait for the process to complete */
            }

#ifdef _DEBUG
            std::cout << "Decryptor exited with " << WEXITSTATUS(status) << "\n";
#endif
            return true;
    }
}

The manifest inside the jar is correct (it was generated by eclipse):

Manifest-Version: 1.0
Class-Path: .
Main-Class: com.{...}.Decryptor

Add:

Trying to change the path to the absolute path of the jar didn't fix the problem.

const std::string decryptJar = workingDir() + "/util/decrypt.jar";

解决方案

Solved

Stupid mistake from my side, the first argument should, by convention, always be the path to the executable.

So

ex = execl(Config::getInstance().getJava().c_str(), "-jar", decryptJar.c_str(), file.c_str(), NULL); /* Execute the program */

Should be

ex = execl(Config::getInstance().getJava().c_str(), decryptJar.c_str(), "-jar", decryptJar.c_str(), file.c_str(), NULL); /* Execute the program */

What happened is that java took "-jar" as the path, thus my command was actually

java pathToJar input

instead of

java -jar pathToJar input

Edit: the corrected code snippet:

bool decrypt_file(const std::string& javaPath, const std::string& file) {
        int result, status;
        int pipefd[2];
        FILE *cmd_output;
        char buf[1024];
        int ex;
        const std::string decryptJar = workingDir() + "/util/decrypt.jar";

        result = pipe(pipefd);
        if (result < 0) {
            throw "pipe error!";
        }

        pid_t pid = fork(); /* Create a child process */
        if ( !fileExists(decryptJar) ) throw "File decryptor does not exist!";

        switch (pid) {
            case -1: /* Error */
    #ifdef _DEBUG
                std::cout<<"fork() failed!\n";
    #endif
                return false;
            case 0: /* Child process */
                dup2(pipefd[1], STDOUT_FILENO); /* Duplicate writing end to stdout */
                close(pipefd[0]);
                close(pipefd[1]);

                ex = execl(javaPath.c_str(), decryptJar.c_str(), "-jar", decryptJar.c_str(), file.c_str(), NULL); /* Execute the program */     
    #ifdef _DEBUG
                std::cout << "execl() failed! returned "<<ex<<", errno = "<<errno<<"\n"; /* execl doesn't return unless there's an error */
    #endif
                if ( errno == 2 ) {
                    std::cout<<"JAVA NOT FOUND! Check if java is installed and/or if the path in the config file points to a correct java installation!\n\n";
                }
                return false;
            default: /* Parent process */
                close(pipefd[1]); /* Close writing end of pipe */
                cmd_output = fdopen(pipefd[0], "r");
    #ifdef _DEBUG
                if (fgets(buf, sizeof buf, cmd_output)) {
                    std::string str(buf);
                    if ( str != "OK" )
                        std::cout<<"---DECRYPT OUTPUT: "<<str<<"\n";
                }
    #endif
                while (!WIFEXITED(status)) {
                    waitpid(pid, &status, 0); /* Wait for the process to complete */
                }

    #ifdef _DEBUG
                std::cout << "Decryptor exited with " << WEXITSTATUS(status) << "\n";
    #endif
                return true;
        }
    }

这篇关于无法使用execl()启动jar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆