替换动态加载的jar
replace dynamically loaded jar
我已经从其他 jar 文件动态加载了 jar,然后在某些时候,我想删除这个 jar 并用更新的版本替换它,在 linux 上它工作正常,而在 windows 当我尝试将文件移动到备份目录时,我得到文件正在被另一个进程异常使用。
public void loadJarAndClass() {
URL[] jarUrl = new URL[1];
jarUrl[0] = jarFile.toURI().toURL();
classLoader = new URLClassLoader (jarUrl, this.getClass().getClassLoader());
classToLoad = Class.forName ("Burner.MainWindow", true, classLoader);
}
public void unloadJarAndClass() {
/* all object must be collected in order to reload jar */
jarFile = null;
dukeClassLoader = null;
classToLoad = null;
System.gc();
}
我的主要:
jarPath = currentPath.getAbsolutePath() + File.separator + JAR_NAME;
jarFile = new File(jarPath);
loadJarAndClass();
unloadJarAndClass();
Files.delete(FileSystems.getDefault().getPath(jarPath));
我的问题是删除引发异常“进程无法访问该文件,因为它正被另一个进程使用”
如何绕过此异常并关闭所有打开的处理程序?
尝试使用Classloader.close()方法,
这是 Oracle link,
的摘录
In Java SE 7, the URLClassLoader close() method effectively invalidates the loader, so that no new classes can be loaded from it. It also closes any JAR files that were opened by the loader. This allows the application to delete or replace these files and, if necessary, create new loaders using new implementations.
以下是可能达到目的的代码的简化版本,
public class Example {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String jarPath = "C:\example.jar";
File jarFile = new File(jarPath);
URL[] jarUrl = new URL[1];
jarUrl[0] = jarFile.toURI().toURL();
URLClassLoader classLoader = new URLClassLoader (jarUrl, Example.class.getClassLoader());
Class classToLoad = Class.forName ("DataGenerator", true, classLoader);
classLoader.close();
Files.delete(FileSystems.getDefault().getPath(jarPath));
}
}
请尝试在 'unload' 之前关闭类加载器。
public void unloadJarAndClass() throws IOException {
dukeClassLoader.close();
/* all object must be collected in order to reload jar */
jarFile = null;
dukeClassLoader = null;
classToLoad = null;
// System.gc(); don't do this unless you're really
// sure you have to !
}
我建议不要显式调用 System.gc() !
(例如参见Why is it bad practice to call System.gc()?)
我已经从其他 jar 文件动态加载了 jar,然后在某些时候,我想删除这个 jar 并用更新的版本替换它,在 linux 上它工作正常,而在 windows 当我尝试将文件移动到备份目录时,我得到文件正在被另一个进程异常使用。
public void loadJarAndClass() {
URL[] jarUrl = new URL[1];
jarUrl[0] = jarFile.toURI().toURL();
classLoader = new URLClassLoader (jarUrl, this.getClass().getClassLoader());
classToLoad = Class.forName ("Burner.MainWindow", true, classLoader);
}
public void unloadJarAndClass() {
/* all object must be collected in order to reload jar */
jarFile = null;
dukeClassLoader = null;
classToLoad = null;
System.gc();
}
我的主要:
jarPath = currentPath.getAbsolutePath() + File.separator + JAR_NAME;
jarFile = new File(jarPath);
loadJarAndClass();
unloadJarAndClass();
Files.delete(FileSystems.getDefault().getPath(jarPath));
我的问题是删除引发异常“进程无法访问该文件,因为它正被另一个进程使用”
如何绕过此异常并关闭所有打开的处理程序?
尝试使用Classloader.close()方法,
这是 Oracle link,
的摘录In Java SE 7, the URLClassLoader close() method effectively invalidates the loader, so that no new classes can be loaded from it. It also closes any JAR files that were opened by the loader. This allows the application to delete or replace these files and, if necessary, create new loaders using new implementations.
以下是可能达到目的的代码的简化版本,
public class Example {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String jarPath = "C:\example.jar";
File jarFile = new File(jarPath);
URL[] jarUrl = new URL[1];
jarUrl[0] = jarFile.toURI().toURL();
URLClassLoader classLoader = new URLClassLoader (jarUrl, Example.class.getClassLoader());
Class classToLoad = Class.forName ("DataGenerator", true, classLoader);
classLoader.close();
Files.delete(FileSystems.getDefault().getPath(jarPath));
}
}
请尝试在 'unload' 之前关闭类加载器。
public void unloadJarAndClass() throws IOException {
dukeClassLoader.close();
/* all object must be collected in order to reload jar */
jarFile = null;
dukeClassLoader = null;
classToLoad = null;
// System.gc(); don't do this unless you're really
// sure you have to !
}
我建议不要显式调用 System.gc() ! (例如参见Why is it bad practice to call System.gc()?)