From f1de7d058a8bf8ce8e80c6153593a3671823619d Mon Sep 17 00:00:00 2001 From: Ivan Pekov Date: Thu, 28 Oct 2021 19:55:52 +0300 Subject: [PATCH] Better FileUtil#findClass Issue #727 's CME roots come from FileUtil. This can be due to the previous implementation having 2 lists linking each other. This is removing 1 of the lists and handling on-the-go while also cleaning up the code a bit. Oh, and for the CloudExpansionManager change: I put it on the wrong spot the first time :P so yea --- .../manager/CloudExpansionManager.java | 8 ++-- .../me/clip/placeholderapi/util/FileUtil.java | 41 +++++++++---------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/expansion/manager/CloudExpansionManager.java b/src/main/java/me/clip/placeholderapi/expansion/manager/CloudExpansionManager.java index e0d57d7..346816f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/manager/CloudExpansionManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/manager/CloudExpansionManager.java @@ -104,6 +104,10 @@ public final class CloudExpansionManager { public void kill() { clean(); + ASYNC_EXECUTOR.shutdown(); + try { + ASYNC_EXECUTOR.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + } catch (InterruptedException ignored) {} } @NotNull @@ -167,10 +171,6 @@ public final class CloudExpansionManager { await.values().forEach(future -> future.cancel(true)); await.clear(); - ASYNC_EXECUTOR.shutdown(); - try { - ASYNC_EXECUTOR.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); - } catch (InterruptedException ignored) {} } public void fetch(final boolean allowUnverified) { diff --git a/src/main/java/me/clip/placeholderapi/util/FileUtil.java b/src/main/java/me/clip/placeholderapi/util/FileUtil.java index 825ff54..53741a1 100644 --- a/src/main/java/me/clip/placeholderapi/util/FileUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/FileUtil.java @@ -28,9 +28,11 @@ import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; public class FileUtil { @@ -41,37 +43,34 @@ public class FileUtil { return null; } - final URL jar = file.toURI().toURL(); - final URLClassLoader loader = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader()); - final List matches = new ArrayList<>(); - final List> classes = new ArrayList<>(); - - try (final JarInputStream stream = new JarInputStream(jar.openStream())) { - JarEntry entry; - while ((entry = stream.getNextJarEntry()) != null) { - final String name = entry.getName(); - if (name.isEmpty() || !name.endsWith(".class")) { + JarFile jar = new JarFile(file); + Enumeration entries = jar.entries(); + List> classes = new ArrayList<>(); + try (URLClassLoader loader = + new URLClassLoader(new URL[] {file.toURI().toURL()}, clazz.getClassLoader())) { + while (entries.hasMoreElements()) { + ZipEntry zip = entries.nextElement(); + JarEntry entry = jar.getJarEntry(zip.getName()); + if (entry == null) { continue; } - - matches.add(name.substring(0, name.lastIndexOf('.')).replace('/', '.')); - } - - for (final String match : matches) { + String name = entry.getName(); + if (!name.endsWith(".class")) { + continue; + } + name = name.substring(0, name.indexOf('.')).replace('/', '.'); try { - final Class loaded = loader.loadClass(match); + Class loaded = loader.loadClass(name); if (clazz.isAssignableFrom(loaded)) { classes.add(loaded.asSubclass(clazz)); } - } catch (final NoClassDefFoundError ignored) { + } catch (NoClassDefFoundError ignored) { } } } if (classes.isEmpty()) { - loader.close(); - return null; + return null; } return classes.get(0); } - }