Ответ прост: если вы запускаете свою пусковую установку из среды IDE, такой как Eclipse или IntelliJ IDEA, возможно, у нее не установлено System.console()
, поэтому нет ничего, что может наследовать подпроцесс. Просто попробуйте написать что-то System.console()
из пусковой установки, он также потерпит неудачу с той же ошибкой. Но если вы запускаете свою пусковую установку с интерактивной консоли, такой как Cmd.exe или Git Bash, обе пусковая установка и процесс, запущенные через ProcessBuilder
, могут записываться в System.console()
. Ваша пусковая установка даже не нужна "cmd", "/c"
, она работает с этими параметрами или без них.
package de.scrum_master.stackoverflow;
import java.io.File;
import java.io.IOException;
public class Launcher {
public static void main(String[] args) throws IOException, InterruptedException {
String classPath = "out/production/SO_ExternalProcessSystemConsole";
String launchClass = "de.scrum_master.stackoverflow.MyApp";
File workDir = new File(".");
System.console().printf("Hi, I am the launcher app!%n");
String[] arguments = new String[] {
// "cmd", "/c",
"java", "-cp", classPath,
launchClass
};
ProcessBuilder pb = new ProcessBuilder(arguments);
pb.environment().putAll(System.getenv());
pb.directory(workDir);
pb.inheritIO();
Process process = pb.start();
process.waitFor();
}
}
package de.scrum_master.stackoverflow;
public class MyApp {
public static void main(String[] args) {
System.console().printf("Hi, I am an externally started app!%n");
}
}
журнала консоли при запуске из IntelliJ IDEA:
журнала
Exception in thread "main" java.lang.NullPointerException
at de.scrum_master.stackoverflow.Launcher.main(Launcher.java:11)
(...)
консоли при запуске из cmd.exe:
Hi, I am the launcher app!
Hi, I am an externally started app!
Не стесняйтесь задавать любые дополнительные вопросы ,
Update: Если вы не возражаете, что внешняя программа работает в своей собственной интерактивной консоли, а не в консоли IDE, вы можете использовать команду для Windows start
для этой цели, а затем либо cmd /c
(окна является закрыто сразу после внешней программы закончилась) или cmd /k
(окно остается открытым для вас, чтобы проверить результат):
package de.scrum_master.stackoverflow;
import java.io.File;
import java.io.IOException;
public class Launcher {
public static void main(String[] args) throws IOException, InterruptedException {
String classPath = "out/production/SO_ExternalProcessSystemConsole";
String launchClass = "de.scrum_master.stackoverflow.MyApp";
String[] arguments = new String[] {
"cmd", "/c", "start",
"cmd", "/k", "java", "-cp", classPath, launchClass
};
ProcessBuilder pb = new ProcessBuilder(arguments);
Process process = pb.start();
process.waitFor();
}
}
Но если затем вы хотите для чтения/записи из/в эту консоль, вы вернулись на площадь # 1. Вы спросили, почему вы не можете наследовать System.console()
подпроцессу. Ну, это потому, что это null
из-за того, как Eclipse и IntelliJ запускают Java-программы из среды IDE (см. [Здесь] для получения дополнительной информации). Но, как сказал Magnus, вы до сих пор System.{out|in}
и их можно использовать следующим образом:
package de.scrum_master.stackoverflow;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class Launcher {
public static void main(String[] args) throws IOException, InterruptedException {
String classPath = "out/production/SO_ExternalProcessSystemConsole";
String launchClass = "de.scrum_master.stackoverflow.MyApp";
File workDir = new File(".");
System.out.println("Hi, I am the launcher app!");
String[] arguments = new String[] { "cmd", "/c", "java", "-cp", classPath, launchClass };
ProcessBuilder pb = new ProcessBuilder(arguments);
pb.environment().putAll(System.getenv());
pb.directory(workDir);
pb.inheritIO();
Process process = pb.start();
process.waitFor();
System.out.print("What is your favourite city? ");
Scanner scanner = new Scanner(System.in);
String city = scanner.nextLine();
System.out.println("I guess that " + city + " is a nice place.");
}
}
package de.scrum_master.stackoverflow;
import java.util.Scanner;
public class MyApp {
public static void main(String[] args) {
System.out.println("----------------------------------------");
System.out.println("Hi, I am an externally started app.");
System.out.print("Please enter your name: ");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println("Hello " + name + "!");
System.out.println("----------------------------------------");
}
}
Hi, I am the launcher app!
----------------------------------------
Hi, I am an externally started app.
Please enter your name: Alexander
Hello Alexander!
----------------------------------------
What is your favourite city? Berlin
I guess that Berlin is a nice place.
Это на самом деле не представляется возможным или хорошая идея, 'System.Console()' является доступен только в том случае, если программа запускается в интерактивном режиме, так как вы разговариваете с другим приложением Java, вам будет намного лучше загружать его в качестве библиотеки. В качестве альтернативы вы можете просто использовать 'System.in' и' System.out' вместо 'Console', который будет работать вне интерактивного режима. – Magnus
Возможный обман http://stackoverflow.com/q/22799265/6754053 –