JVM 在启动时锁定 JAR 文件
JVM locks JAR files on startup
我已经实现了一个通过系统 属性 -Djava.system.class.loader=com.MyClassLoader
设置的自定义类加载器。 CL 包含一个静态初始化程序,它调用一些代码(在加载任何 class 之前)使用 javassist 库操作 jar(maven 依赖项)中的 class 文件的字节代码。这工作正常,除了我不能用新的替换旧的 jar,因为 JVM 正在锁定文件并且只在它终止时释放它。为什么会这样,我如何强制 JVM 释放锁?
这是一小段代码:
public class CustomClassLoader extends ClassLoader {
static {
...
modifyJar();
}
private static void modifyJar(){
URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
URL[] urls = urlClassLoader.getURLs();
for(URL url : urls) {
//find matching jar and modify byte code
}
replaceJarFile(metaData);
}
private static void replaceJarFile(JarMetaData jmd){
//add modified class to new jar file
JarFile jar = new JarFile(jmd.getJarFile());
...
//this method call returns false, jar is locked by another process (the JVM)
if(oldJarFile.delete()){
...
}
}
}
OS: Windows 10
JDK版本:1.8.0_131
从来没有指定更改 JVM 使用的 jars 应该是可能的。 JVM 正在长时间安静地锁定罐子。更改正在使用的 jar 中的 classes 也会带来语义问题,即如何处理对已加载 classes 的修改,甚至是正在进行的 class 加载与写入重叠。
由于修改 jar 将是永久性的更改,因此最合理的方法是在启动 JVM 之前进行修改,例如在不同的 JVM 中。
但是如果您想即时更改 class 定义,您应该编写一个 Java 代理。对于那些支持 Java 代理的 JVM,Instrumentation API 提供了所需的一切,例如在加载时转换 classes 甚至重新定义已经加载的 classes.
它还提供了一种将 jar 文件添加到 bootstrap 或系统 class 路径的标准方法,而假设应用程序 class 加载器是 [=10= 的子 class ] 将开始失败 Java 9.
我已经实现了一个通过系统 属性 -Djava.system.class.loader=com.MyClassLoader
设置的自定义类加载器。 CL 包含一个静态初始化程序,它调用一些代码(在加载任何 class 之前)使用 javassist 库操作 jar(maven 依赖项)中的 class 文件的字节代码。这工作正常,除了我不能用新的替换旧的 jar,因为 JVM 正在锁定文件并且只在它终止时释放它。为什么会这样,我如何强制 JVM 释放锁?
这是一小段代码:
public class CustomClassLoader extends ClassLoader {
static {
...
modifyJar();
}
private static void modifyJar(){
URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
URL[] urls = urlClassLoader.getURLs();
for(URL url : urls) {
//find matching jar and modify byte code
}
replaceJarFile(metaData);
}
private static void replaceJarFile(JarMetaData jmd){
//add modified class to new jar file
JarFile jar = new JarFile(jmd.getJarFile());
...
//this method call returns false, jar is locked by another process (the JVM)
if(oldJarFile.delete()){
...
}
}
}
OS: Windows 10
JDK版本:1.8.0_131
从来没有指定更改 JVM 使用的 jars 应该是可能的。 JVM 正在长时间安静地锁定罐子。更改正在使用的 jar 中的 classes 也会带来语义问题,即如何处理对已加载 classes 的修改,甚至是正在进行的 class 加载与写入重叠。
由于修改 jar 将是永久性的更改,因此最合理的方法是在启动 JVM 之前进行修改,例如在不同的 JVM 中。
但是如果您想即时更改 class 定义,您应该编写一个 Java 代理。对于那些支持 Java 代理的 JVM,Instrumentation API 提供了所需的一切,例如在加载时转换 classes 甚至重新定义已经加载的 classes.
它还提供了一种将 jar 文件添加到 bootstrap 或系统 class 路径的标准方法,而假设应用程序 class 加载器是 [=10= 的子 class ] 将开始失败 Java 9.