2010-11-18 31 views
10

Bất kỳ đề xuất nào về cách tiếp cận cách tôi sẽ tìm ra danh sách tên gói tồn tại trên đường dẫn lớp hiện tại hiện tại?Java: lập trình xác định tất cả tên gói được tải trên đường dẫn lớp

Điều này cần được thực hiện theo chương trình tại thời gian chạy bởi một trong các lớp được tải (và thực thi) trên đường dẫn lớp (ví dụ: bên trong ra ngoài, không nằm ngoài).


Thông tin chi tiết:

Một cách tiếp cận tôi coi là sử dụng phản ánh trên mỗi lớp được nạp vậy, đến nay bởi bộ nạp lớp, và trích xuất các tên gói từ họ. Tuy nhiên, ứng dụng của tôi đã chạy vào hàng nghìn lớp, vì vậy tôi cần một cách tiếp cận hiệu quả hơn.

Một thứ khác mà tôi cho là tương tự để tìm ra tệp JAR nào trong đường dẫn lớp và sau đó thực hiện danh sách thư mục song song cho mỗi JAR. Tuy nhiên, tôi không biết nếu điều này là có thể từ bên trong ứng dụng/làm thế nào để làm điều đó.

điểm thưởng

điểm thưởng cho bất cứ ai đề nghị một cách mà có thể lọc theo gói cấp cao nhất. Ví dụ. hiển thị tất cả các gói có dưới com.xyz ==>com.xyz.*, com.xyz.*.*

Cảm ơn!

Trả lời

6

Nếu bạn cần gắn kết và quét các tệp jar commons-vfs đã được tích hợp sẵn. Điều đó có thể giúp mọi việc dễ dàng hơn một chút nếu bạn phải đi tuyến đường đó.

EDIT # 1: Bạn có thể lấy classpath như vậy (từ ví dụ here):

String strClassPath = System.getProperty("java.class.path"); 
System.out.println("Classpath is " + strClassPath); 

Từ đó bạn có thể nhìn vào các lớp hệ thống tập tin địa phương, lọ vv

EDIT # 2: Đây là giải pháp với VFS:

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

Tôi biết VFS nhưng không biết về chức năng này. Bạn có thể đưa ra một mẹo mà lớp học giúp quét đường dẫn lớp không? – AlexR

3

Tặng http://code.google.com/p/reflections/ một ảnh.

Reflections quét classpath của bạn, chỉ số siêu dữ liệu, cho phép bạn truy vấn nó trên thời gian chạy và có thể lưu và thu thập thông tin cho nhiều module trong dự án của bạn.

2

Mã này sẽ cung cấp cho bạn tất cả classpath-mục (bao gồm cả các thư viện jre):

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

ClassPath là một phần của apache BCEL và có thể được tìm thấy như một lớp bên trong (nhưng có thể sử dụng) trong jre (com.sun.org.apache.bcel.internal.util). AFAIK, lớp này là "nội bộ" để tránh xung đột khi một dự án yêu cầu thư viện bcel "thực".

Bạn có thể muốn lọc các thư viện của JRE (họ đang có vì đây là thực classpath)

Bước tiếp theo sẽ được xem xét từng (JarFile-) nhập, hãy truy cập tất cả các thư mục con (đệ quy) và nếu (và chỉ nếu) một thư mục chứa ít nhất một tệp lớp, tên của thư mục này (có liên quan đến mục nhập classpath) có thể được chuyển đổi thành tên gói (ví dụ: META_INF là một thư mục trong tất cả các tệp jar chứ không phải tên gói ...)

Các vấn đề liên quan