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.
This is a showstopping bug for j2me code-freeze on Sept 8th, 2004. It appears to be mdr related, but my appologies if it ends up being something we're doing wrong. Steps to reproduce: -Open new j2me project with midlet -build project -make some compile error, wait for error annotation to appear. -fix compile error, wait for annotation to dissapear -clean&build project The distribution jar will be locked. ---- Using a debugger and a file lock observing program, i determined that the lock seems to be created at the following location (for certain, it is created somewhere in the "refreshAnnotation()" method): System Thread [Error Annotation Queue] (Running) File.<init>(String) line: 183 File.getAbsoluteFile() line: 475 File.toURI() line: 607 ArchiveURLMapper.getURL(FileObject, int) line: 64 URLMapper.findURL(FileObject, int) line: 80 AbstractFileObject(FileObject).getURL() line: 703 ECRequestDescImpl.getFileName(FileObject, StringBuffer) line: 127 ECRequestDescImpl.getCompileAndSourcePath(ClassPath, StringBuffer, StringBuffer, Set) line: 98 ECRequestDescImpl.<init>(ASTProvider, ErrConsumer) line: 50 ResourceImpl$ErrorList.initCheck() line: 1167 ResourceImpl$ErrorList.size() line: 1177 J2MEEditorSupport(JavaEditor).refreshAnnotations() line: 373 JavaEditor.access$200(JavaEditor) line: 69 JavaEditor$2.run() line: 228 RequestProcessor$Task(Task).run() line: 136 RequestProcessor$Task.run() line: 330 RequestProcessor$Processor.run() line: 686
Additional info: -This problem is not occuring in beta 1. -The problem does not occur after disabling annotations (by setting tools->options->java sources->automatic parsing delay = 0)
Note that this bug also effects J2SE projects. -Create an application project that depends on a library project. -Build the library project. -Trigger the annotation process on the application project -clean/rebuild the library project will fail.
I'm not involved with mdr, and hope never to be.
I'll look into it, since everyone in Prague has probably gone home by now...
I cannot reproduce this problem on today's source base. I created a J2SE app with a dependency on a library added to the Library Manager, as Jesse describes. After invoking the error checker (just type a character), it works regardless of how I modify the library's distribution jar file. I also tried making the library a required project, with the same (non-)result. Please attach a real stacktrace of the deadlock, instead of this incomplete and inaccurate list (for example, File.File() doesn't have any synchronization). Also, if you send me a pointer to where your j2me projects live, I can investigate further. I don't think the problem has anything to do with the error checker as it doesn't synchronize any objects. My change to use the execute path instead of the compile path means that the error checker will try to access those elements returned by a ClassPath.getClassPath(ClassPath.EXECUTE) instead of ClassPath.COMPILE, but both should always return paths that are safe to access. If your code holds locks on those elements, it needs to stop doing that.
Not likely anything to do with MDR. Presumably something in the parser, and presumably specific to Windows. I agree that the top of the attached stack is not very helpful, since the File constructor does not acquire a file lock. On Windows, file locks on JARs usually occur as a result of someone making (and not closing) a ZipFile. ArchiveURLMapper will not create such a lock, but the manner in which it is being called indicates that it has been passed a FileObject from a JarFileSystem, which may have such a lock. What does look suspicious to me is ECRequestDescImpl.getCompileAndSourcePath. It gets a ClassPath.Entry and then does two things with it: 1. Uses entry.root to get the compilation CP (I guess). 2. Uses entry.url to get source roots. #2 is fine. But I can't see any justification in #1 for using entry.root rather than entry.url; in fact getFileName is only going to use the URL anyway! The only reason to call entry.root would be that it will return null if the file does not exist, which lets the code skip the CP entry. But this is an inefficient way to make that check; getFileName could take the java.io.File and call .exists() to the same effect. Now if you get the FileObject for the root of a JAR, that means making a JarFileSystem, and ArchiveURLMapper holds it softly. Ideally JFS would not hold a lock on the JAR except when first made (when it needs to scan entries) or when actually reading an entry, but perhaps it does anyway - Radek would know. Anyway, this is likely the source of the problem. ECRDI does not need to go through the Filesystems API for this piece of code, and it should avoid doing so. (Even if there were no locking issues, it is inefficient.) May be the case that this bug only became apparent due to Tom's changes re. ClassPath.EXECUTE, but it is unlikely that the problem did not exist before that; would apply to any situation where you are compiling against a JAR file and subsequently want to delete it.
Created attachment 17365 [details] Possible diff - please test
I made up a testing patch that might correct the problem, by using URL over FileObject wherever possible. I don't run Windows so I can't really know. It at least compiles and does not cause me obvious problems on Linux. Anyone who is able to reproduce this bug, please check whether the patch cures it. Please note that I do not work on this module, this is just a guess what is wrong (and how it should be corrected). Fortunately it seemed all the suspicious code was relatively well localized to this one Java source.
The patch does not resolve the issue.
This problem is caused by the following commit: java/gjast/libsrc/org/netbeans/lib/gjast/Attic/ASClassReader.java revision 1.1.2.19 date: 2004/08/12 22:33:53; author: tball; state: Exp; lines: +45 -3 Improved attribution speed by caching jar file contents. Jar files are hold in private static Map<String,SharedArchive> sharedArchives Disabling the cache fixes the problem. Here is the diff: RCS file: /nbextra/java/gjast/libsrc/org/netbeans/lib/gjast/Attic/ASClassReader.java,v retrieving revision 1.1.2.21 diff -c -r1.1.2.21 ASClassReader.java *** ASClassReader.java 2004/08/26 21:10:39 1.1.2.21 --- ASClassReader.java 2004/09/06 08:31:12 *************** *** 85,91 **** if (archive == null || file.lastModified() > archive.lastModified) { ZipFile zdir = new ZipFile(file); archive = new SharedArchive(zdir, file.lastModified()); ! sharedArchives.put(dirname, archive); } return archive; } --- 85,91 ---- if (archive == null || file.lastModified() > archive.lastModified) { ZipFile zdir = new ZipFile(file); archive = new SharedArchive(zdir, file.lastModified()); ! // sharedArchives.put(dirname, archive); } return archive; } Note that this is not a fix. This is just a prove what caused the problem. Tom has to fix it correctly. I will attach modified gjast.jar as a short-term workaround.
I am sorry, I cannot attach modified gjast.jar, since it is larger than attachment limit.
Note that the patch I attached may be desirable for performance and robustness reasons whether or not it is needed to fix this problem. Will leave it at that, was just jumping in because it was a Friday. :-)
Removed jar caching from ClassReader for beta2.
*** Issue 48736 has been marked as a duplicate of this issue. ***
Reorganization of java component