public static Collection<Class<?>> loadAllClassesFromJar(final File jarFile, final Class<?> superTypeClass) throws IOException { List<Class<?>> classes = JarReader.findConcreteSubtypesOfClass(jarFile, superTypeClass); final ProxyUtil<?> proxyUtil = new ProxyUtil<>(superTypeClass); return Collections2.filter(classes, new Predicate<Class<?>>() { @Override public boolean apply(@Nullable Class<?> s) { try { proxyUtil.loadClassFromJar(jarFile.getAbsolutePath(), s.getName()); return true; } catch (Throwable ex) { LOG.warn("class {} is concrete subtype of {}, but can't be initialized due to exception:", s, superTypeClass, ex); return false; } } }); }
/** * Find concrete (instantiable) subtypes of a given superType from file, * and return their reference Class objects. * * @param jarFile File object which points Jar file * @param superTypeClass type of class desired * @return list of classes * @throws IOException */ public static List<Class<?>> findConcreteSubtypesOfClass(File jarFile, Class superTypeClass) throws IOException { try (InputStream tmpFileInputStream = new FileInputStream(jarFile)) { List<String> classNames = JarReader.extractClassNames(tmpFileInputStream); URLClassLoader urlClassLoader = new URLClassLoader( new URL[] {new URL("file://" + jarFile.getAbsolutePath())}, Thread.currentThread().getContextClassLoader()); List<Class<?>> subTypeClasses = Lists.newArrayList(); for (String className : classNames) { try { Class<?> candidate = Class.forName(className, false, urlClassLoader); if (superTypeClass.isAssignableFrom(candidate) && isConcrete(candidate)) { subTypeClasses.add(candidate); } } catch (Throwable ex) { // noop... } } return subTypeClasses; } }