JDK-5031910 : App fails w/ classnotfound exception after restoring n/w connectivity
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 1.4.2_03
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2004-04-15
  • Updated: 2010-02-22
  • Resolved: 2004-12-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2_08 b01Fixed
Related Reports
Relates :  
Description
I have attached a *simple* test case which loads a class from a jar
file (test.jar).  All the components involved (JRE, *.class, *.jar) are
located on a network mapped drive on a Windows 2000 system. JRE version
that was used was 1.4.2_03.

When we run this program, the classloader loads a class "Test" from
"test.jar" file. It will continue to load this class for 5 iterations
for every return key pressed, followed by loading a second class
"Test2" in an infinite loop (again with every return key).

The problem here is if we remove the n/w connectivity between these
interations and *restore* it back before trying to load the same/next
class. The program will abort with a "classnotfound" exception. 

IMP: The problem is observed only when the JRE is also installed on a
n/w mapped drive.

Interestingly, on one of the Windows box that I verified this problem
with, the native OS restores the access to the offlined n/w mapped
drive *automatically*. So, in theory, we should not have had problem in
loading class files from the jar file.

A new version of the program "Loadernew.java" just lists the directory
contents and it resumes listing the files and never throws any
exception after the n/w connectivity is *restored*.

So, the problem seems to be specific the Java side components related
to the "Classloader" mechanism.

I wrote a simple Hello World C program and copied the resulting "exe"
to the n/w mapped drive. I did not see any probem when I disconnected
and reconnected back the n/w cable while the program was in action. Of
course, the "java.exe" is more complex and will have dependency on
other DLL's which are also located on the n/w mapped drive.

Comments
EVALUATION I talked with Ken Russell of the HotSpot team. Basically the JVM doesn't support the notion of error recovery. That is, since the JRE is also located on a remote machine, when you unplug the network, meanwhile if the JVM is trying to access some JVM files such as those in rt.jar, it will encounter an IO error, as a result it throws a ClassDefNotFoundError. If the application really wants to recover from this kind of error, it can catch it and continue (I tried it, it works), or it can restart the JVM. Depending on the status of the JVM and what it's trying to execute next, you could encounter other file not found (i.e it's not limited to "sun/reflect/MethodAccessorGenerator"). To see this, you can try to kill the vm by "ctrl-c" while having the network cable unplugged, and it would complain about "java/lang/Shutdown" not being found. But what is interesting about "sun/reflect/MethodAccessorGenerator" is that it provides an optimization to reflection (newInstance uses reflection). It kicks in after the reflection method being called 15 times. So even if you have already loaded a class, in this case Test2, if you unplug the network, you would continue to be able to load and instantiate Test2. However, after about 15 times, you would suddenly see "NoClassDefFoundError: sun/reflect/MethodAccessorGenerator ...". This is because the JVM optimizer starts to kick in and needs to load MethodAccessorGenerator class (part of rt.jar), but due to network inaccessibility, it couldn't load it, thus the error. In summary, this is not a bug. ###@###.### 2004-04-19 There are a number of scenarios where we could try to be more robust in the face of I/O failures. On Windows, a jar file is represented internally as a file descriptor. If that file descriptor is closed because the network became temporarily unavailable, it is certainly reasonable to try to reopen it. However, this is a high-risk change that should only be contemplated for a future release, in my opinion. Another consideration is that we may someday use mapped files on Windows, as we do on Unix. A similar scenario where we could imagine being more robust is when a jar file is replaced on disk. If we notice this, we can discard our in-memory cache of the central directory and re-read it, avoiding errors on the next Class load operation. In any case, I don't think these sorts of changes are appropriate for older releases. Even for future releases, we have more important bugs/features in the jar/zip implementation to take core of first. ###@###.### 2004-04-27 Fix caused a build failure. Hence, backed out from 1.4.2_08/b01. ###@###.### 10/27/04 17:31 GMT
27-04-2004