Java load jar files from directory

java add jar to classpath at runtime
java load jar at runtime
java load class from jar
java load class from file
java load module at runtime
load class from path java
java add jar to classpath command line
java urlclassloader example

I currently develop an open-source project where people may add their own .jar to extend the included features. However, I'm stuck with how to load the classes in the jar.

I have an abstract class which has an abstract method onEnable() and some getter that provides some objects to work with the application. The plugin needs the subclass my plugin-class BasePlugin. The jar should be added to /plugins and thus I want all *.jar files in the /plugins folder to be loaded when the application starts.

The problem I'm running to now is that, of all the approaches I found, I need to declare a classpath of the classes in the jar file, which I do not know. Neither do I know the name of the jar file. Thus, I need to scan the /plugins folder for any *.jar file and load the corresponding class inside the jar which implements BasePlugin and invoke the onEnable() method.

The basic idea is too...

  1. Read all the files in a specific directory
  2. Convert the File reference to a URL for each result
  3. Use a URLClassLoader, seeded with the URL results to load each result
  4. Use URLClassLoader#findResources to find all the match resources with a specific name
  5. Iterate over the matching resources and load each one, which should give, at least, the "entry point" class name
  6. Load the class specified by the "entry point" property

For example...

public List<PluginClass> loadPlugins() throws MalformedURLException, IOException, ClassNotFoundException {
    File plugins[] = new File("./Plugins").listFiles(new FileFilter() {
        @Override
        public boolean accept(File file) {
            return file.getName().endsWith(".jar");
        }
    });
    List<URL> plugInURLs = new ArrayList<>(plugins.length);
    for (File plugin : plugins) {
        plugInURLs.add(plugin.toURI().toURL());
    }
    URLClassLoader loader = new URLClassLoader(plugInURLs.toArray(new URL[0]));
    Enumeration<URL> resources = loader.findResources("/META-INFO/Plugin.properties");
    List<PluginClass> classes = new ArrayList<>(plugInURLs.size());
    while (resources.hasMoreElements()) {
        URL resource = resources.nextElement();
        Properties properties = new Properties();
        try (InputStream is = resource.openStream()) {
            properties.load(is);
            String className = properties.getProperty("enrty-point");
            PluginClass pluginClass = loader.loadClass(className);
            classes.add(pluginClass);
        }
    }
    return classes
}

nb: I've not run this, but this is the "basic

Adding Classes to the JAR File's Classpath (The Java™ Tutorials , An Example. We want to load classes in MyUtils.jar into the class path for use in MyJar.jar. These two JAR files are in the same directory. We first create a text file � To do this, I need to be able to scan all of the .class files from the project location (JAR/WAR or just a folder) Scanning all of the files in a folder is simple. One option is to call File.listFiles() on the File that denotes the folder, then iterate the resulting array. To traverse trees of nested folders, use recursion.

SpigotMC uses JAR files as plugins as well, inside the jar is a plugin.yaml file that stores extra information about the plugin including the classpath. You don't need to use a YAML file, instead you could use something like JSON or even a plain text file.

The YAML file is inside the jar and can be accessed by using some of the methods explained here. You can then get the classpath property and then load the jar using the methods explained here. Extra information can be stored about the plugin such as the name, version, and dependencies.

How Classes are Found, The java command is called the Java launcher because it launches Java applications. Every .jar file in the extension directory, jre\lib\ext , is assumed to be an further extends the class path, but only while loading classes from that JAR file. For dynamic uploading of jar files, you can use my modification of URLClassLoader. This modification has no problem with changing the jar file during application operation, like the standard URLClassloader. All loaded jar files are loaded into RAM and thus independent of the original file. In-memory jar and JDBC class loader

Java already has a class for this: ServiceLoader.

The ServiceLoader class was introduced with Java 6, but the "SPI jar" concept is actually as old as Java 1.3. The idea is that each jar contains a short text file that describes its implementations of a particular service provider interface.

For instance, if a .jar file contains two subclasses of BasePlugin named FooPlugin and BarPlugin, the .jar file would also contain the following entry:

META-INF/services/com.example.BasePlugin

And that jar entry would be a text file, containing the following lines:

com.myplugins.FooPlugin
com.myplugins.BarPlugin

Your project would scan for the plugins by creating a ClassLoader that reads from the plugins directory:

Collection<URL> urlList = new ArrayList<>();

Path pluginsDir = Paths.get(
    System.getProperty("user.home"), "plugins");

try (DirectoryStream<Path> jars =
    Files.newDirectoryStream(pluginsDir, "*.jar")) {

    for (Path jar : jars) {
        urlList.add(jar.toUri().toURL());
    }
}

URL[] urls = urlList.toArray(new URL[0]);
ClassLoader pluginClassLoader = new URLClassLoader(urls,
    BasePlugin.class.getClassLoader());

ServiceLoader<BasePlugin> plugins =
    ServiceLoader.load(BasePlugin.class, pluginClassLoader);

for (BasePlugin plugin : plugins) {
    plugin.onEnable();
    // etc.
}

An additional advantage of using ServiceLoader is that your code will be capable of working with modules, a more complete form of code encapsulation introduced with Java 9 which offers increased security.

Java extension mechanism loads all JARs, jar (and related JARs) but before the classes loaded from the typical classpath. The extension directory works a bit like the classpath in that its part of the class loading mechanism and classes available within JARs in the extension directory are made available to Java applications. This class path is filled with all files (classes and resources) found in jar files and folders placed on the classpath. For example, if you have two jar and one folder : A.jar com/ mycompany/ A.class Another.class B.jar com/ mycompany/ B.class neededImage.gif bin-folder/ org/ apache/ Something.class

There is an example here it may be helpful. Also, you should take a look at OSGi.

Understanding the Tomcat Classpath, There are some interesting naming conventions having to do with directory structure, but they've The Common class loader loads all classes and JAR files contained in Java class loading is "lazy", which means that the first classloader that� You need to add the jar file in the classpath. To compile your java class: javac -cp .;jwitter.jar MyClass.java To run your code (provided that MyClass contains a main method): java -cp .;jwitter.jar MyClass You can have the jar file anywhere. The above work if the jar file is in the same directory as your java file.

The Executable Jar Format, Java does not provide any standard way to load nested jar files (that is, Dependencies should be placed in a nested BOOT-INF/lib directory. For example one file was called "save map.png", but the application was looking for "Save Map.png". This worked fine when loading files from the drive, but when turned into a URL and loaded directly from the jar, it made all the difference. Therefore, it seems that resource file names in a jar are case-sensitive.

How to access properties file located in library jar file - Forums, <library id="CustomLoginModuleLib"> <fileset dir="${wlp.lib.dir}" As for loading the properties file in the Java code, your first line will work - assuming that this� Extracting the Contents of a JAR File You can use the Jar tool to unpack a JAR file. When extracting files, the Jar tool makes copies of the desired files and writes them to the current directory, reproducing the directory structure that the files have in the archive. Updating a JAR File

What is the default loading order for jar files in a fileset in Liberty, That said, to answer your specific question, when pulling a full directory into a classpath, WebSphere does not do any ordering - it simply retrieves the directory � This page is your source to download or update your existing Java Runtime Environment (JRE, Java Runtime), also known as the Java plug-in (plugin), Java Virtual Machine (JVM, VM, and Java VM).

Comments
  • I used a configuration file which provided the "entry point" into the plugin, placed within a "known"/"common" location within the Jar. The class loader used to load the Jar could then find and load this file, which would provide the name of the class which is the "entry point" for it
  • @MadProgrammer so basically one can add the name of the jar e.g. MyPluginExtension to the configuration file and my class looks for the a class called like this and then trys to load and invoke it?
  • No, you would create a "plugin" configuration file, which would be stored within the Jar as an embedded resource. All the "plugins" would have a file named the same, in the same location, which could then be read by the class loader. Within this file, it would contain the name of the class that conforms to the "base" class/interface requirements which the class loader would then load
  • @Nordic88 You don't need to. You simply list all the Jars in, let say, the "plugins" directory, use one or more class loaders to load them and then find the configuration Jar
  • @Nordic88 The basic idea involves using a URLClassloader, for example and example, then you can use findResource to find the "named" configuration, for example (although findResources will return multiple matches)