1

送信前にファイルを準備するために使用されるdecrypt.jarandファイルが与えられました。encrypt.jar

ターミナルを起動して次のように入力すると:

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

出力が得られます:

No input file specified

どちらでもOK!瓶は機能します。私のコードでは、execl() で jar を起動すると、次の出力が得られます。

Error: Could not find or load main class util.decrypt.jar
Decryptor exited with 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) {
        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;
    }
}

jar 内のマニフェストは正しいです (Eclipse によって生成されました)。

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

追加:

パスをjarの絶対パスに変更しようとしても、問題は解決しませんでした。

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

1 に答える 1

1

解決済み

私の側からの愚かな間違いです。最初の引数は、慣例により、常に実行可能ファイルへのパスでなければなりません。

そう

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

する必要があります

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

何が起こったのかというと、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) {
            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;
        }
    }
于 2015-09-30T08:54:02.527 に答える