سؤال

أستخدم Eclipse IDE لتطوير وتجميع وتشغيل مشاريع Java الخاصة بي.اليوم، أحاول استخدام java.io.Console فئة لإدارة الإخراج، والأهم من ذلك، إدخال المستخدم.

المشكلة هي System.console() عائدات null عند تشغيل التطبيق "من خلال" Eclipse.يقوم Eclipse بتشغيل البرنامج في عملية خلفية، بدلاً من عملية المستوى الأعلى في نافذة وحدة التحكم التي اعتدنا عليها.

هل هناك طريقة لإجبار Eclipse على تشغيل البرنامج كعملية ذات مستوى أعلى، أو على الأقل إنشاء وحدة تحكم يتعرف عليها JVM؟بخلاف ذلك، سأضطر إلى تشغيل المشروع وتشغيله في بيئة سطر أوامر خارج Eclipse.

هل كانت مفيدة؟

المحلول

أفترض أنك تريد أن تكون قادرًا على استخدام التصحيح التدريجي من Eclipse.يمكنك فقط تشغيل الفئات خارجيًا عن طريق تعيين الفئات المبنية في دلائل الحاوية على مسار فئة JRE.

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 هو ملف دفعي يعمل بنظام Windows ويجب تشغيله خارجيًا من ملف 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

في الوسيطات، تم تعيين منفذ التصحيح على 8787.ال تعليق=y تخبر الوسيطة JVM بالانتظار حتى يتم إرفاق مصحح الأخطاء.

2.قم بإنشاء تكوين تشغيل التصحيح

في Eclipse، افتح مربع حوار Debug (Run > Open Debug Dialog...) وقم بإنشاء ملف جديد تطبيق جافا عن بعد التكوين مع الإعدادات التالية:

  • مشروع: اسم المشروع الخاص بك
  • نوع الاتصال: قياسي (إرفاق المقبس)
  • يستضيف: مضيف محلي
  • ميناء: 8787

3.تصحيح الأخطاء

لذلك، كل ما عليك فعله في أي وقت تريد فيه تصحيح أخطاء التطبيق هو:

  • تعيين نقطة استراحة
  • قم بتشغيل الملف الدفعي في وحدة التحكم
  • إطلاق تكوين التصحيح

يمكنك تتبع هذه المشكلة في الخطأ 122429.يمكنك التغلب على هذه المشكلة في تطبيقك باستخدام طبقة التجريد كما هو موضح هنا.

نصائح أخرى

الحل البديل الذي أستخدمه هو استخدام System.in/System.out فقط بدلاً من وحدة التحكم عند استخدام Eclipse.على سبيل المثال، بدلاً من:

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=43 .

وللأسف، نظرًا لأن وحدة التحكم نهائية، فلا يمكنك توسيعها لإنشاء غلاف حول system.in وsystem.out يقوم بذلك أيضًا.حتى داخل وحدة تحكم Eclipse، لا يزال بإمكانك الوصول إليها.ربما لهذا السبب لم يقم Eclipse بتوصيل هذا إلى وحدة التحكم الخاصة بهم حتى الآن ...

أتفهم سبب عدم رغبتك في الحصول على أي طريقة أخرى للحصول على وحدة تحكم بخلاف System.console، بدون أداة ضبط، لكنني لا أفهم سبب عدم رغبتك في أن يتمكن شخص ما من تجاوز الفصل لإجراء وحدة تحكم وهمية/اختبارية...

هناك خيار آخر وهو إنشاء طريقة لإنهاء كلا الخيارين، و"الفشل" في الأسلوب System.in عندما لا تكون وحدة التحكم متاحة.المثال أدناه هو مثال أساسي إلى حد ما - يمكنك اتباع نفس العملية لإكمال الطرق الأخرى في وحدة التحكم (قراءة كلمة المرور، التنسيق) كما هو مطلوب.وبهذه الطريقة يمكنك تشغيله بسعادة في 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.أود فقط التأكد من أن وحدة التحكم! = فارغة، ثم قم بتشغيلها وتشغيلها من سطر الأوامر.

يبدو أنه لا توجد طريقة للحصول على كائن java.io.Console عند تشغيل تطبيق من خلال Eclipse.لا يتم فتح نافذة وحدة تحكم سطر الأوامر مع التطبيق، حيث يتم تشغيلها كعملية خلفية (خلفية لـ Eclipse؟).حاليًا، لا يوجد مكون إضافي لـ Eclipse للتعامل مع هذه المشكلة، ويرجع ذلك أساسًا إلى حقيقة أن java.io.Console هي فئة نهائية.

كل ما يمكنك فعله حقًا هو اختبار كائن وحدة التحكم الذي تم إرجاعه بحثًا عن قيمة خالية والمتابعة من هناك.

هذا وصلة يقدم بدائل لاستخدام System.console().الأول هو استخدام BufferedReader الملتف حول System.in، والثاني هو استخدام الماسح الضوئي الملتف حول System.in.

كلاهما ليس موجزًا ​​مثل وحدة التحكم، لكن كلاهما يعمل في وضع الكسوف دون الحاجة إلى اللجوء إلى تصحيح الأخطاء!

لنفترض أن مساحة عمل Eclipse الخاصة بك هي C: myworkspace ، لقد قمت بإنشاء تطبيق Java الخاص بك داخل مشروع Maven MyProject ، وفئة Java الرئيسية الخاصة بك هي com.mydomain.mypackage.myclass.

في هذه الحالة، يمكنك تشغيل فصلك الرئيسي الذي يستخدم System.console() في سطر الأوامر:

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

ملحوظة 1:إذا لم يكن في مشروع Maven ، فتحقق من مجلد الإخراج في خصائص المشروع | جافا بناء مسار | مصدر.قد لا يكون "الهدف/الفئات"

NB2:إذا كان مشروعًا مخضرمًا، ولكن فصلك الدراسي موجود في src/test/java، فمن المحتمل أن تضطر إلى استخدام "target est-classes" بدلاً من "target\classes"

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top