gpt4 book ai didi

java - ProcessBuilder - 一个潜在的错误

转载 作者:行者123 更新时间:2023-12-02 07:09:26 27 4
gpt4 key购买 nike

在尝试执行代码块(更具体地说是 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 变量中(这是 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 代码为用户创建一个目录,删除一个存储文件,并重命名新生成的文件以供用户注册。

最佳答案

由于抛出异常

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");

有可能找到acl命令,但无法执行重定向。在这种情况下,错误消息并不是很有帮助,但是 - 如果您阅读字里行间 - 也没有错误。

关于java - ProcessBuilder - 一个潜在的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15716737/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com