From 1215a52d090b762303cd7eb4e6076cdcf435b1cc Mon Sep 17 00:00:00 2001 From: libinglong <38123153+libinglong@users.noreply.github.com> Date: Thu, 23 Jul 2020 21:51:30 +0800 Subject: [PATCH] Concurrent accessing allJars causes the plugin to fail to load (#5158) Another thread could get the list which is still in the initialization stage, due to first element added. So we need a local variable to avoid this. Also, notice this happens only in concurrency class loader env. --- .../core/plugin/loader/AgentClassLoader.java | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/loader/AgentClassLoader.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/loader/AgentClassLoader.java index 9b46c1476..659712f4a 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/loader/AgentClassLoader.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/loader/AgentClassLoader.java @@ -174,22 +174,7 @@ public class AgentClassLoader extends ClassLoader { jarScanLock.lock(); try { if (allJars == null) { - allJars = new LinkedList<>(); - for (File path : classpath) { - if (path.exists() && path.isDirectory()) { - String[] jarFileNames = path.list((dir, name) -> name.endsWith(".jar")); - for (String fileName : jarFileNames) { - try { - File file = new File(path, fileName); - Jar jar = new Jar(new JarFile(file), file); - allJars.add(jar); - logger.info("{} loaded.", file.toString()); - } catch (IOException e) { - logger.error(e, "{} jar file can't be resolved", fileName); - } - } - } - } + allJars = doGetJars(); } } finally { jarScanLock.unlock(); @@ -199,6 +184,26 @@ public class AgentClassLoader extends ClassLoader { return allJars; } + private LinkedList doGetJars() { + LinkedList jars = new LinkedList<>(); + for (File path : classpath) { + if (path.exists() && path.isDirectory()) { + String[] jarFileNames = path.list((dir, name) -> name.endsWith(".jar")); + for (String fileName : jarFileNames) { + try { + File file = new File(path, fileName); + Jar jar = new Jar(new JarFile(file), file); + jars.add(jar); + logger.info("{} loaded.", file.toString()); + } catch (IOException e) { + logger.error(e, "{} jar file can't be resolved", fileName); + } + } + } + } + return jars; + } + @RequiredArgsConstructor private static class Jar { private final JarFile jarFile;