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.

Bug 14130 - Unable to add files to the already created jar(-Content)
Summary: Unable to add files to the already created jar(-Content)
Status: CLOSED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Filesystems (show other bugs)
Version: 3.x
Hardware: All All
: P2 blocker (vote)
Assignee: rmatous
URL:
Keywords:
: 17400 19741 (view as bug list)
Depends on:
Blocks:
 
Reported: 2001-08-02 10:21 UTC by Marek Grummich
Modified: 2008-12-22 16:48 UTC (History)
3 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marek Grummich 2001-08-02 10:21:07 UTC
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.
Comment 1 Mike Schilling 2001-08-09 19:42:26 UTC
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?
Comment 2 Marek Grummich 2001-08-10 08:31:17 UTC
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.
Comment 3 Mike Schilling 2001-08-10 22:34:47 UTC
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.
Comment 4 Marek Grummich 2001-08-21 09:22:29 UTC
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.

Comment 5 Mike Schilling 2001-08-21 13:02:46 UTC
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.
Comment 6 Jan Zajicek 2001-09-11 11:40:19 UTC
just updating the subcomponent
Comment 7 rmatous 2001-09-21 19:24:21 UTC
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 ?

Comment 8 rmatous 2001-09-21 19:29:03 UTC
I did not emphasize that above mentioned piece of code was executed 
after modifying content and compiling.
Comment 9 Mike Schilling 2001-09-21 19:41:53 UTC
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.
Comment 10 rmatous 2001-09-24 11:42:12 UTC
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) ?
Comment 11 Mike Schilling 2001-09-24 21:45:35 UTC
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.) 

Comment 12 Mike Schilling 2001-09-26 19:27:21 UTC
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.
Comment 13 rmatous 2001-09-26 20:09:10 UTC
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.
Comment 14 Mike Schilling 2001-09-26 20:33:13 UTC
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.
Comment 15 Jaroslav Tulach 2001-09-27 10:25:36 UTC
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....

Comment 16 Mike Schilling 2001-09-27 17:30:12 UTC
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.
Comment 17 rmatous 2001-10-05 19:33:25 UTC
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)

Comment 18 Mike Schilling 2001-10-06 01:11:14 UTC
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.
Comment 19 rmatous 2001-10-23 16:56:02 UTC
> 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.

Comment 20 rmatous 2001-11-08 11:11:35 UTC
*** Issue 17400 has been marked as a duplicate of this issue. ***
Comment 21 rmatous 2001-11-08 11:19:39 UTC
#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.
Comment 22 rmatous 2001-11-08 11:24:12 UTC
Seems to be platform independent problem.
Comment 23 Jesse Glick 2001-11-08 11:29:34 UTC
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.
Comment 24 grk 2001-11-08 17:22:06 UTC
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)
Comment 25 _ ttran 2001-11-09 11:00:12 UTC
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
Comment 26 rmatous 2001-11-13 12:11:13 UTC
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.
Comment 27 _ ttran 2001-11-13 16:28:51 UTC
> But I`m afraid  this bug persist also with 1.3.1_01.

are you able to reproduce it with 1.3.1_01?

Comment 28 rmatous 2001-11-13 17:48:39 UTC
I`m able to reproduce it with 1.3.1_01. 
Comment 29 grk 2001-11-15 20:37:57 UTC
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!
Comment 30 _ ttran 2001-11-16 12:05:42 UTC
> 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"

Comment 31 grk 2001-11-20 00:03:14 UTC
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.
Comment 32 rmatous 2001-12-14 10:28:28 UTC
There was reported bug against this problem with bugID:4607439

Comment 33 _ ttran 2002-01-14 15:57:34 UTC
the situation hasn't change since 3.3.0
Comment 34 Jan Chalupa 2002-01-16 09:46:07 UTC
Waiver for 3.3.1 approved by QA.
Comment 35 rmatous 2002-01-25 13:10:55 UTC
*** Issue 19741 has been marked as a duplicate of this issue. ***
Comment 36 rmatous 2002-01-25 13:12:57 UTC
bugID:4607439 was resolved in jdk1.4.0-rc. I checked it and seeems
that everything is OK. So marked as fixed.


Comment 37 Marek Grummich 2002-10-14 11:26:57 UTC
Verified
Comment 38 Quality Engineering 2003-07-01 16:27:28 UTC
Resolved for 3.4.x or earlier, no new info since then -> closing.