0

尝试执行代码块时遇到一个奇怪的问题(尤其是 Java 中的 ProcessBuilder 类)

有效的代码:

package modules.user.verify;

import java.io.*;
import java.util.*;
import java.net.*;

public class VerifyUser {
public static void main(String[] args) {
    boolean listening = true;

    try {
        ServerSocket server = new ServerSocket(20002);

        while(listening) {
            Socket client = server.accept();

            PrintWriter out = new PrintWriter(client.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

            String input, store = "", request = "";

            // For all input received, write it to the request buffer.
            while((input = in.readLine()) != null) {
                request += input;
            }   // end while loop

            BufferedReader reader = new BufferedReader(new FileReader("store/address-book/address-book.xml"));

            while((input = reader.readLine()) != null) {
                store += input;
            }   // end while loop

            String acl2 = "(include-book \"modules/user/verify/verify-user\")" + 
                              "(in-package \"ACL2\")" +
                         "(set-state-ok t)" +
                              "(set-guard-checking :none)" + 
                          "(testUser \"" + request + "\" \"" + store + "\" state)";

            System.out.println("Executing ACL2 runtime...");
            ProcessBuilder processBuilder = new ProcessBuilder("acl2");
            File log = new File("logs/user/verify/acl2_log.txt");
            processBuilder.redirectErrorStream(true);
            processBuilder.redirectOutput(ProcessBuilder.Redirect.appendTo(log));
            Process process = processBuilder.start();
            PrintWriter procIn = new PrintWriter(process.getOutputStream());

            // Write the ACL2 to the process, exit ACL2 and close the socket
            procIn.println(acl2);
            procIn.println("(good-bye)");
            procIn.flush();
            procIn.close();
            out.close();
            in.close();
            client.close();
        }   // end while loop

        server.close();
        System.exit(0);
    } catch(Exception e) {
        e.printStackTrace();
    }   // end try/catch
}   // end function main
}   // end class VerifyUser

不起作用的代码:

package modules.user.register;

import java.io.*;
import java.util.*;
import java.net.*;

public class RegisterUser {
public static void main(String[] args) {
    boolean listening = true;

    try {
        // Acquire the listening port for connection to client.
        ServerSocket server = new ServerSocket(20001);

        while(listening) {
            // Wait until the client connects
            Socket client = server.accept();

            // Handles for input and output streams relating to the socket connection
            PrintWriter out = new PrintWriter(client.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

            // Buffers
            String input, store="", request="";

            // Read the input from the connection
            while((input = in.readLine()) != null) {
                request += input;
            }   // end while

            // Read the contents of the address-book currently stored
            BufferedReader reader = new BufferedReader(new FileReader("store/address-book/address-book.xml"));
            while((input = reader.readLine()) != null) {
                store += input;
            }   // end while

            // The ACL2 code to execute.
            String acl2 = "(include-book \"register-user\")" +
                          "(in-package \"ACL2\")"            +
                          "(registerUser \"" + request + "\" \"" + store + "\" state)";

            // Initialize ACL2 and dump its output to the log
            System.out.println("Executing ACL2 runtime for RegisterUser...");
            ProcessBuilder processBuilder = new ProcessBuilder("acl2");
            File log = new File("logs/user/register/acl2_log.txt");
            processBuilder.redirectErrorStream(true);
            processBuilder.redirectOutput(ProcessBuilder.Redirect.appendTo(log));

            Process process = processBuilder.start();
            PrintWriter procIn = new PrintWriter(process.getOutputStream());

            // Write the ACL2 to the process, close ACL2
            //procIn.println(acl2);
            //procIn.println("(good-bye)");
            //procIn.flush();
            //procIn.close();

            // Old store is old address-book file and new store is newly generated
            File oldStore = new File("store/address-book/address-book.xml");
            File newStore = new File("store/address-book/temp_address-book.xml");

            // Response header information
            String response = "<?xml version='1.0'?>"                        + 
                              "<!DOCTYPE response SYSTEM 'dtd/reponse.dtd'>" +
                              "<response>";

            // Determine if there was a change.
            // If entry was added, the length > that old length.
            if(oldStore.length() < newStore.length()) {
                // Replace old file with new file
                oldStore.delete();
                newStore.renameTo(oldStore);

                // Extract data from request XML
                String name   = request.substring(request.indexOf("<name>")+6, request.indexOf("</name>")-7);
                String domain = request.substring(request.indexOf("<domain>")+8, request.indexOf("</domain>")-9);

                // Create the store directory for the user's emails
                File storeDirectory = new File("store/email/" + domain + "/" + name + "/");
                storeDirectory.mkdirs();

                response += "<message>ACCEPT</message>";
            } else {
                // Remove new file as it is pointless
                newStore.delete();
                response += "<message>REJECT</message>";
            }   // end if-else

            response += "</response>";

            // Writeback the response to the client
            out.print(response);
            out.flush();

            // Close all streams
            out.close();
            in.close();
            client.close();
        }   // end while
    } catch(Exception e) {
        e.printStackTrace();
    }   // end try/catch
}   // end function main
}   // end class RegisterUser

如您所见,我没有向程序传递任何参数。当我在 Windows DOS shell 上回显 %PATH% 时,它显示 C:\ACL2 在我的 ENV vars 中(这是 acl2.exe 所在的文件夹)。我尝试将 acl2 更改为 C:\ACL2\acl2.exe 只是为了得到相同的结果。

令我惊讶的是为什么第一个工作完美而第二个(具有几乎相同的完全相同的代码 - 完全相同的 ProcessBuilder 代码)不起作用。

看来这段代码是我的问题所在:

        System.out.println("Executing ACL2 runtime...");
        ProcessBuilder processBuilder = new ProcessBuilder("acl2");
        File log = new File("logs/user/register/acl2_log.txt");
        processBuilder.redirectErrorStream(true);
        processBuilder.redirectOutput(ProcessBuilder.Redirect.appendTo(log));
        Process process = processBuilder.start();
        PrintWriter procIn = new PrintWriter(process.getOutputStream());

错误:

Executing ACL2 runtime for RegisterUser...
java.io.IOException: Cannot run program "acl2": The system cannot find the path specified
        at java.lang.ProcessBuilder.start(Unknown Source)
    at modules.user.register.RegisterUser.main(RegisterUser.java:74)
Caused by: java.io.IOException: The system cannot find the path specified
    at java.lang.ProcessImpl.openForAtomicAppend(Native Method)
    at java.lang.ProcessImpl.newFileOutputStream(Unknown Source)
    at java.lang.ProcessImpl.start(Unknown Source)
    ... 2 more

应该发生的是,启动的进程是 ACL2 环境,代码被发送到它被执行,然后进程被杀死(通过 ACL2 中的(再见)命令)。之后代码应该在一点点Java之后退出,这与发生错误的ACL2进程无关。

VerifyUser 程序调用 ACL2,将响应写入“server-response.xml”文件并正常退出而不会发生任何事件。

RegisterUser 程序应该调用 ACL2,写一个响应并优雅地退出,一个小的 java 代码为用户创建一个目录,删除一个存储文件并重命名新生成的用户注册。

4

1 回答 1

2

由于异常被抛出

at java.lang.ProcessImpl.openForAtomicAppend(Native Method)

并且您使用两种不同的路径:

File log = new File("logs/user/verify/acl2_log.txt");
File log = new File("logs/user/register/acl2_log.txt");

it might be possible, that the acl command is found but that the redirection cannot be performed. In this case the error message is not quite helpful but - if you read between the lines - also not wrong.

于 2013-03-30T09:32:10.437 回答