How can I load a jar at runtime and replace it for later use without closing it first?

huangapple 未分类评论54阅读模式
英文:

How can I load a jar at runtime and replace it for later use without closing it first?

问题

public class Test
{

    int counter = 1;
    long constructedMillis = System.currentTimeMillis();

    public Test()
    {
        System.out.println("Test constructed! " + constructedMillis + " counter=" + counter);
    }

    public void methodA(String arg1)
    {
        System.out.println("Test methodA called: "+ constructedMillis + " counter=" + counter);
        new Test2();
    }
}

public class Test2
{
    public Test2()
    {
        System.out.println("Test 2 constructed");
    }
}

// another .java
public static Class loadJar(String pathToJar, String classPkg, boolean closeClassLoader)
{
    URL[] urls = new URL[]
    {
        new File(pathToJar).toURI().toURL()
    };
    classLoader = new URLClassLoader(urls);
    Class cls = Class.forName(classPkg, true, classLoader);
    if (closeClassLoader) classLoader.close();
    return cls;
}

public static void main(String[] args)
{
     // example 1: it works but I cannot rebuild the jar so I can reload it for different situations as it is locked from the classLoader since I don't close it in this case.
     {
         boolean closeClassLoader = false;
         Class test = loadJar(args[0],args[1], closeClassLoader);
         Object instance = test.newInstance();
         Method method = test.getDeclaredMethod("methodA", String.class);
         method.invoke(instance, "alpha");
     }

    // example 2:
    // if I do closeClassLoader = true then I get the following exception
    // at the method.invoke(instance, "alpha");
    // because it does new Test2();

    Exception in thread "main" java.lang.reflect.InvocationTargetException
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
}

Note: The provided code does not seem to have any specific translation requirements, as it appears to be mostly Java code. If you have any additional instructions or questions, feel free to ask.

英文:
public class Test
{

    int counter = 1;
    long constructedMillis = System.currentTimeMillis();

    public Test()
    {
        System.out.println("Test constructed! " + constructedMillis + " counter=" + counter);
    }

    public void methodA(String arg1)
    {
        System.out.println("Test methodA called: "+ constructedMillis + " counter=" + counter);
        new Test2();
    }
}
public class Test2
{
    public Test2()
    {
        System.out.println("Test 2 constructed");
    }
}


// another .java
    public static Class loadJar(String pathToJar, String classPkg, boolean closeClassLoader)
    {
        URL[] urls = new URL[]
        {
            new File(pathToJar).toURI().toURL()
        };
        classLoader = new URLClassLoader(urls);
        Class cls = Class.forName(classPkg, true, classLoader);
        if (closeClassLoader) classLoader.close();
        return cls;
    }

public static void main(String[] args)
{
     // example 1: it works but I cannot rebuild the jar so I can reload it for different situation as it is locked from the classLoader since I don't close it in this case.
     {
         boolean closeClassLoader = false;
         Class test = loadJar(args[0],args[1], closeClassLoader);
         Object instance = test.newInstance();
         Method method = test.getDeclaredMethod("methodA", String.class);
         method.invoke(instance, "alpha");
     }

    // example 2:
    // if I do closeClassLoader = true then I get the following exception
    // at the method.invoke(instance, "alpha");
    // because it does new Test2();

    Exception in thread "main" java.lang.reflect.InvocationTargetException
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)

}

please note, I want the loaded jar to remain functional where I use it, however I also want the after jar to be loaded as well on the same path for the later usages.

For example I want to load a jar that has some functionality and assign user commands on it.
But later on I want new users that will arrive to use the next one.

any suggestions?

huangapple
  • 本文由 发表于 2020年7月26日 07:35:26
  • 转载请务必保留本文链接:https://java.coder-hub.com/63094637.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定