英文:
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?
专注分享java语言的经验与见解,让所有开发者获益!
评论