2009-11-29 12 views
15

मान लें कि जावा कोडबेस में "com.example" नामक एक पैकेज है। किसी भी classloader अभी तक लोड नहीं किया गया है -क्या क्लासलोडर को पैकेज लोड करने के लिए मजबूर करने का कोई तरीका है, भले ही उसके किसी भी वर्ग को लोड नहीं किया गया हो?

क्रम में, हम बुला

Packages[] ps = Package.getPackages(); 

समस्या है द्वारा

Package p = Package.getPackage("com.example"); //(returns null) 

या यहाँ तक कि सभी संकुल की एक सूची प्राप्त फोन करके इस पैकेज प्राप्त कर सकते हैं पैकेज से वर्ग, यह इन फ़ंक्शन कॉल के लिए उपलब्ध नहीं होगा। हम इसे बल लोडिंग द्वारा पैकेज लोड करने के लिए पैकेज में वर्गों में से एक पहले, इस तरह मजबूर कर सकते हैं:

this.getClass().getClassLoader().loadClass("com.example.SomeClass"); 
Package p = Package.getPackage("com.example"); //(returns non-null) 

हालांकि, इस hacky है और समय से आगे जानने कुछ क्लास का नाम है कि के अंतर्गत आता है की आवश्यकता है पैकेज।

तो सवाल यह है कि क्या क्लासलोडर ने कुछ भी किया है या नहीं, इस पर ध्यान दिए बिना पैकेज का उदाहरण प्राप्त करने का कोई तरीका है? क्या इस धारणा में क्लासलोडिंग/पैकेज कैसे काम करते हैं, इस बारे में मेरी धारणाएं सही हैं?

+0

https://stackoverflow.com/questions/3455267/why-does-class-getpackage-return-the-same-package-for-classes-from-different-pac से सावधान रहें – Vadzim

उत्तर

11

वैकल्पिक रूप से आप कक्षा रूट निर्देशिका को प्रारंभिक बिंदु के रूप में उपयोग कर सकते हैं और सभी * .class फ़ाइलों और उप निर्देशिकाओं के माध्यम से चल सकते हैं। यह केवल तभी काम करेगा यदि आप जानते हैं कि आपकी सभी .class फ़ाइलें पहले से कहाँ रहेंगी।

इसका कारण यह है कि जावा में गतिशील क्लासलोडिंग है, इसलिए कक्षाओं को रनटाइम पर संकलित समय पर या स्टार्टअप समय पर भी ज्ञात स्थानों से लोड किया जा सकता है। इसलिए पैकेज की अवधारणा केवल लोड कक्षाओं के लिए एक नामस्थान है, न कि एक निर्देशिका जिसे आप उन्हें देखने के लिए उपयोग कर सकते हैं।

5

मुझे डर है कि आपकी धारणाएं मान्य नहीं हैं। कक्षाओं को लोड करने के रूप में क्लासलोडर्स पैकेज बुक-रख-रखाव करते हैं।

आप वाइल्डकार्ड को ClassLoader.getResources पर पास कर सकते हैं और इसे पैकेज में कक्षाएं लेने के लिए मजबूर कर सकते हैं, जो बदले में काम करेगा।

आप अपना खुद का क्लासलोडर बना सकते हैं जो definePackage पर कॉल करता है, लेकिन यह सामान्य वेनिला क्लासलोडर्स के उपयोग में आपकी सहायता नहीं करेगा।

5

मुझे लगता है कि आपको इसकी आवश्यकता है क्योंकि आपको इसकी टिप्पणियों का निरीक्षण करने की आवश्यकता है। अन्यथा आपको पैकेज संदर्भ रखने में कोई दिलचस्पी नहीं होगी, जो केवल एनोटेशन तक पहुंचने के आसपास ही हैं। इससे यह माना जाता है कि आपके पास कुछ एनोटेशन के साथ एक पैकेज-info.java भी परिभाषित किया गया है।

यदि आप java.lang.Package चेक करते हैं तो आप देखेंगे कि getPackageInfo केवल पैकेज-जानकारी क्लास को सामान्य कक्षा के रूप में लोड करता है।

मुझे एक ही समस्या थी और इस समाधान के साथ आया।

public static Package getPackage(String packageName) throws ClassNotFoundException { 
    Class.forName(packageName+".package-info"); // makes sure package info exist and that the class loader already knows about the package 
    return Package.getPackage(packageName); 
} 
संबंधित मुद्दे

 संबंधित मुद्दे