无法使用execl()启动jar [英] Unable to launch jar with execl()
问题描述
我得到一个 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
andencrypt.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屋!