dukungan java.io.Console di Eclipse IDE

103

Saya menggunakan Eclipse IDE untuk mengembangkan, mengkompilasi, dan menjalankan proyek Java saya. Hari ini, saya mencoba menggunakan java.io.Consolekelas untuk mengelola keluaran dan, yang lebih penting, masukan pengguna.

Masalahnya adalah yang System.console()kembali nullketika aplikasi dijalankan "melalui" Eclipse. Eclipse menjalankan program pada proses latar belakang, bukan proses tingkat atas dengan jendela konsol yang kita kenal.

Apakah ada cara untuk memaksa Eclipse menjalankan program sebagai proses tingkat atas, atau setidaknya membuat Konsol yang akan dikenali JVM? Jika tidak, saya terpaksa mengacaukan proyek dan menjalankan lingkungan baris perintah di luar Eclipse.

Ross
sumber
Juga lihat stackoverflow.com/questions/26470972/… Saya telah mengidentifikasi System.outdan System.inmencukupi untuk kasus penggunaan saya dan berhenti menggunakan System.console().
OneWorld
Saya mengekspor proyek sebagai jar yang dapat dijalankan, tetapi saya masih mendapatkan kesalahan konsol nol
Abhigyan

Jawaban:

50

Saya berasumsi Anda ingin dapat menggunakan langkah-langkah debugging dari Eclipse. Anda bisa menjalankan kelas secara eksternal dengan menyetel kelas yang dibangun di direktori bin pada jalur kelas JRE.

java -cp workspace\p1\bin;workspace\p2\bin foo.Main

Anda dapat men-debug menggunakan debugger jarak jauh dan memanfaatkan file kelas yang dibangun dalam proyek Anda.

Dalam contoh ini, struktur proyek Eclipse terlihat seperti ini:

workspace\project\
                 \.classpath
                 \.project
                 \debug.bat
                 \bin\Main.class
                 \src\Main.java

1. Mulai Konsol JVM dalam Mode Debug

debug.bat adalah file batch Windows yang harus dijalankan secara eksternal dari konsol cmd.exe .

@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

Dalam argumen, port debug telah disetel ke 8787 . The menangguhkan = y argumen memberitahu JVM untuk menunggu sampai atase debugger.

2. Buat Konfigurasi Peluncuran Debug

Di Eclipse, buka dialog Debug (Run> Open Debug Dialog ...) dan buat konfigurasi Aplikasi Java Jarak Jauh baru dengan setelan berikut:

  • Proyek: nama proyek Anda
  • Jenis Koneksi: Standar (Socket Attach)
  • Host: localhost
  • Pelabuhan: 8787

3. Debugging

Jadi, yang harus Anda lakukan kapan pun Anda ingin men-debug aplikasi adalah:

  • menetapkan titik istirahat
  • meluncurkan file batch di konsol
  • luncurkan konfigurasi debug

Anda dapat melacak masalah ini di bug 122429 . Anda dapat mengatasi masalah ini dalam aplikasi Anda dengan menggunakan lapisan abstraksi seperti yang dijelaskan di sini .

McDowell
sumber
1
Saya juga akan meletakkan pausedi akhir file batch itu sehingga Anda dapat melihat pesan kesalahan yang muncul sebelum ditutup.
Matt Lyons
10
Ini adalah pukulan terakhir bagi saya. Jika saya harus melakukan semua ini hanya untuk men-debug, saya beralih kembali ke Netbeans. Begitu banyak bug yang tidak diperbaiki dan gangguan UI di Eclipse bahkan tidak lucu.
nuzzolilo
@Nuzzolilo, ini hanya untuk debugging jarak jauh. Anda dapat men-debug secara lokal di eclipse tanpa semua itu.
Laplie Anderson
35

Solusi yang saya gunakan adalah dengan hanya menggunakan System.in/System.out daripada Konsol saat menggunakan Eclipse. Misalnya, alih-alih:

String line = System.console().readLine();

