I have this Java code, to get all classes in a package:
public static Set<Class> findAllClassesUsingClassLoader(String packageName) throws Exception {
InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(packageName.replaceAll("[.]", "/"));
System.out.println(packageName);
String text = new String(stream.readAllBytes(), StandardCharsets.UTF_8);
System.out.println(text);
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
return reader.lines().filter(line -> line.endsWith(".class")).map(line -> {
try {
System.out.println("HERE");
return getClass(line, packageName);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}).collect(Collectors.toSet());
}
public static Class getClass(String className, String packageName) throws Exception {
try {
return Class.forName(packageName + "." + className.substring(0, className.lastIndexOf('.')));
} catch (ClassNotFoundException e) {
throw new Exception("Class " + className + " not found!");
}
}
It works when I run it from the IDE, but when I run my application with java -jar
the InputStream is empty.
How can I change my code in order to make it work running it with java -jar
?
I found a solution to the problem:
Here's the code:
public static Set<Class<?>> getClassesFromResource(String packageName) throws Exception {
String packageFolder = packageName.replaceAll("[.]", "/");
Set<Class<?>> classes = new HashSet<Class<?>>();
URI resource = EntityDAOUtils.class.getClassLoader().getResource(packageFolder).toURI();
Path myPath = null;
if ("jar".equals(resource.getScheme())) {
for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {
if (provider.getScheme().equalsIgnoreCase("jar")) {
try {
myPath = provider.getFileSystem(resource).getPath(packageFolder);
} catch (FileSystemNotFoundException e) {
// in this case we need to initialize it first:
myPath = provider.newFileSystem(resource, Collections.emptyMap()).getPath(packageFolder);
}
}
}
}
Stream<Path> walk = Files.walk(myPath, 1);
for (Iterator<Path> it = walk.iterator(); it.hasNext();) {
String line = it.next().toString();
if (line.endsWith(".class")) {
classes.add(getClass(line.replace('/', '.').replace(".class", ""), packageName));
}
}
walk.close();
return classes;
}
public static Class getClass(String className, String packageName) throws Exception {
try {
return Class.forName(packageName + "." + className.substring(className.lastIndexOf('.') + 1));
} catch (ClassNotFoundException e) {
throw new Exception(
"Class " + packageName + "." + className.substring(className.lastIndexOf('.') + 1) + " not found!");
}
}