1 package org.owasp.dependencycheck;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.lang.instrument.Instrumentation;
6 import java.util.jar.JarFile;
7
8 /**
9 * Java agent for loading plugin JARs from a specified directory into the system classpath
10 * before the main application starts. This allows additional plugins to be available at runtime
11 * by appending their JAR files to the system class loader search path; while allowing use of an
12 * executable jar with deterministic classpath ordering.
13 * <p>
14 * To use, specify this class as a Java agent and provide the plugins directory as the -javaagent argument
15 * </p>
16 */
17 public class PluginLoader {
18 /**
19 * Java agent entry point. Loads all JAR files from the specified plugins directory
20 * and appends them to the system class loader search path.
21 *
22 * @param agentArg the path to the plugins directory containing JAR files to load, e.g `-javaagent:cli.jar=/usr/share/dependency-check/plugins`
23 * @param inst the instrumentation instance provided by the JVM
24 */
25 public static void premain(String agentArg, Instrumentation inst) {
26 File pluginsDir = new File(agentArg);
27 if (pluginsDir.isDirectory()) {
28 File[] files = pluginsDir.listFiles((dir, name) -> name.endsWith(".jar"));
29 for (File file : files == null ? new File[0] : files) {
30 try (JarFile jar = new JarFile(file)) {
31 inst.appendToSystemClassLoaderSearch(jar);
32 } catch (IOException e) {
33 System.err.printf("[WARN] Failed to read plugin jar file at %s. Jar will not be available on classpath: %s%n", file, e);
34 e.printStackTrace(System.err);
35 }
36 }
37 }
38 }
39 }