2010-11-18 18 views
10

कोई सुझाव classpath पर लोड के सभी निर्धारित?जावा: प्रोग्राम के रूप में मैं कैसे <strong>पैकेज के नाम</strong> कि <strong>वर्तमान classpath</strong> पर मौजूद हैं की एक सूची मिलेगा दृष्टिकोण पैकेज के नाम कैसे के रूप में

यह classpath पर लोड वर्गों में से एक (और क्रियान्वित) द्वारा रन टाइम पर प्रोग्राम के रूप में किया जाना चाहिए (अर्थात अंदर बाहर, नहीं बाहर में)।


अधिक विवरण:

एक दृष्टिकोण मैं माना वर्ग लोडर द्वारा अब तक भरी हुई वर्गों में से प्रत्येक पर प्रतिबिंब का उपयोग करने के लिए, और उन लोगों से पैकेज के नाम निकालने था। हालांकि, मेरा आवेदन पहले से ही हजारों वर्गों में चलता है, इसलिए मुझे एक और अधिक कुशल दृष्टिकोण की आवश्यकता है।

मुझे लगता है कि एक और चीज क्लास पथ में जेएआर फाइलें क्या थीं, और फिर प्रत्येक जार के लिए समानांतर सूची निर्देशिका करने के लिए समान थी। हालांकि, मुझे नहीं पता कि यह आवेदन के भीतर से/यह कैसे करना संभव है।

बोनस अंक जो कोई एक तरीका है कि शीर्ष स्तर के संकुल द्वारा फ़िल्टर कर सकते पता चलता है के लिए

बोनस अंक मिलेंगे। जैसे com.xyz ==>com.xyz.*, com.xyz.*.*

धन्यवाद के अंतर्गत आने वाले सभी पैकेज दिखाएं!

उत्तर

6

यदि आपको जार फ़ाइलों को माउंट और स्कैन करने की आवश्यकता है commons-vfs ने इसे बनाया है। यदि आपको उस मार्ग पर जाना है तो इससे चीज़ें थोड़ा आसान हो सकती हैं।

संपादित करें # 1: आप (उदाहरण के here से) तो जैसे classpath प्राप्त कर सकते हैं:

String strClassPath = System.getProperty("java.class.path"); 
System.out.println("Classpath is " + strClassPath); 
वहां से

आप स्थानीय फाइल सिस्टम कक्षाएं, जार देख सकते हैं, आदि

संपादित करें # 2:

import java.util.HashSet; 

import org.apache.commons.lang.StringUtils; 
import org.apache.commons.vfs.FileObject; 
import org.apache.commons.vfs.FileSystemManager; 
import org.apache.commons.vfs.FileType; 
import org.apache.commons.vfs.VFS; 

public class PackageLister { 

    private static HashSet<String> packageNames = new HashSet<String>(); 
    private static String localFilePath; 

    /** 
    * @param args 
    * @throws Throwable 
    */ 
    public static void main(final String[] args) throws Throwable { 
     FileSystemManager fileSystemManager = VFS.getManager(); 

     String[] pathElements = System.getProperty("java.class.path").split(";"); 
     for(String element : pathElements) { 
      if (element.endsWith("jar")) { 
       FileObject fileObject = fileSystemManager.resolveFile("jar://" + element); 
       addPackages(fileObject); 
      } 
      else { 
       FileObject fileObject = fileSystemManager.resolveFile(element); 
       localFilePath = fileObject.getName().getPath(); 

       addPackages(fileObject); 
      } 
     } 

     for(String name : packageNames) { 
      System.out.println(name); 
     } 
    } 

    private static void addPackages(final FileObject fileObject) throws Throwable { 
     FileObject[] children = fileObject.getChildren(); 
     for(FileObject child : children) { 
      if (!child.getName().getBaseName().equals("META-INF")) { 
       if (child.getType() == FileType.FOLDER) { 
        addPackages(child); 
       } 
       else if (child.getName().getExtension().equals("class")) { 
        String parentPath = child.getParent().getName().getPath(); 
        parentPath = StringUtils.remove(parentPath, localFilePath); 
        parentPath = StringUtils.removeStart(parentPath, "/"); 
        parentPath = parentPath.replaceAll("/", "."); 

        packageNames.add(parentPath); 
       } 
      } 
     } 
    } 
} 
+0

मुझे वीएफएस पता है लेकिन इस कार्यक्षमता के बारे में नहीं पता था। क्या आप कृपया एक टिप दे सकते हैं जो कक्षा कक्षा को स्कैन करने में मदद करती है? – AlexR

3

http://code.google.com/p/reflections/ एक शॉट दे दो: यहाँ वीएफएस साथ एक समाधान है।

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

2

इस कोड को आप (JRE पुस्तकालयों सहित) सभी classpath-प्रविष्टियों दे देंगे:

String[] entries = ClassPath.getClassPath().split(";"); 
for (String entry:entries) 
    System.out.println(entry); 

ClassPath अपाचे BCEL का हिस्सा है और JRE में एक आंतरिक (लेकिन प्रयोग करने योग्य) वर्ग के रूप में पाया जा सकता है (com.sun.org.apache.bcel.internal.util)। AFAIK, जब एक परियोजना को "असली" बीएसएल लाइब्रेरी की आवश्यकता होती है तो संघर्ष से बचने के लिए कक्षा "आंतरिक" होती है।

आप सभी सबडायरेक्टरियों जाएँ JRE के पुस्तकालयों फिल्टर करने के लिए चाहते हो सकता है

अगले कदम के प्रत्येक (JarFile-) प्रविष्टि पर विचार करना होगा (के रूप में इस असली classpath है वे शामिल रहे हैं), (रिकर्सिवली) और यदि (और केवल अगर) निर्देशिका में कम से कम एक वर्ग फ़ाइल होती है, तो इस निर्देशिका का नाम (क्लासपाथ एंट्री के सापेक्ष) को पैकेज नाम में परिवर्तित किया जा सकता है (उदाहरण: META_INF सभी जार फ़ाइलों में एक निर्देशिका है लेकिन नहीं एक पैकेज नाम ...)