我有一个java进程在类路径中运行两个jar文件,即
- A.jar
- B.jar
当进程运行时,我用另一个B.jar替换了B.jar,我用一些文件更新了.jar。现在在我的进程中,我看到了B.jar中的类的一些ClassNotFoundException。我不明白这里发生了什么。我认为在java进程启动时会加载jar。如果是这样的话,为什么会这样呢?有人可以帮我吗?我知道如果我重新开始这个过程,一切都会好的。但我很想知道背后的原因。
答案 0 :(得分:4)
JAR文件中的类在first used时加载,而不是在JVM启动时加载。通过在应用程序运行时替换B.jar,如果您删除了其他人引用的类,您将获得ClassNotFoundException
。
如果您一段时间没有使用过的类被垃圾回收,那么在Java 7中也会发生这种情况。 JVM将尝试重新加载它,并发现它不再位于类路径中。如果您使用-XX:+CMSClassUnloadingEnabled
启动选项,则在早期版本的Java中也会发生这种情况。
答案 1 :(得分:1)
JVM支持类的静态和动态加载。 JVM将在启动时加载所有明确链接的类,但不会“发现”在运行时动态加载的类,例如通过反射。如果您在代码中执行Class.forName("org.package.mySuperClass")
,并且SuperClass
从未与其他代码链接,则会在呼叫时加载。如果在调用之前已从类路径中删除了包含此类的jar,则会抛出ClassNotFoundException
请注意,很多现代框架都使用动态加载(甚至动态编译链接到类路径中之前未链接的类),并且知道哪些是困难的(并且不确定)。