अवैध चिंतनशील पहुंच क्या है


126

जावा 9 में अवैध चिंतनशील पहुंच के बारे में बहुत सारे सवाल हैं।

अब मुझे जो नहीं मिल रहा है, क्योंकि सभी Google द्वारा चलाए गए लोग त्रुटि संदेशों के आसपास काम करने की कोशिश कर रहे हैं, वास्तव में एक अवैध चिंतनशील पहुंच क्या है।

तो मेरा सवाल काफी सरल है:

एक अवैध चिंतनशील पहुंच को परिभाषित करता है और किन परिस्थितियों में चेतावनी ट्रिगर होती है?

मैंने पाया है कि जावा 9 में पेश किए गए एनकैप्सुलेशन सिद्धांतों के साथ इसका कुछ लेना-देना है, लेकिन यह सब एक साथ कैसे लटका रहता है और किस परिस्थिति में चेतावनी को ट्रिगर करता है, इसका स्पष्टीकरण मुझे नहीं मिल सकता है।


2
यह आपको रूचि दे सकता है: jaxenter.com/jdk-9-replace-permit-illegal-access-134180.html
एडविन

जवाबों:


54

मॉड्यूल और उनके संबंधित पैकेजों के बीच पहुंच की समझ के अलावा। मेरा मानना ​​है कि इसका क्रेज मॉड्यूल सिस्टम # रिलैक्स्ड-स्ट्रॉन्ग-इनकैप्सुलेशन में निहित है और मैं सवाल पूछने और जवाब देने के लिए इसके संबंधित हिस्सों को चेरी-पिक करूंगा।

एक अवैध चिंतनशील पहुंच को परिभाषित करता है और किन परिस्थितियों में चेतावनी ट्रिगर होती है?

जावा -9 के प्रवास में सहायता के लिए, मॉड्यूल के मजबूत इनकैप्सुलेशन को शिथिल किया जा सकता है।

  • एक कार्यान्वयन स्थिर पहुंच प्रदान कर सकता है , अर्थात संकलित बायटेकोड द्वारा।

  • मई अपने रन-टाइम सिस्टम को एक या अधिक मॉड्यूल के एक या अधिक पैकेजों के साथ लागू करने का साधन प्रदान करता है जो सभी अनाम मॉड्यूल में कोड करने के लिए खुले होते हैं , अर्थात क्लासपैथ पर कोड करने के लिए। यदि रन-टाइम सिस्टम को इस तरह से लागू किया जाता है, और यदि ऐसा करने से प्रतिबिंब एपीआई के कुछ चालान सफल होते हैं, तो अन्यथा वे विफल हो जाते।

ऐसे मामलों में, आपने वास्तव में एक चिंतनशील पहुंच बना ली है जो "अवैध" है क्योंकि शुद्ध मॉड्यूलर दुनिया में आप इस तरह की एक्सेस करने के लिए नहीं थे।

यह सब कैसे एक साथ लटका रहता है और किस परिदृश्य में चेतावनी को ट्रिगर करता है?

--illegal-accessएनकैप्सुलेशन की इस छूट को रनटाइम पर एक नए लॉन्चर विकल्प द्वारा नियंत्रित किया जाता है जो कि जावा 9 में डिफ़ॉल्ट रूप से होता है permitpermitमोड सुनिश्चित

ऐसे किसी भी पैकेज के लिए पहला रिफ्लेक्टिव-एक्सेस ऑपरेशन एक चेतावनी जारी करने का कारण बनता है, लेकिन उस बिंदु के बाद कोई चेतावनी जारी नहीं की जाती है। यह एकल चेतावनी बताती है कि आगे की चेतावनी को कैसे सक्षम किया जाए। इस चेतावनी को दबाया नहीं जा सकता।

मोड मूल्यों के साथ कॉन्फ़िगर करने योग्य हैं debug(संदेश और साथ ही ऐसी हर एक्सेस के लिए स्टैकट्रेस), warn(प्रत्येक ऐसी एक्सेस के लिए संदेश), और deny(इस तरह के संचालन को अक्षम करता है)।


अनुप्रयोगों पर डिबग और फिक्स करने के लिए कुछ चीजें होंगी: -

  • इसके --illegal-access=denyबारे में जानने के लिए इसे चलाएं और वीएम एर्ग के ऐसे निर्देश ( ) या स्पष्ट उपयोग सहित मॉड्यूल घोषणा के बिना एक मॉड्यूल से दूसरे में खुले आईएनजी पैकेज से बचें ।opens--add-opens
  • संकलित कोड से JDK- आंतरिक APIs के स्थिर संदर्भों jdepsको --jdk-internalsविकल्प के साथ उपकरण का उपयोग करके पहचाना जा सकता है

अवैध चिंतनशील-पहुंच संचालन का पता चलने पर जारी किया गया चेतावनी संदेश निम्न रूप में है:

WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM

कहाँ पे:

$PERPETRATOR उस प्रकार का पूरी तरह से योग्य नाम है जिसमें कोड शामिल है जो प्रश्न में चिंतनशील संचालन को लागू करता है और यदि उपलब्ध हो तो कोड स्रोत (यानी, JAR- फ़ाइल पथ), और

$VICTIM एक स्ट्रिंग है जो सदस्य को एक्सेस करने का वर्णन करता है, जिसमें पूरी तरह से योग्य नाम संलग्नक प्रकार शामिल है

इस तरह के एक नमूना चेतावनी के लिए प्रश्न: = JDK9: एक अवैध चिंतनशील पहुंच संचालन हुआ है। org.python.core.PySystemState