Kamu bisa memakai:

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();
Laplie Anderson
sumber
20
Saya tidak berpikir bahwa Anda akan dapat membaca kata sandi dengan penyamaran kata sandi seperti itu.
Sualeh Fatehi
3
... dan satu kebutuhan untuk menangani IOException, yang tidak terlempar dalam kasus Console.readLine().
dma_k
5

Alasan hal ini terjadi adalah karena eclipse menjalankan aplikasi Anda sebagai proses latar belakang dan bukan sebagai proses tingkat atas dengan konsol sistem.

Heath Borders
sumber
5

Anda dapat menerapkan kelas sendiri. Berikut ini contohnya:

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);
    }
}
yztaoj
sumber
4

Temukan sesuatu tentang ini di http://www.stupidjavatricks.com/?p=43 .

Dan sayangnya, karena konsol sudah final, Anda tidak dapat memperluasnya untuk membuat pembungkus di sekitar system.in dan system.out yang juga melakukannya. Bahkan di dalam konsol gerhana Anda masih memiliki akses ke sana. Mungkin itu sebabnya eclipse belum menghubungkan ini ke konsol mereka ...

Saya mengerti mengapa Anda tidak ingin memiliki cara lain untuk mendapatkan konsol selain System.console, tanpa penyetel, tetapi saya tidak mengerti mengapa Anda tidak ingin seseorang dapat menimpa kelas untuk membuat tiruan / konsol pengujian ...

John Gardner
sumber
4

Opsi lainnya adalah membuat metode untuk menggabungkan kedua opsi, dan "gagal" ke metode System.in saat Konsol tidak tersedia. Contoh di bawah ini cukup mendasar - Anda dapat mengikuti proses yang sama untuk menyelesaikan metode lain di Console (readPassword, format) sesuai kebutuhan. Dengan cara itu Anda dapat menjalankannya dengan senang hati di Eclipse & saat diterapkan, Anda mendapatkan fitur Konsol (mis. Penyembunyian kata sandi) mulai bekerja.

    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;
    }
biner kubus
sumber
2

Sejauh yang saya tahu, tidak ada cara untuk mendapatkan objek Konsol dari Eclipse. Saya hanya akan memastikan konsol itu! = Null, lalu JAR dan jalankan dari baris perintah.

perimosocordiae
sumber
1

Sepertinya tidak ada cara untuk mendapatkan objek java.io.Console saat menjalankan aplikasi melalui Eclipse. Jendela konsol baris perintah tidak dibuka dengan aplikasi, karena dijalankan sebagai proses latar belakang (latar belakang ke Eclipse?). Saat ini, tidak ada plugin Eclipse untuk menangani masalah ini, terutama karena java.io.Console adalah kelas terakhir.

Yang benar-benar dapat Anda lakukan adalah menguji objek Konsol yang dikembalikan untuk null dan melanjutkan dari sana.

Ross
sumber
1

Tautan ini menawarkan alternatif untuk menggunakan System.console (). Salah satunya adalah dengan menggunakan BufferedReader yang melingkari System.in, yang kedua adalah menggunakan Scanner yang membungkus System.in.

Tidak ada yang sesingkat konsol, tetapi keduanya bekerja dalam gerhana tanpa harus menggunakan debug kekonyolan!

Dave Richardson
sumber
0

Katakanlah ruang kerja Eclipse Anda adalah C: \ MyWorkspace, Anda membuat aplikasi java di dalam proyek maven MyProject, dan kelas utama Java Anda adalah com.mydomain.mypackage.MyClass.

Dalam hal ini, Anda dapat menjalankan kelas utama yang menggunakan System.console()baris perintah:

java -cp C:\MyWorkspace\MyProject\target\classes com.mydomain.mypackage.MyClass

NB1: jika tidak ada dalam proyek maven, periksa folder keluaran di properti proyek | Jalur Membangun Java | Sumber. Ini mungkin bukan "target / kelas"

NB2: jika ini adalah proyek maven, tetapi kelas Anda ada di src / test / java, Anda mungkin harus menggunakan "target \ test-class" daripada "target \ kelas"

Paulo Merson
sumber