У меня возникли странные проблемы при попытке выполнить блок кода (в частности, класс ProcessBuilder в 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
Как вы можете видеть, я не передаю никаких аргументов программе. когда я повторяю% PATH% на моей Windows DOS-оболочке, он показывает, что 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 создает каталог для пользователя и удаляет файл хранилища и переименовывает вновь созданный для регистрации пользователя.
Трудно легко увидеть различия между двумя длинными примерами кода. Не могли бы вы упростить, чтобы сделать простейший возможный код, который показывает вашу проблему? Или, если вы не знаете, как это сделать, возможно, вы можете описать словами разницу в ожидаемой функциональности двух модулей кода и определить, какие части имеют отношение к проблеме? –
System.out.println («Выполнение ACL2 runtime ...»); ProcessBuilder processBuilder = новый ProcessBuilder ("acl2"); Файл log = новый файл («logs/user/verify/acl2_log.txt»); processBuilder.redirectErrorStream (true); processBuilder.redirectOutput (ProcessBuilder.Redirect.appendTo (log)); Процесс process = processBuilder.start(); PrintWriter procIn = новый PrintWriter (process.getOutputStream()); – Treston
@Treston: Нет, не публикуйте код в комментарии.Измените свой вопрос, так что это действительно ясно. –