This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
Build: 010731_1 When user wants to add some files to the already created jar(-Content) then these file aren't saved. Sometimes happen, the jar-file is empty => exception java.lang.InternalError: jzentry == 0 at java.util.zip.ZipFile$2.nextElement(ZipFile.java:297) at java.util.jar.JarFile$1.nextElement(JarFile.java:198) at org.openide.filesystems.JarFileSystem$1.run(JarFileSystem.java:152) at org.openide.util.Task.run(Task.java:124) at org.openide.util.RequestProcessor$ProcessorThread.run(RequestProcessor.java:626) Note: It's happen a more often when jar-file contains a manifest.
Is any more information available? It seems from the stack trace that the jar file was mounted at the time (which is OK.) Does it happen when the JAR is not mounted?
Hi, a jar file is not mounted. Seems to me, it's happen when I am doing actions (add/remove files, compile, mountJar) quickly, but a status bar & output window always signals a finished action.
The stack trace you mention is printed to standard output, right? This is unfortunate (it's tracing output which should not be shown in the released version), but the exception is handled and should not cause any other problems. When you say that the added files aren't saved, do you mean: 1. They are missing from the Content Property window next time you look at it 2. You compiled that jar and the files don't appear in the jar file system in the explorer. 3. You compiled the jar and "jar tf <jarfile>" shows that the files were not added to the jar. Also, what version are you seeing this in? The bug is marked FFJ 3.0 ea, but the stack trace looks more like 3.2.1 or FFJ 3.0 fcs.
The stack trace is printed to the console window. I selected the "FFJ 3.0 ea" , because we haven't a value "FFJ 3.0 fcs" in the list of versions. 1. No, They are comprised in the Content Property window. It's OK. 2. Exactly. I saved, compiled the jar(-Content) and mounted the jar. The files don't appear in the jar file system in the explorer. I cannot say that it is happend every time. I tried this behaviour on NB 3.2.1 build 98 (linux) and FFJ 3.0 fcs build 010814 (solaris) and it was happend only twice today. 3. "jar tf <jarfile>" shows a right state of jar file. All required files are contained.
Marek's comments show that this as a jar file system issue, not a jar packager one. The jar file was constructed correctly, but the jar file system's display of the contents is incorrect. The fact that the behavior is inconsistent probably points to underlying timing issues in the update and refresh of the JFS's nodes, rather than any errors in the logic for parsing jars. See the thread "JarFileSystem problems" in ndbev.
just updating the subcomponent
Strange. There is not necessary to mount JarFileSystem at all. Suffice to execute (in internal execution) such code: JarFile jf = null; while (true) { try { jf = new JarFile ( new File ("C:\\Development\\Test.jar") ); Enumeration en = jf.entries(); while ( en.hasMoreElements() ) { System.out.println( en.nextElement() ); } break; } catch (Throwable t) { t.printStackTrace(); jf.close (); } } If InternalError is fired then this loop is never ending. This piece of code cannot recover from this problem. Any idea how to solve this problem ?
I did not emphasize that above mentioned piece of code was executed after modifying content and compiling.
Sorry, Radek, I don't understand the question. Where are you seeing code like this? I don't find it in JarFileSystem. The closest thing is the "parse" method, which returns if there is any exception thrown while listing the jar's entries. The logic there is that there may be transient errors if the jar is being modified while parse runs, but once the jar is fully constructed, the next parse will work. It does fail silently if the jar is actually bad, which is a problem, but apparently not the one being reported here, since "jar tf" works.
Above mentioned piece of code is standalone program (call it e.g. Test). So insetad of mounting JAR I ran this Test that transparently simulates what method JFS.parse does. As you can see after error occures the jar is closed and fully constructed and enumaration continous. So this Test runs so long until no error occures. Once the problem occures then the next pass(parse) should work - but doesn`t as I`ve noticed (despite the fact that jar was fully constructed). So once the problem occures then break in Test is never reached. Result: fully construct jar doesn`t help (at least not under all circumstances). Then question is: what else should I do (when error occures) ?
I played with this program fragment on NT 4.0 and found the following: If the file C:\Development\Test.jar is not open by any other File object, the behavior is correct, that is, the InternalError goes away after the jar is fully rebuilt. If C:\Development\Test.jar is open by another File object, the infinite loop results. Apparently, Java (or NT, but I suspect Java) is caching the contents of the file, and not refreshing the cache while any java object has the file open. This is a real problem, since creating a JarFileSystem opens the file, and it's necessary for the client code to specifically call removeNotify to close it. I've seen several cases where code using a JarFileSystem failed to do so, leaving the file open until the IDE exits. (One case was to parse a jar file; a recent one was the mount Jar wizard, which created a JarFileSystem as a way of checking if the jar file was already mounted.) This has other ill effects, like making the jar file undeletable on Windows. (By the way, I went down this path because in the code fragment, the jar file isn't closed if it parses correctly.)
I do have one thought -- it's similar to something I did in the jar packager. Instead of opening the jar file in place for parsing, copy it to a temporary location, and parse it from there. Then you can be sure no one else has the file open. If the parse fails, you can close and delete the file until next time. There is some expense involved, of course, especially at startup. I suggest doing this only for the JarFileSystems that show up in the explorer.
Perhaps if there is possible to copy it to a temporary location after error occures then I`ll do it (I would like to copy it only if error is handled). I`ll investigate it tomorrow. Thanks for hints. Really helpful and I appreciate it.
Copying only after an error is worth trying, but I'm pessimistic. I think that the FileInputStream used to create the copy will also see the incorrect cached file contents, so the copied file will still be invalid.
Radek told me to check this bug - I expect that the most common situation is that a JarPackager creates a JAR and after that automatically mounts it into repository. My question is whether in the packager could not improve its behaviour and work with the JAR in a better way? Uninstall it from repository, call removeNotify on it, etc.? I am asking because the JarFS is used in different situations and for some of them a heavyweight support of situations when jar is modified is overkill....
The important situation is this: A jar file is already mounted. The jar packager rebuilds it. The jar file system now needs to reparse the file. In 3.2, this didn't work at all. The jar file system tried to reparse the file without closing and re-opening it, invariably leading to internal error exceptions that ended the rescheduling of the parsing task. It's kind of amusing, actually: every mounted jar was being checked every 15 seconds so that, if it did change, the IDE could issue a cryptic message and then stop checking it. I put in as lightweight a fix as I could (version 1.46) into 3.2.1 to: close and re-open the jar file before parsing it. if the parse fails, return instead of throwing an exception (that is, assume the jar file was in the process of being built, and that the next parse would work.) ensure that, even if an unexpected exception was throwm, the parse task was rescheduled. The JFS was pretty much rewritten in 1.49, but I don't think any of this logic changed. This would actually work quite well except for the problem I noted above: if Java has the jar file open using some other file descriptor than the one the JFS is using, closing an re-opening the JarFile doesn't help: apparently Java is reading from some stale memory buffer instead of from the disk and internal errors result. This would still be true if the jar packager called removeNotify, since all that does is close the jar file (and doesn't even do that all of the time.) I see two ways to approach this problem: 1. As I suggested, have the JFS make a copy of the jar file and parse that. This guarantees that no one else will have the file open. 2. Change the JFS to make it less likely to keep the file open. As I mentioned above, the JFS implementation makes it far too easy to leave the file open, even for a JFS of extremely temporary use (like the ones used in the mount wizard.) If the jar file were kept open only when necessary, this bug would go away. Now we need to define "when necessary." There are two candidates: 1. During parsing 2. When one of the JFS's FileObjects is open 1 is obvious. This isn't a problem, since it's completely under the control of the JFS. I'd also consider only reparsing a jar file system after it's added to the repository; there's really no point in doing this for short-lived JFS's (again, like the ones used by the mount wizard.) 2 can be avoided by copying the jar entry to a temp file and creating the input stream from there. I think this is best, since it also fixes the current problem where removeNotify can't always close the jar file.
There seems to mee that I`m able to solve this problem (instead of JarFile use JarInputStream if problem occures). I`ve implemented subclass of JarFile that calls super methods if OK. If problem occures, uses JarInputStream and its methods. But it looks like heavyweight solution with lack of performance (probably brings next regression). I think that in this case would be better to behave carefuly to JFS. I agree with Jarda. Perhaps if jar packager rebuilds it, then could be: - disabled possibility to Mount Jar - uninstall already mounted Jar from repository (after compiling again add to Repository)
1. Why do you think that would help? 2. What about the case where the jar file changes for some reason other than the jar packager? If we don't expect the JFS to handle changes to the jar file, why are all these timers running? 3. This is pretty complex behavior, and introduces race conditions as well as other chances for more complicated failures. I think it's a lesser evil to live with this bug.
> I think it's a lesser evil to live with this bug. I agree. Workaround exists, then priority decreased. Let`s solve this bug in 3.4.
*** Issue 17400 has been marked as a duplicate of this issue. ***
#17400 showed another possible way how to cause this bug. JarFile modification in internal execution (same claasloader) is source of problems as comments above. Priority increased.
Seems to be platform independent problem.
I have observed with URLClassLoader, which uses JarFile for opening *.jar, that you have no chance of observing changes in the JAR file unless the classloader and thus JarFile is garbage collected. On Windows, there will also be a file lock on the *.jar. The only workaround I am aware of (used in the module system for implementing reloadable modules), assuming you cannot ensure collection of the JarFile for whatever reason, is to make a copy of the *.jar as a temporary file and load that instead.
To make sure I understand. Netbeans 3.3 (I never saw this problem in 3.2.1) uses a jarFS to load jar files even if [indirect] ant is used to compile the project. Said another way, I have a build.xml that netbeans uses to compile my app. Thus the jar files that are referenced in the build.xml get loaded by netbeans jarFS (and from what I am seeing are cached) so that if you update a jar referenced in the build.xml, the next time I build my app the ant compilation doesn't see the changes made to the updated jar. If what I am saying is correct, this is definitely a serious bug, which probably affects J2EE dev's the most since a J2EE app consists of many ejbjars referenced by an additional java classes packaged in a war file. So if I have a project tree with standalone components (ejbjars) with separate build.xml's (each which produces a ejbjar), and have in the same project an app directory with a separate build.xml which references those ejbjars, changes made to the ejbjars are not reflected and compilation will fail (if you change the public api for example). Result is (will be) huge frustration because you "swore" you updated the code (and in fact netbeans confirms reflects your changes), but it won't work! Anyways, this bug started for me as bug 17400. I have build nb 3.3 beta 3 (build 200111021545), redhat linux 7.2, java version: [grk@acoldone2 grk]$ java -version java version "1.3.1_01" Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_01) Java HotSpot(TM) Client VM (build 1.3.1_01, mixed mode)
See also this bug filed against JDK "JarURLConnection.openConnection() doesn't reflect current jar file contents" <http://developer.java.sun.com/developer/bugParade/bugs/4211817.html> which has been fixed in 1.3.1_01
I tested it with jdk: 1.3.1_01. At first glance I thought that I`m not able to reproduce this bug anymore. But I`m afraid this bug persist also with 1.3.1_01.
> But I`m afraid this bug persist also with 1.3.1_01. are you able to reproduce it with 1.3.1_01?
I`m able to reproduce it with 1.3.1_01.
Remember, I did not (and do not) see this problem in 3.2.1 so this would appear to be a netbeans bug and not a jdk bug!
> Remember, I did not (and do not) see this problem in 3.2.1 so this > would appear to be a netbeans bug and not a jdk bug! Sorry to be rude, but if I apply the same kind of logics, I would be able to say "I did not and do not see this problem on my machine so this would appear to be a bug in your machine not in the IDE"
ok, ok, sometimes rude is good, it gets your attention ;-) Being more careful I found: the bug does indeed exist in nb 3.2.1 as well as nb 3.3 beta 4 but I now think this is a jdk bug (as pointed to above) and not a netbeans bug...because running with j2sdk1.4 beta3, it appears that everything works as you would hope! Sorry for the misleading info.
There was reported bug against this problem with bugID:4607439
the situation hasn't change since 3.3.0
Waiver for 3.3.1 approved by QA.
*** Issue 19741 has been marked as a duplicate of this issue. ***
bugID:4607439 was resolved in jdk1.4.0-rc. I checked it and seeems that everything is OK. So marked as fixed.
Verified
Resolved for 3.4.x or earlier, no new info since then -> closing.