मैंने @Grodriguez और @bemace के उत्तरों को मिश्रित किया और एक सर्वोत्तम प्रयास समाधान के साथ आने के लिए अपनी रणनीति को जोड़ा। यह समाधान संकलन समय पर ऑटो-आयात सुविधा उपलब्ध रनटाइम पर अनुकरण करता है।
my solution is here का पूरा कोड। एक साधारण नाम दिया गया है, मुख्य चरण हैं:
- वर्तमान क्लासलोडर से सुलभ पैकेजों की एक सूची प्राप्त करें।
- प्रत्येक पैकेज के लिए, पैकेज + सरल नाम से प्राप्त पूर्णतः योग्य नाम लोड करने का प्रयास करें।
चरण 2 आसान है:
public List<String> getFQNs(String simpleName) {
if (this.packages == null) {
this.packages = getPackages();
}
List<String> fqns = new ArrayList<String>();
for (String aPackage : packages) {
try {
String fqn = aPackage + "." + simpleName;
Class.forName(fqn);
fqns.add(fqn);
} catch (Exception e) {
// Ignore
}
}
return fqns;
}
चरण 1 कठिन है और आपके आवेदन/पर्यावरण पर निर्भर है तो मैं संकुल की अलग-अलग सूचियां प्राप्त करने के लिए विभिन्न रणनीतियों को लागू करने।
वर्तमान classloader (गतिक रूप से उत्पन्न वर्गों का पता लगाने के उपयोगी हो सकता)
public Collection<String> getPackages() {
Set<String> packages = new HashSet<String>();
for (Package aPackage : Package.getPackages()) {
packages.add(aPackage.getName());
}
return packages;
}
क्लासपाथ (आवेदन कि पूरी तरह से लोड किए गए हैं classpath के लिए काफी अच्छा। ग्रहण की तरह जटिल अनुप्रयोगों के लिए अच्छा नहीं)
public Collection<String> getPackages() {
String classpath = System.getProperty("java.class.path");
return getPackageFromClassPath(classpath);
}
public static Set<String> getPackageFromClassPath(String classpath) {
Set<String> packages = new HashSet<String>();
String[] paths = classpath.split(File.pathSeparator);
for (String path : paths) {
if (path.trim().length() == 0) {
continue;
} else {
File file = new File(path);
if (file.exists()) {
String childPath = file.getAbsolutePath();
if (childPath.endsWith(".jar")) {
packages.addAll(ClasspathPackageProvider
.readZipFile(childPath));
} else {
packages.addAll(ClasspathPackageProvider
.readDirectory(childPath));
}
}
}
}
return packages;
}
बूटस्ट्रैप classpath (जैसे, java.lang)
public Collection<String> getPackages() {
// Even IBM JDKs seem to use this property...
String classpath = System.getProperty("sun.boot.class.path");
return ClasspathPackageProvider.getPackageFromClassPath(classpath);
}
ग्रहण बंडलों (डोमेन-विशिष्ट पैकेज प्रदाता)
// Don't forget to add "Eclipse-BuddyPolicy: global" to MANIFEST.MF
public Collection<String> getPackages() {
Set<String> packages = new HashSet<String>();
BundleContext context = Activator.getDefault().getBundle()
.getBundleContext();
Bundle[] bundles = context.getBundles();
PackageAdmin pAdmin = getPackageAdmin(context);
for (Bundle bundle : bundles) {
ExportedPackage[] ePackages = pAdmin.getExportedPackages(bundle);
if (ePackages != null) {
for (ExportedPackage ePackage : ePackages) {
packages.add(ePackage.getName());
}
}
}
return packages;
}
public PackageAdmin getPackageAdmin(BundleContext context) {
ServiceTracker bundleTracker = null;
bundleTracker = new ServiceTracker(context,
PackageAdmin.class.getName(), null);
bundleTracker.open();
return (PackageAdmin) bundleTracker.getService();
}
प्रश्नों और मेरी ग्रहण वातावरण में जवाब के उदाहरण:
- फ़ाइल: [java.io.File, org.eclipse.core.internal.resources.File]
- सूची: [java.awt.List, org.eclipse.swt.widgets.List, com.sun.xml.internal.bind.v2.schemage n.xmlschema.List, java.util.List, org.hibernate.mapping.List]
- IResource: [org.eclipse.core.resources.IResource]
मैं भी यकीन है कि आप कर सकते हैं कि नहीं कर रहा हूँ एक वर्ग लोडर से लोड कक्षाओं की सूची। यह आपकी मदद कर सकता है http://media.techtarget.com/tss/static/articles/content/dm_loadedClasses/executing.pdf –
@ कोलिन: फिर भी, यह आपको कक्षाओं को लोड करने देगा जो क्लास लोडर द्वारा पहले ही लोड हो चुके हैं, लेकिन कक्षाएं नहीं जो "रनटाइम पर उपलब्ध हैं"। AFAIK को यह जानने का कोई तरीका नहीं है कि किसी दिए गए वर्ग को लोड करने का प्रयास किए बिना उपलब्ध है या नहीं। – Grodriguez
@ ग्रोड्रिगेज: आप सही हैं कि जानने का कोई तरीका नहीं है। क्लास लोडर पर विचार करें जो रनटाइम पर बाइटकोड ऑन-द-फ्लाई उत्पन्न करते हैं। –