अंतिम और एक महत्वपूर्ण नोट, यह सुनिश्चित करने की कोशिश करते हुए कि आप इस तरह की चेतावनियों का सामना नहीं करते हैं और भविष्य में सुरक्षित हैं, आपको बस यह सुनिश्चित करने की आवश्यकता है कि आपके मॉड्यूल उन अवैध चिंतनशील पहुंचों को नहीं बना रहे हैं। :)


21

जावा 9 मॉड्यूल सिस्टम के संबंध में एक ओरेकल लेख है

डिफ़ॉल्ट रूप से, एक मॉड्यूल में एक प्रकार अन्य मॉड्यूल के लिए सुलभ नहीं है जब तक कि यह एक सार्वजनिक प्रकार नहीं है और आप इसके पैकेज को निर्यात करते हैं। आप केवल उन पैकेजों को उजागर करते हैं जिन्हें आप उजागर करना चाहते हैं। जावा 9 के साथ, यह भी प्रतिबिंब पर लागू होता है।

जैसा कि https://stackoverflow.com/a/50251958/134894 में बताया गया है , AccessibleObject#setAccessibleJDK8 और JDK9 के बीच अंतर शिक्षाप्रद है। विशेष रूप से, JDK9 गयी

इस विधि का उपयोग कक्षा C में एक कॉलर द्वारा निम्नलिखित में से किसी एक वर्ग D को घोषित कक्षा के सदस्य तक पहुँच के लिए किया जा सकता है:

  • C और D एक ही मॉड्यूल में हैं।
  • सदस्य सार्वजनिक होता है और D एक पैकेज में सार्वजनिक होता है कि D युक्त मॉड्यूल कम से कम C वाले मॉड्यूल को निर्यात करता है।
  • सदस्य को स्थैतिक संरक्षित किया जाता है, डी एक पैकेज में सार्वजनिक होता है कि डी युक्त मॉड्यूल कम से कम सी युक्त मॉड्यूल को निर्यात करता है, और सी डी का एक उपवर्ग है।
  • D एक ऐसे पैकेज में है, जिसमें D वाला मॉड्यूल कम से कम मॉड्यूल को खोलता है। C. जिसमें अनाम और खुले मॉड्यूल में सभी पैकेज सभी मॉड्यूल के लिए खुले हैं और इसलिए यह तरीका हमेशा सफल होता है जब D एक अनाम या खुले मॉड्यूल में होता है।

जो मॉड्यूल और उनके निर्यात के महत्व पर प्रकाश डालता है (जावा 9 में)


2
इसलिए यदि मैं उस लेख को सही ढंग से पढ़ता हूँ तो निर्यात की गई कक्षाओं में निजी संपत्तियों को संशोधित करना टेबल से दूर है। केवल संरक्षित और सार्वजनिक संपत्तियों को संशोधित किया जा सकता है। अब मैं जावा इंटर्नल एक्सपोर्ट्स के बारे में ज्यादा परवाह नहीं करता, लेकिन तीसरी पार्टी लाइब्रेरियों के बारे में जहां मुझे कभी-कभी एक विशिष्ट मूल्य पर सेट होने के लिए एक निजी चर तक पहुंच की आवश्यकता होती है। इस योजना में अब यह संभव नहीं होगा यदि यह खुद को एक मॉड्यूल के रूप में परिभाषित करेगा, क्या यह सही है?
त्चलाकैक

1
मेरे पास इसका प्रत्यक्ष अनुभव नहीं है, लेकिन यह मेरी समझ होगी, और कहीं और उल्लिखित लेख के साथ पढ़ें ( jaxenter.com/jdk-9-replace-permit-illegal-access-134180.html ) जो ऐसा प्रतीत होगा मुकदमा। अपने JVM को –illegal-access=permit...
पोमाली

1
ठीक है कि चीजों को और अधिक रोचक बनाने की कोशिश की जा रही है ताकि कुछ चीजों के लिए काम करने की कोशिश की जाए जब वे मॉड्यूल तरीके से जाने का फैसला करते हैं। सुपर मजेदार समय आगे।
सिकलचैक

1
के विभिन्न मूल्यों के लिएfun
ptomli

मैंने अन्य उत्तर को स्वीकार कर लिया क्योंकि यह अधिक स्पष्टीकरण प्रदान करता था और प्रश्न का उत्तर अधिक था लेकिन दुख की बात है कि मैं दो उत्तरों को स्वीकार नहीं कर सकता।
सिकलचैक

13

फ़ील्ड और विधियों setAccessible()तक पहुँचने के लिए उपयोग की जाने वाली विधि को देखें private:

https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-

https://docs.oracle.com/javase/9/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-

अब इस विधि के काम करने के लिए और भी बहुत सी शर्तें आवश्यक हैं। एकमात्र कारण यह लगभग सभी पुराने सॉफ़्टवेयर को नहीं तोड़ता है, सादे JAR से ऑटोजेनरेटेड मॉड्यूल बहुत अनुज्ञेय हैं (सभी के लिए सब कुछ खोलें और निर्यात करें)।


1

यदि आप ऐड-ओपन विकल्प के साथ जाना चाहते हैं, तो यहां यह पता लगाने के लिए एक कमांड है कि कौन सा मॉड्यूल कौन सा पैकेज प्रदान करता है ->

java --list-modules | tr @ " " | awk '{ print $1 }' | xargs -n1 java -d

मॉड्यूल का नाम @ के साथ दिखाया जाएगा, जबकि इसके बिना संकुल का नाम

नोट: JDK 11 के साथ परीक्षण किया गया

महत्वपूर्ण: स्पष्ट रूप से बेहतर है कि पैकेज के प्रदाता अवैध पहुंच नहीं करता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.