Java Reflection: Lista klas w danym Package

0

Package pobieram za pomocą this.getClass().getPackage(). W jaki sposób mogę z niego pobrać listę wszystkich znajdujących się w danym Package klas?

0

Wprost chyba (wielkie chyba) się nie da, ale zawsze możesz wyciągnąć classpatha i sobie po nim przeiterować.

0

Użyłem kiedyś biblioteki, która robiła takie rzeczy. Radziła sobie nawet ze spakowanym JAR-em i wybierała klasy, które coś implementują lub rozszerzają. Nie mogę teraz tego znaleźć, ale jeśli problem się sam nie rozwiąże to przypomnij mi się na PW, to popołudniu to wygrzebię.

0

Mówisz chyba o Reflections, ale to nie wiedzieć czemu nie działa. Dzisiaj jednak spróbuję jeszcze raz.

0

W czystej Javie sie nie da, wynika to z faktu, ze bardzo czesto klasy z danego pakietu nie sa po prostu dostepne, i musialoby zbyt duzo zostac wczytane. Np. jak classpath sklada sie z 10 katalogow, 10 jarow, oraz 10 urli to wszystkie 30 musialyby byc sprawdzone czy nie zawieraja danego pakietu. Do tego dochodzi fakt, ze takie klasy bylyby wszystkie ladowane za jednym razem (chyba ze takie APi by zwracalo stringi) mimo ze czesto by nie musialy.
Sa do tego specjalne biblioteki, ktore wlasnie to robia - sciagaja wszystkie jary, iteruja po klasach itp. Dodatkowo potrafia sprawdzac interfejsy czy adnotacje, ale zamiast je ladowac do JVM, potrafia operaowac bezposrednio na bytach. Poszukaj w necie, to nie boli.

0

Udało mi się zrobić coś takiego samemu, ale tylko wtedy, gdy pliki .class są osobno, a nie spakowane w .jar. Za kilka godzin, gdy wrócę do domu, wyślę rozwiązanie, może ktoś wpadnie na pomysł uproszczenia.

0
public static Class[] getClassesFromPackage(Class cl) throws IOException, ClassNotFoundException {
        File f = new File(cl.getResource(cl.getSimpleName() + ".class").getFile());
        File[] pack = f.getParentFile().listFiles();
        Class[] classes = new Class[pack.length];
        for (int i = 0; i < pack.length; i++) {
            classes[i] = Class.forName(cl.getPackage().getName() + "." + pack[i].getName().replaceAll(".class", ""));
        }
        return classes;
    }

To działa wtedy, gdy klasy są "luźno", poza .JAR.

0

Polecam extensible-component-scanner. Działa w JAR-ach. U mnie szuka klas roszszerzających coś i będących w danym pakiecie:

		commandMap = new HashMap<>();

		final Set<Class<? extends Command>> classes = new HashSet<Class<? extends Command>>();

		ComponentScanner scanner = new ComponentScanner();
		scanner.getClasses(new ComponentQuery() {
			@Override
			protected void query() {
				select().from("pl.package.name.project.name.somethinh.else.consoleInterface.commands")
						.andStore(thoseExtending(Command.class).into(classes)).returning(none());
			}
		});
		if (classes.isEmpty()) {
			log.warn("Nie wczytałem żadnego polecenia do bazy konsoli zdalnej");
		}
		for (Class<? extends Command> comm : classes) {
			Command com;
			try {
				com = comm.newInstance();
				commandMap.put(com.getName().toLowerCase(), com);
			} catch (InstantiationException | IllegalAccessException e) {
				log.warn("Nie mogę wczytać komendy " + comm.getSimpleName(), e);
			}
		}

1 użytkowników online, w tym zalogowanych: 0, gości: 1