त्वरित सारांश, आप या तो कर सकते हैं:
जोसेफ के जवाब के माध्यम से --module-path
और --add-modules
जैसे JavaFX मॉड्यूल शामिल करें ।
या
एक बार जब आप अपने प्रोजेक्ट में जावाएफ़एक्स पुस्तकालयों को जोड़ लेते हैं (या तो मैन्युअल रूप से या मावेन / ग्रेडेल आयात के माध्यम से), module-info.java
इस उत्तर में निर्दिष्ट फ़ाइल के समान फ़ाइल जोड़ें । (ध्यान दें कि यह समाधान आपके ऐप को मॉड्यूलर बनाता है, इसलिए यदि आप अन्य पुस्तकालयों का उपयोग करते हैं, तो आपको module-info.java
फ़ाइल के अंदर उनके मॉड्यूल की आवश्यकता के लिए स्टेटमेंट भी जोड़ना होगा )।
यह उत्तर जोस के उत्तर का पूरक है।
स्थिति यह है:
- आप हाल ही के जावा संस्करण का उपयोग कर रहे हैं, उदाहरण के लिए 13।
- आपके पास जावा प्रोजेक्ट एक मावेन प्रोजेक्ट के रूप में है।
- अपने मावेन प्रोजेक्ट में आपके पास जोसफ के उत्तर के अनुसार JavaFX प्लगइन कॉन्फ़िगर और JavaFX निर्भरता सेटअप है।
- आप अपने मुख्य वर्ग के स्रोत कोड पर जाते हैं जो अनुप्रयोग का विस्तार करता है, आप उस पर राइट-क्लिक करते हैं और इसे चलाने का प्रयास करते हैं।
- आप प्राप्त एक
IllegalAccessError
जब एप्लिकेशन को लॉन्च करने की कोशिश कर रहा एक "अज्ञात मॉड्यूल" से जुड़े।
IllegalAccessError
जब एक Intellij Idea से JavaFX ऐप चलाने की कोशिश कर रहे एक स्टैक ट्रेस उत्पन्न के लिए अंश :
Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x45069d0e) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x45069d0e
at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
at org.jewelsea.demo.javafx.springboot.Main.start(Main.java:13)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Exception running application org.jewelsea.demo.javafx.springboot.Main
ठीक है, अब आप एक तरह से फंस गए हैं और कोई सुराग नहीं है कि क्या चल रहा है।
वास्तव में क्या हुआ है:
- मावेन ने आपके आवेदन के लिए सफलतापूर्वक जावाएफएक्स निर्भरताएं डाउनलोड की हैं, इसलिए आपको निर्भरता को अलग से डाउनलोड करने या जावाएफएक्स एसडीके या मॉड्यूल वितरण या ऐसा कुछ भी स्थापित करने की आवश्यकता नहीं है।
- आइडिया ने मॉड्यूल को आपकी परियोजना पर निर्भरता के रूप में सफलतापूर्वक आयात किया है, इसलिए सब कुछ ठीक है और सभी कोड पूरा होने और सब कुछ ठीक काम करता है।
तो ऐसा लगता है कि सब कुछ ठीक होना चाहिए। लेकिन, जब आप अपना एप्लिकेशन चलाते हैं, तो आपके ऐप्लिकेशन क्लास (जब आप लॉन्च शुरू करते हैं) और आपके एफएक्सएमएल कंट्रोलर क्लासेस (जब आप एफएक्सएमएल लोड करते हैं) के तुरंत इंस्टेंस को रिफ्लेक्ट करने की कोशिश करते समय JavaFX मॉड्यूल्स में कोड फेल हो रहा होता है। कुछ मदद के बिना, प्रतिबिंब का यह उपयोग कुछ मामलों में विफल हो सकता है, अस्पष्ट पैदा कर सकता है IllegalAccessError
। यह जावा मॉड्यूल सिस्टम सुरक्षा सुविधा के कारण है जो अन्य मॉड्यूल से कोड को आपकी कक्षाओं पर प्रतिबिंब का उपयोग करने की अनुमति नहीं देता है जब तक कि आप स्पष्ट रूप से इसकी अनुमति नहीं देते हैं (और जावाएफ़एक्स एप्लिकेशन लॉन्चर और एफएक्सएमएलएलडियर दोनों को कार्य करने के लिए उनके वर्तमान कार्यान्वयन में प्रतिबिंब की आवश्यकता होती है। सही ढंग से)।
यह वह जगह है जहां इस प्रश्न के कुछ अन्य उत्तर, जो संदर्भ module-info.java
, चित्र में आते हैं।
तो जावा मॉड्यूल में क्रैश कोर्स करें:
मुख्य भाग यह है:
4.9। खुलती
यदि हमें निजी प्रकार के प्रतिबिंब की अनुमति देने की आवश्यकता है, लेकिन हम अपने सभी कोड को उजागर नहीं करना चाहते हैं, तो हम विशिष्ट पैकेजों को उजागर करने के लिए ओपन डायरेक्टिव का उपयोग कर सकते हैं।
लेकिन याद रखें, यह पूरी दुनिया के लिए पैकेज खोल देगा, इसलिए सुनिश्चित करें कि आप क्या चाहते हैं:
module my.module { opens com.my.package; }
इसलिए, शायद आप अपना पैकेज पूरी दुनिया के लिए नहीं खोलना चाहते, तो आप ऐसा कर सकते हैं:
4.10। खुलता है ... करने के लिए
ठीक है, इसलिए प्रतिबिंब कभी-कभी बहुत अच्छा होता है, लेकिन हम अभी भी उतनी ही सुरक्षा चाहते हैं जितना कि हम एनकैप्सुलेशन से प्राप्त कर सकते हैं। हम चुनिंदा तौर पर अपने पैकेज को मॉड्यूल की एक पूर्व-अनुमोदित सूची में खोल सकते हैं, इस मामले में, ओपन का उपयोग करते हुए ... निर्देश के लिए:
मॉड्यूल my.module {मॉड्यूल के लिए com.my.package खोलता है, मॉड्यूलटाउ, आदि; }
तो, आप अंत में एक src / main / java / मॉड्यूल-info.java क्लास बनाते हैं जो इस तरह दिखता है:
module org.jewelsea.demo.javafx.springboot {
requires javafx.fxml;
requires javafx.controls;
requires javafx.graphics;
opens org.jewelsea.demo.javafx.springboot to javafx.graphics,javafx.fxml;
}
जहाँ, org.jewelsea.demo.javafx.springboot
उस पैकेज का नाम है जिसमें जावाएफ़एक्स एप्लिकेशन क्लास और जावाएफ़एक्स कंट्रोलर क्लासेस शामिल हैं (इसे अपने आवेदन के लिए उपयुक्त पैकेज नाम से बदलें)। यह जावा रनटाइम को बताता है कि यह आपके पैकेज में कक्षाओं के लिए javafx.graphics
और कक्षाओं में javafx.fxml
प्रतिबिंब लागू करने के लिए ठीक है org.jewelsea.demo.javafx.springboot
। एक बार यह पूरा हो जाने के बाद, और एप्लिकेशन को संकलित किया जाता है और फिर से चलने वाली चीजें ठीक काम करेंगी और IllegalAccessError
जावाएफ़एक्स द्वारा प्रतिबिंब के उपयोग से उत्पन्न अब नहीं होगा।
लेकिन क्या होगा अगर आप एक मॉड्यूल-info.java फ़ाइल नहीं बनाना चाहते हैं
यदि इसके बजाय अपने आवेदन वर्ग को सीधे चलाने के लिए IDE के शीर्ष टूलबार में रन बटन का उपयोग करें, तो आप इसके बजाय:
- IDE के साइड में Maven विंडो पर गया।
- Javafx maven plugin को टारगेट करें
javafx.run
।
- उस पर राइट-क्लिक किया और
Run Maven Build
या तो चुना Debug...
।
फिर ऐप बिना module-info.java
फाइल के चलेगा । मुझे लगता है कि यह इसलिए है क्योंकि मावेन प्लगइन गतिशील रूप से काफी स्मार्ट है जिसमें कुछ प्रकार की सेटिंग्स शामिल हैं जो कि ऐप को जावाएफएक्स कक्षाओं द्वारा बिना किसी module-info.java
फ़ाइल के भी प्रतिबिंबित करने की अनुमति देता है , हालांकि मुझे नहीं पता कि यह कैसे पूरा होता है।
उस टूल को शीर्ष टूलबार में रन बटन पर स्थानांतरित करने के लिए, javafx.run
मावेन लक्ष्य पर राइट-क्लिक करें और लक्ष्य के लिए विकल्प चुनें Create Run/Debug Configuration
। तब आप केवल मावेन लक्ष्य को निष्पादित करने के लिए शीर्ष टूलबार से रन चुन सकते हैं।