LECHIP
LECHIP

Reputation: 81

Submitting jar for execution

I am designing a system using Spring where some users should able to implement some classes, submit a JAR and be able to execute their submission provided that the classes inside the Jar comply with the interfaces that are supposed to be implemented. The idea is to have a framework for extensiblility using jars (and some xml configuration files).

My questions is, is this possible? How should I approach the execution of the mentioned Jars and can I validate that the content of the jars complies with the API during submission?

Thank you!

Upvotes: 0

Views: 124

Answers (2)

LECHIP
LECHIP

Reputation: 81

I ended up using JCL: https://github.com/kamranzafar/JCL

I used it with something like this:

public class AnalyticsMethodsClassPathLoader {

private JarClassLoader jcl;
private JclObjectFactory factory;

public AnalyticsMethodsClassPathLoader(String analyticsMethodsJarsFolder) {

    //JCL object for loading jars
    jcl = new JarClassLoader();
    //Loading classes from different sources
    jcl.add(analyticsMethodsJarsFolder);

    // Set ClassPathLoader priorities to prevent collisions when loading
    jcl.getParentLoader().setOrder(1);
    jcl.getLocalLoader().setOrder(2);
    jcl.getSystemLoader().setOrder(3);
    jcl.getThreadLoader().setOrder(4);
    jcl.getCurrentLoader().setOrder(5);

    // Set default to cglib (from version 2.2.1)
    ProxyProviderFactory.setDefaultProxyProvider( new CglibProxyProvider() );
    factory = JclObjectFactory.getInstance(true);
}

public AnalyticsMethod loadClass(String implementingClass) throws AnalyticsMethodLoaderException {
    //Create object of loaded class
    AnalyticsMethod abstractMethod;
    try{
        abstractMethod = (AnalyticsMethod) factory.create(jcl, implementingClass);
        return abstractMethod;
    }
    catch (JclException e)
    {
        e.printStackTrace();
        throw new AnalyticsMethodLoaderException("The class " + implementingClass +
                " was not found or does not implement the framework.");
    }
    catch (java.lang.NoSuchMethodError error)
    {
        error.printStackTrace();
        throw new AnalyticsMethodLoaderException("The class " + implementingClass +
                " does not have an empty constructor.");
    }
}

}

It is relatively stable and allows me to do just what I needed in spring without the need to combine it with the now unsupported OSGi features of spring. I do know that it has limitations and is not the absolute best solution in all cases, but for submitting and executing simple jars works just fine.

Upvotes: 1

Vovka
Vovka

Reputation: 599

URLClassLoader child = new URLClassLoader (myJar.toURL(), this.getClass().getClassLoader());
Class classToLoad = Class.forName ("com.MyClass", true, child);
Method method = classToLoad.getDeclaredMethod ("myMethod");
Object instance = classToLoad.newInstance ();
Object result = method.invoke (instance);

How should I load Jars dynamically at runtime?

restrict permissions of loaded jars Java security: Sandboxing plugins loaded via URLClassLoader

use reflection to test classes How can I determine whether a Java class is abstract by reflection https://docs.oracle.com/javase/tutorial/reflect/

Upvotes: 1

Related Questions