दिलचस्प पोस्ट
सरणी PHP करने के लिए सरणी? किसी तालिका के लिए मौजूदा AUTO_INCREMENT मान प्राप्त करें IPhone पर संपीड़न एपीआई PHP में दो स्ट्रिंग के बीच एक सबस्ट्रिंग कैसे प्राप्त करें? त्रुटि: मुख्य वर्ग को ढूंढ या लोड नहीं किया जा सका कैसे स्प्रिंग अनुप्रयोग में सिस्टम पर्यावरण चर को पढ़ने के लिए MySQL में ऑटो इंफिरिअम आईडी कॉलम के विखंडन को कैसे संभालना है I एकाधिक पैरामीटर को mysqli क्वेरी में बाँधें मैं ऊँचाई कैसे बदल सकता हूं: 0; ऊंचाई तक: ऑटो; सीएसएस का उपयोग कर? Java.util.Date को java.time.LocalDate में कनवर्ट करें बेहतर प्रदर्शन करने के लिए IOStream कैसे प्राप्त करें? ट्विटर बूटस्ट्रैप मॉडल बंद करने के लिए एक फ़ंक्शन बाँध लें वास्तव में अपरिवर्तनीय एक जावा स्ट्रिंग है? मध्य में शब्दों के साथ एक क्षैतिज रेखा के लिए सीएसएस तकनीक कैसे कंसोल अनुप्रयोग में प्रमुख प्रेस घटना को संभालने के लिए

मैं क्लासपाथ में एक जावा पैकेज से सभी वर्गों को कैसे पढ़ूं?

मुझे एक जावा पैकेज में निहित वर्गों को पढ़ने की आवश्यकता है। उन कक्षाएं कक्षापथ में हैं मुझे यह काम सीधे जावा प्रोग्राम से करना होगा क्या आप एक साधारण तरीका जानते हैं?

List<Class> classes = readClassesFrom("my.package") 

वेब के समाधान से एकत्रित समाधान "मैं क्लासपाथ में एक जावा पैकेज से सभी वर्गों को कैसे पढ़ूं?"

यदि आपके पास स्प्रिंग में कक्षा की है तो निम्नलिखित में यह करना होगा।

XmlRootElement के साथ एनोटेट किए गए पैकेज में सभी वर्गों को ढूंढें:

 private List<Class> findMyTypes(String basePackage) throws IOException, ClassNotFoundException { ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver); List<Class> candidates = new ArrayList<Class>(); String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + "**/*.class"; Resource[] resources = resourcePatternResolver.getResources(packageSearchPath); for (Resource resource : resources) { if (resource.isReadable()) { MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource); if (isCandidate(metadataReader)) { candidates.add(Class.forName(metadataReader.getClassMetadata().getClassName())); } } } return candidates; } private String resolveBasePackage(String basePackage) { return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage)); } private boolean isCandidate(MetadataReader metadataReader) throws ClassNotFoundException { try { Class c = Class.forName(metadataReader.getClassMetadata().getClassName()); if (c.getAnnotation(XmlRootElement.class) != null) { return true; } } catch(Throwable e){ } return false; } 

आप यहाँ वर्णित प्रतिबिंब परियोजना का उपयोग कर सकते हैं

यह काफी पूर्ण और उपयोग में आसान है

उपरोक्त वेबसाइट से संक्षिप्त विवरण:

प्रतिबिंब आपकी क्लासपाथ को स्कैन करता है, मेटाडेटा को अनुक्रमित करता है, आप इसे रनटाइम पर पूछताछ करने की अनुमति देता है और आपकी प्रोजेक्ट में कई मॉड्यूल्स के लिए उस जानकारी को बचा सकता है और इकट्ठा कर सकता है।

उदाहरण:

 Reflections reflections = new Reflections( new ConfigurationBuilder() .setUrls(ClasspathHelper.forJavaClassPath()) ); Set<Class<?>> types = reflections.getTypesAnnotatedWith(Scannable.class); 

मैं इसका उपयोग करता हूं, यह फाइल या जार अभिलेखागार के साथ काम करता है

 public static ArrayList<String>getClassNamesFromPackage(String packageName) throws IOException{ ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL packageURL; ArrayList<String> names = new ArrayList<String>();; packageName = packageName.replace(".", "/"); packageURL = classLoader.getResource(packageName); if(packageURL.getProtocol().equals("jar")){ String jarFileName; JarFile jf ; Enumeration<JarEntry> jarEntries; String entryName; // build jar file name, then loop through zipped entries jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8"); jarFileName = jarFileName.substring(5,jarFileName.indexOf("!")); System.out.println(">"+jarFileName); jf = new JarFile(jarFileName); jarEntries = jf.entries(); while(jarEntries.hasMoreElements()){ entryName = jarEntries.nextElement().getName(); if(entryName.startsWith(packageName) && entryName.length()>packageName.length()+5){ entryName = entryName.substring(packageName.length(),entryName.lastIndexOf('.')); names.add(entryName); } } // loop through files in classpath }else{ URI uri = new URI(packageURL.toString()); File folder = new File(uri.getPath()); // won't work with path which contains blank (%20) // File folder = new File(packageURL.getFile()); File[] contenuti = folder.listFiles(); String entryName; for(File actual: contenuti){ entryName = actual.getName(); entryName = entryName.substring(0, entryName.lastIndexOf('.')); names.add(entryName); } } return names; } 

स्प्रिंग ने PathMatchingResourcePatternResolver में एक उत्कृष्ट PathMatchingResourcePatternResolver खोज खोज कार्यान्वित की है। यदि आप classpath* : उपसर्ग का उपयोग करते हैं, तो आप किसी दिए गए पदानुक्रम में वर्गों सहित सभी संसाधनों को पा सकते हैं, और यदि आप चाहें तो उन्हें फ़िल्टर भी कर सकते हैं। फिर आप AbstractTypeHierarchyTraversingFilter AssignableTypeFilter , AnnotationTypeFilter AssignableTypeFilter और AssignableTypeFilter के बच्चों का उपयोग उन वर्गों के एनोटेशन पर या उन इंटरफेसों पर फ़िल्टर करने के लिए कर सकते हैं जो वे लागू करते हैं।

जावा 1.6.0_24:

 public static File[] getPackageContent(String packageName) throws IOException{ ArrayList<File> list = new ArrayList<File>(); Enumeration<URL> urls = Thread.currentThread().getContextClassLoader() .getResources(packageName); while (urls.hasMoreElements()) { URL url = urls.nextElement(); File dir = new File(url.getFile()); for (File f : dir.listFiles()) { list.add(f); } } return list.toArray(new File[]{}); } 

यह समाधान ईजेबी पर्यावरण के भीतर परीक्षण किया गया था।

स्कैनोटेशन और रिफ्लेक्शंस वर्ग पथ स्कैनिंग दृष्टिकोण का उपयोग करते हैं:

 Reflections reflections = new Reflections("my.package"); Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class); 

एक और तरीका है एनोटेशन प्रोसेसर लिखने के लिए जावा प्लगेबल एनोटेशन प्रोसेसिंग एपीआई का उपयोग करना जो कि समयबद्धता के दौरान सभी एनोटेटेड क्लास एकत्र करेगा और रनटाइम के उपयोग के लिए सूचकांक फाइल का निर्माण करेगा। यह तंत्र क्लासइंडएक्स लाइब्रेरी में लागू किया गया है:

 Iterable<Class> classes = ClassIndex.getPackageClasses("my.package"); 

जहां तक ​​मुझे पता है कि यह कार्यक्षमता अभी भी जावा प्रतिबिंब एपीआई से संदेह से गुम है। आप ऐसा करने से एक पैकेज वस्तु प्राप्त कर सकते हैं:

 Package packageObj = Package.getPackage("my.package"); 

लेकिन जैसा कि आपने शायद देखा है, वह आपको उस पैकेज में कक्षाओं की सूची नहीं देगा। अभी के रूप में, आपको एक और फाइलसिस्टम-उन्मुख दृष्टिकोण का होना चाहिए।

मैंने इस पोस्ट में कुछ नमूना लागूकरण पाया

मैं 100% यकीन नहीं है कि इन तरीकों से काम होगा जब आपकी कक्षाएं जार फाइल में दफन हो जाएंगी, लेकिन मुझे आशा है कि उनमें से एक आपके लिए यह करता है।

मैं @ एसएफ़फ़ैमैन से सहमत हूं … यदि आपके पास इसके बारे में जानने का एक और तरीका है, तो मैं इसके बदले यह करने की सिफारिश करता हूं।

आप अपने पुस्तकालय FastClasspathScanner कोशिश कर सकते क्लासपाथ को स्कैन करने से जावा। java.class.path संपत्ति की जांच के रूप में सरल नहीं है, और कक्षाओं के लिए फिर से स्कैन किया जा रहा है, क्योंकि कई तरीके हैं कि क्लासपाथ निर्दिष्ट किया जा सकता है (उदाहरण के लिए आप Class-Path प्रविष्टियों को एक जर्फाइल के मैनिफेस्ट में जोड़ सकते हैं)। Class.forName () का उपयोग करना वास्तव में कक्षा को आरंभ करता है, जो हो सकता है कि आप क्या चाहते हों, आदि। FastClasspathScanner आपके लिए इन जटिलताओं का प्रबंधन करता है

पैकेज में सभी वर्गों की गणना करने के लिए, निम्न करें:

 String packageName = "my.package"; Set<String> classNames = new FastClassPathScanner(packageName) .scan() .getNamesOfAllClasses(); String packageNamePrefix = packageName + "."; for (String className : classNames) { if (className.startsWith(packageNamePrefix) { System.out.println("Found class: " + className); } } 

आपको जांच की ज़रूरत है if (className.startsWith(packageNamePrefix) क्योंकि अगर कोई क्लास दूसरे वर्ग (जैसे एक if (className.startsWith(packageNamePrefix) को संदर्भित करता है, और यह श्वेतसूचीबद्ध पैकेज उपसर्ग my.package के बाहर है, तो इसे .getNamesOfAllClasses() द्वारा लौटाए गए सेट में शामिल किया .getNamesOfAllClasses()

मैं इसे लागू किया है, और यह ज्यादातर मामलों में काम करता है। चूंकि यह बहुत लंबा है, इसलिए मैं इसे एक फाइल में डाल दिया।

यह विचार वर्ग स्रोत फ़ाइल का स्थान ढूंढना है जो ज्यादातर मामलों में उपलब्ध है (एक ज्ञात अपवाद JVM वर्ग की फ़ाइलें हैं – जहां तक ​​मैंने परीक्षण किया है)। यदि कोड किसी निर्देशिका में है, तो सभी फ़ाइलों और केवल स्पॉट क्लास फ़ाइलों के माध्यम से स्कैन करें। यदि कोड किसी JAR फ़ाइल में है, तो सभी प्रविष्टियों को स्कैन करें।

इस पद्धति का उपयोग तब ही किया जा सकता है जब:

  1. आपके पास एक ऐसा वर्ग है जिसे आप खोजना चाहते हैं उसी पैकेज में है, इस वर्ग को सीडक्लास कहा जाता है उदाहरण के लिए, यदि आप 'java.io' में सभी वर्गों को सूचीबद्ध करना चाहते हैं, तो बीज वर्ग java.io.File हो सकता है

  2. आपकी कक्षाएं एक निर्देशिका या एक JAR फ़ाइल में हैं, जिसमें स्रोत फाइल जानकारी है (स्रोत कोड फ़ाइल नहीं, बल्कि सिर्फ स्रोत फ़ाइल)। जहां तक ​​मैंने कोशिश की है, यह जेवीएम कक्षा को छोड़कर लगभग 100% काम करता है (उन कक्षाएं जेवीएम के साथ आती हैं)

  3. आपके प्रोग्राम को उन कक्षाओं के संरक्षणदान का उपयोग करने की अनुमति होनी चाहिए। यदि आपका प्रोग्राम स्थानीय स्तर पर लोड हो रहा है, तो कोई समस्या नहीं होनी चाहिए।

मैंने केवल अपने नियमित उपयोग के लिए कार्यक्रम का परीक्षण किया है, इसलिए यह अभी भी समस्या हो सकती है

आशा है कि ये आपकी मदद करेगा।

एक्टेक्सस आशाजनक लग रहा है कल्पना कीजिए कि आप सभी वर्गों को खोजना चाहते हैं जो:

  1. वर्ग "घटक" से बढ़ाएं, और उन्हें स्टोर करें
  2. "MyComponent" के साथ एनोटेट किया गया है, और
  3. "सामान्य" पैकेज में हैं

एक्स्टिक्स के साथ यह उतना आसान है जितना

 ClasspathScanner scanner = new ClasspathScanner(); final Set<Class> classStore = new ArraySet<Class>(); Set<Class> classes = scanner.getClasses(new ClassQuery() { protected void query() { select(). from(“common”). andStore(thoseExtending(Component.class).into(classStore)). returning(allAnnotatedWith(MyComponent.class)); } }); 
  1. बिल बर्क ने एक (क्लास स्कैनिंग के बारे में अच्छा लेख ) लिखा है और फिर उन्होंने स्कैनोटेशन लिखा है।

  2. सीतनिद्रा में होना पहले से ही लिखा है:

    • org.hibernate.ejb.packaging.Scanner
    • org.hibernate.ejb.packaging.NativeScanner
  3. सीडीआई इसका समाधान कर सकता है, लेकिन पता नहीं है – अभी तक पूरी तरह से जांच नहीं की है

 @Inject Instance< MyClass> x; ... x.iterator() 

एनोटेशन के लिए:

 abstract class MyAnnotationQualifier extends AnnotationLiteral<Entity> implements Entity {} 

यहाँ एक और विकल्प है, ऊपर / नीचे में एक और उत्तर के लिए मामूली संशोधन:

 Reflections reflections = new Reflections("com.example.project.package", new SubTypesScanner(false)); Set<Class<? extends Object>> allClasses = reflections.getSubTypesOf(Object.class); 

वापस जब ऐपलेट सामान्य स्थान थे, तो उसके पास एक क्लासपाथ पर यूआरएल हो सकता था। जब क्लासलोडर को एक कक्षा की आवश्यकता होती है, तो वह सभी स्थानों को कक्षा के रास्ते खोजती है, जिसमें http संसाधन शामिल हैं। क्योंकि क्लासपाथ पर यूआरएल और निर्देशिका जैसी चीज़ें हो सकती हैं, कक्षाओं की एक निश्चित सूची प्राप्त करने का कोई आसान तरीका नहीं है।

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

प्रोजेक्ट ldapbeans एक क्लास स्कैनर प्रदान करता है जो ऐसा करते हैं।

निर्भरता मेवेन का उपयोग करें:

 groupId: net.sf.extcos artifactId: extcos version: 0.4b 

तो इस कोड का उपयोग करें:

 ComponentScanner scanner = new ComponentScanner(); Set classes = scanner.getClasses(new ComponentQuery() { @Override protected void query() { select().from("com.leyton").returning(allExtending(DynamicForm.class)); } }); 

ब्रेंट – कारण एसोसिएशन एक तरीका है इस तथ्य के साथ क्या करना है कि आपके क्लासस्पैट के किसी भी घटक पर कोई भी वर्ग खुद को किसी भी पैकेज में घोषित कर सकता है (जावा / जावा के अलावा)। इस प्रकार, किसी दिए गए "पैकेज" में सभी वर्गों का कोई मानचित्रण नहीं है क्योंकि कोई भी नहीं जानता और न ही जान सकता है। आप कल जार फ़ाइल अपडेट कर सकते हैं और कक्षाएं हटा सकते हैं या जोड़ सकते हैं। यह दुनिया के सभी देशों में जॉन / जॉन / जोहान नामक सभी लोगों की एक सूची प्राप्त करने की कोशिश करने की तरह है – हममें से कोई भी सर्वज्ञ नहीं है इसलिए हम में से कोई भी सही जवाब कभी नहीं देगा।