All Downloads are FREE. Search and download functionalities are using the official Maven repository.

samrg472.plugins.jar.loader.JarLoader Maven / Gradle / Ivy

The newest version!
package samrg472.plugins.jar.loader;

import samrg472.plugins.exception.FileNotFoundException;
import samrg472.plugins.exception.NullArgumentException;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @param  the type plugin instances will be of
 * @author samrg472
 */
public class JarLoader {

    private boolean disposed = false;
    private URLClassLoader loader;

    private List jars = new ArrayList();

    /** Instances of the plugin */
    protected List instances;

    /**
     * Creates a new dynamic jar loader on a new class loader
     */
    public JarLoader() {
        this.loader = new URLClassLoader();
        this.instances = new ArrayList();
    }

    /**
     * Loads the jar into the class loader
     * In most cases the jar with the plugin will only be loaded except for needed dependencies by the jar
     * @param jar jar to be loaded
     * @throws FileNotFoundException jar cannot be located
     */
    public void load(File jar) throws FileNotFoundException {
        if (disposed)
            throw new IllegalStateException(JarLoader.class.getSimpleName() + " was disposed");
        if (jar == null)
            throw new NullArgumentException("jar");
        if (!jar.isFile())
            throw new FileNotFoundException(jar);
        try {
            if (jars.contains(jar.getAbsolutePath()))
                return;
            loader.addURL(jar.toURI().toURL());
            jars.add(jar.getAbsolutePath());
        } catch (MalformedURLException e) {
            throw new RuntimeException(e); // Should never happen, but just in case
        }
    }

    /**
     * Remove all instances of the plugin
     */
    public void destroyInstances() {
        if (disposed)
            throw new IllegalStateException(JarLoader.class.getSimpleName() + " was disposed");
        instances.clear();
    }

    /**
     * @return instances of the plugin class
     */
    public List getInstances() {
        if (disposed)
            throw new IllegalStateException(JarLoader.class.getSimpleName() + " was disposed");
        return Collections.unmodifiableList(instances);
    }

    /**
     * @param clazz fully resolved class name to instantiate, must extend T or an exception will be thrown
     * @return new instance of the plugin
     * @see samrg472.plugins.jar.JarProbe for extracting information about a jar to load
     */
    @SuppressWarnings("unchecked")
    public T createInstance(String clazz) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        if (disposed)
            throw new IllegalStateException(JarLoader.class.getSimpleName() + " was disposed");
        if (clazz == null)
            throw new NullArgumentException("clazz");
        T instance = (T) loader.loadClass(clazz).newInstance();
        instances.add(instance);
        return instance;
    }

    /**
     * Must be called when finished with the instance to properly unload the classes
     * Make sure there are no instance references to any instances here
     * @throws IOException
     */
    public void destroy(boolean gc) throws IOException {
        if (disposed)
            return;
        disposed = true;
        IOException e = null;
        try {
            loader.close();
        } catch (IOException _e) {
            e = _e;
        }
        instances.clear();
        jars.clear();
        loader = null;
        if (gc)
            System.gc(); // Must be garbage collected to properly unload the classes
        if (e != null)
            throw e;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy