2012-12-19 18 views
11

Buduję aplikację Java, która ma wiele różnych pakietów. Chcę móc programowo informować, które pakiety istnieją w aplikacji, które zaczynają się od określonej poprawki wstępnej. Czy mimo to można to zrobić za pomocą interfejsów API Java Reflect? Nie widziałem czegoś podobnego do odbicia apis.Java Reflection - Uzyskaj listę pakietów

Przykład:

com.app.controls.text 
com.app.controls.picker 
com.app.controls.date 
etc 

chcę wyliczać wszystkie z nich wiedząc przedrostek „com.app.controls” i zrozumienia, że ​​nowy pakiet może uzyskać zintegrowane w przyszłości.

Dzięki!

Odpowiedz

16

Możesz to zrobić, używając Package.getPackages(), która zwraca tablicę wszystkich pakietów znanych z aktualnego programu ładującego klasy. Będziesz musiał ręcznie przechodzić przez tablicę i znajdować te z odpowiednim prefiksem, używając getName().

Oto krótki przykład:

public List<String> findPackageNamesStartingWith(String prefix) { 
    List<String> result = new ArrayList<>(); 
    for(Package p : Package.getPackages()) { 
     if (p.getName().startsWith(prefix)) { 
      result.add(p.getName()); 
     } 
    } 
    return result; 
} 

Należy zauważyć, że technika ta powróci tylko pakiety zdefiniowane w bieżącym ładującego klasy. Jeśli potrzebujesz pakiety z innej klasy loader, istnieje kilka możliwości:

  1. Rozmieszczanie rzeczy tak, że program może uruchomić powyższy kod z wewnątrz tej klasy loader. Wymaga to określonej organizacji do bazy kodu, co może, ale nie musi być możliwe.

  2. Użyj odbicia, aby wywołać metodę (zwykle chronioną) getPackages() w odpowiednim module ładującym klasy. To nie zadziała, jeśli program działa pod kontrolą bezpieczeństwa.

+0

Niestety pakiety nie są znane do bieżącego programu ładującego klasy. Czy istnieje inny możliwy sposób? –

+0

Prawdopodobnie nie, nie wyszczególniając ich wyraźnie. –

+0

@DerekGebhard: Przyszło mi do głowy dwie możliwości. Dodałem je do odpowiedzi. –

0

Pakiety ledwo istnieją z POV odbicia, są dość niewidoczne, z wyjątkiem klasowych.

0

podstawie Sean's answer i przy użyciu odbicia, aby uzyskać listę pakietów - ewentualnie ignorowania pustych:

/** 
* Finds all package names starting with prefix 
* @return Set of package names 
*/ 
public Set<String> findAllPackagesStartingWith(String prefix) { 
    List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>(); 
    classLoadersList.add(ClasspathHelper.contextClassLoader()); 
    classLoadersList.add(ClasspathHelper.staticClassLoader()); 
    Reflections reflections = new Reflections(new ConfigurationBuilder() 
      .setScanners(new SubTypesScanner(false), new ResourcesScanner()) 
      .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))) 
      .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("my.base.package")))); 
    Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class); 

    Set<String> packageNameSet = new TreeSet<String>(); 
    for (Class classInstance : classes) { 
     String packageName = classInstance.getPackage().getName(); 
     if (packageName.startsWith(prefix)) { 
      packageNameSet.add(packageName); 
     } 
    } 
    return packageNameSet; 
} 
+0

nie działa dla podpakietów – cyril

Powiązane problemy