Eclipse IDEを使用して、Javaプロジェクトを開発、コンパイル、および実行します。今日、_Java.io.Console
_クラスを使用して、出力を管理し、さらに重要なこととして、ユーザー入力を管理します。
問題は、アプリケーションがEclipseを「介して」実行されると、System.console()
がnull
を返すことです。 Eclipseは、使い慣れたコンソールウィンドウを持つトップレベルプロセスではなく、バックグラウンドプロセスでプログラムを実行します。
Eclipseにプログラムをトップレベルプロセスとして実行させる方法、または少なくともJVMが認識するコンソールを作成する方法はありますか?そうでなければ、プロジェクトをjarして、Eclipseの外部のコマンドライン環境で実行することを余儀なくされます。
Eclipseからステップスルーデバッグを使用できるようにしたいと思います。 JREクラスパスのbinディレクトリにビルド済みクラスを設定することにより、クラスを外部で実行できます。
Java -cp workspace\p1\bin;workspace\p2\bin foo.Main
リモートデバッガーを使用してデバッグし、プロジェクトに組み込まれたクラスファイルを利用できます。
この例では、Eclipseプロジェクトの構造は次のようになります。
workspace\project\
\.classpath
\.project
\debug.bat
\bin\Main.class
\src\Main.Java
1。デバッグモードでJVMコンソールを起動します
debug.batは、cmd.exeコンソールから外部で実行する必要があるWindowsバッチファイルです。
@ECHO OFF
SET A_PORT=8787
SET A_DBG=-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=%A_PORT%,server=y,suspend=y
Java.exe %A_DBG% -cp .\bin Main
引数では、デバッグポートが8787に設定されています。 suspend = y引数は、デバッガーが接続するまで待機するようJVMに指示します。
2。デバッグ起動構成の作成
Eclipseで、[デバッグ]ダイアログ([実行]> [デバッグダイアログを開く...])を開き、次の設定で新しいRemote Java Application)構成を作成します。 :
3。デバッグ
そのため、アプリをデバッグするときに必要なことは次のとおりです。
この問題は bug 122429 で追跡できます。 here で説明されているように、抽象化レイヤーを使用して、アプリケーションでこの問題を回避できます。
私が使用する回避策は、Eclipseを使用するときに、コンソールではなくSystem.in/System.outを使用することです。たとえば、次の代わりに:
String line = System.console().readLine();
次を使用できます。
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();
これが発生する理由は、Eclipseがアプリをシステムコンソールのトップレベルプロセスとしてではなくバックグラウンドプロセスとして実行するためです。
自分でクラスを実装できます。次に例を示します。
public class Console {
BufferedReader br;
PrintStream ps;
public Console(){
br = new BufferedReader(new InputStreamReader(System.in));
ps = System.out;
}
public String readLine(String out){
ps.format(out);
try{
return br.readLine();
}catch(IOException e)
{
return null;
}
}
public PrintStream format(String format, Object...objects){
return ps.format(format, objects);
}
}
http://www.stupidjavatricks.com/?p=4 でこれについての何かを見つけました。
そして悲しいことに、コンソールは最終的なものなので、それを拡張してsystem.inとsystem.outのラッパーを作成することはできません。 Eclipseコンソール内でも、それらにアクセスできます。おそらく、Eclipseがまだこれをコンソールにプラグインしていないのはそのためでしょう...
System.console以外のコンソールをセッターなしで取得したくない理由は理解できますが、クラスをオーバーライドして誰かにクラスをオーバーライドさせたくない理由はわかりませんモック/テストコンソール...
もう1つのオプションは、両方のオプションをラップするメソッドを作成し、コンソールが使用できない場合にSystem.inメソッドに「フェールオーバー」することです。以下の例はかなり基本的なものです-必要に応じて、同じプロセスに従ってコンソールの他のメソッド(readPassword、形式)をまとめることができます。そうすれば、Eclipseで問題なく実行でき、デプロイされるとコンソール機能(パスワードの非表示など)が作動します。
private static String readLine(String Prompt) {
String line = null;
Console c = System.console();
if (c != null) {
line = c.readLine(Prompt);
} else {
System.out.print(Prompt);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
try {
line = bufferedReader.readLine();
} catch (IOException e) {
//Ignore
}
}
return line;
}
私が知る限り、EclipseからConsoleオブジェクトを取得する方法はありません。 console!= nullであることを確認してから、JARを作成してコマンドラインから実行します。
Eclipseを介してアプリケーションを実行する場合、Java.io.Consoleオブジェクトを取得する方法はないようです。コマンドラインコンソールウィンドウは、バックグラウンドプロセス(Eclipseのバックグラウンド?)として実行されるため、アプリケーションでは開きません。現在、主にJava.io.Consoleが最終クラスであるという事実により、この問題を処理するEclipseプラグインはありません。
本当にできることは、返されたConsoleオブジェクトのnullをテストし、そこから続行することだけです。
この link は、System.console()を使用する代替手段を提供します。 1つはSystem.inにラップされたBufferedReaderを使用することで、2つ目はSystem.inにラップされたスキャナーを使用することです。
どちらもコンソールほど簡潔ではありませんが、どちらもEclipseで機能し、愚かさをデバッグする必要はありません!
EclipseワークスペースがC:\ MyWorkspaceであり、MavenプロジェクトMyProject内にJavaアプリケーションを作成し、Javaメインクラスがcom.mydomainであるとします。 mypackage.MyClass。
この場合、コマンドラインでSystem.console()
を使用するメインクラスを実行できます。
Java -cp C:\MyWorkspace\MyProject\target\classes com.mydomain.mypackage.MyClass
NB1:Mavenプロジェクトにない場合は、プロジェクトのプロパティで出力フォルダーを確認してください| Java Build Path | Source。「target/classes」ではない可能性があります
NB2:Mavenプロジェクトであるが、クラスがsrc/test/Javaにある場合、「target\classes」の代わりに「target\test-classes」を使用する必要があります。