From d4aa56b740e05c30448d16427ba4d527b7a551a4 Mon Sep 17 00:00:00 2001 From: StaticDefault Date: Thu, 28 Nov 2019 21:05:18 +0900 Subject: [PATCH] Fixed class finder jar entry error. --- .../reflection/classfile/ClassFinder.java | 66 +++++++++++-------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/realtimetech/reflection/classfile/ClassFinder.java b/src/main/java/com/realtimetech/reflection/classfile/ClassFinder.java index 195dc0a..ea1c93a 100644 --- a/src/main/java/com/realtimetech/reflection/classfile/ClassFinder.java +++ b/src/main/java/com/realtimetech/reflection/classfile/ClassFinder.java @@ -1,26 +1,20 @@ package com.realtimetech.reflection.classfile; -import java.io.File; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.FileSystemNotFoundException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; import java.util.Enumeration; import java.util.LinkedList; -import java.util.List; +import java.util.stream.Stream; public class ClassFinder { - private static void recursiveSearch(File directory, String packageName, List> resultClasses) throws ClassNotFoundException { - if (directory.exists()) { - File[] files = directory.listFiles(); - for (File file : files) { - if (file.isDirectory()) { - recursiveSearch(file, packageName + "." + file.getName(), resultClasses); - } else if (file.getName().endsWith(".class")) { - resultClasses.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6))); - } - } - } - } - public static Class[] getClassInPackages(Class packageInClass) throws IOException { return getClassInPackages(packageInClass.getPackageName()); } @@ -28,21 +22,39 @@ public static Class[] getClassInPackages(Class packageInClass) throws IOEx public static Class[] getClassInPackages(String... packageNames) throws IOException { LinkedList> resultClasses = new LinkedList>(); - for(String packageName : packageNames) { - String path = packageName.replace('.', '/'); - - Enumeration resources = Thread.currentThread().getContextClassLoader().getResources(path); - List directories = new LinkedList(); + for (String packageName : packageNames) { + String packagePath = packageName.replace('.', '/'); + Enumeration resources = Thread.currentThread().getContextClassLoader().getResources(packagePath); while (resources.hasMoreElements()) { - URL resource = resources.nextElement(); - directories.add(new File(resource.getFile())); - } - - for (File directory : directories) { try { - recursiveSearch(directory, packageName, resultClasses); - } catch (ClassNotFoundException e) { + URL resource = resources.nextElement(); + URI packageUri = resource.toURI(); + + Path root; + + if (packageUri.toString().startsWith("jar:")) { + try { + root = FileSystems.getFileSystem(packageUri).getPath(packagePath); + } catch (final FileSystemNotFoundException e) { + root = FileSystems.newFileSystem(packageUri, Collections.emptyMap()).getPath(packagePath); + } + } else { + root = Paths.get(packageUri); + } + + final String extension = ".class"; + try (final Stream allPaths = Files.walk(root)) { + allPaths.filter(Files::isRegularFile).forEach(file -> { + try { + final String path = file.toString().replace('/', '.'); + final String name = path.substring(path.indexOf(packageName), path.length() - extension.length()); + resultClasses.add(Class.forName(name)); + } catch (final ClassNotFoundException | StringIndexOutOfBoundsException ignored) { + } + }); + } + } catch (URISyntaxException e) { } } }