Bug 39007 - Infinite loop trying to index a non-existing external jar
Summary: Infinite loop trying to index a non-existing external jar
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.1   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 3.0 M2   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-06-17 06:57 EDT by Jerome Lanneluc CLA
Modified: 2003-07-17 05:50 EDT (History)
0 users

See Also:


Attachments
Proposed patch for AddJarFileToIndex.execute() (6.23 KB, text/plain)
2003-06-17 07:09 EDT, Philipe Mulet CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jerome Lanneluc CLA 2003-06-17 06:57:26 EDT
Build 20030611

I was running the JDT/Core test under the debugger while Norton Antivirus was 
also running. At one points, the tests hang. The indexer was in an infinite 
loop: it was trying to index D:/eclipse/lib/lib27.jar (which doesn't exist).
Comment 1 Philipe Mulet CLA 2003-06-17 07:05:20 EDT
Problem comes from the (external) JAR indexing job which will consistently fail 
indexing the missing JAR, due to IOException. Thus it keeps discarding all it 
knows about the index, which will cause the index to be reacquired later on, 
and fail once again in the subsequent iteration (for same reason).

Proposed workaround is to check for ZipException, if so, then pretend the index 
is ok (empty). This means that missing/invalid archives are treated as if empty.
Ideally, the IOExceptions should be narrowed to offending code (when opening 
ZIP vs. when saving index).

Wondering if the same protection shouldn't be added to other kinds of resources 
as well.

Note that an alternative existency check could come into play to deal with 
this, but wouldn't capture the possible infinite regression raised by corrupted 
JARs.
Comment 2 Philipe Mulet CLA 2003-06-17 07:09:26 EDT
Created attachment 5207 [details]
Proposed patch for AddJarFileToIndex.execute()
Comment 3 Philipe Mulet CLA 2003-06-20 11:52:07 EDT
The reason why the tests are failing is that the lib27.jar is being requested 
for indexing, but before it gets there, the file is removed by the test itself 
(indexer is behind).
Comment 4 Kent Johnson CLA 2003-06-20 12:37:10 EDT
But how does that cause an infinite loop?

The job is deleting the index but who is constantly asking for the index? If 
the test that deleted the jar file is done, who is left who cares about it?

I propose this change to the execute method:

				try {
					if (resource != null) {
						IPath location = 
this.resource.getLocation();
						if (location == null) return 
false;
						if 
(JavaModelManager.ZIP_ACCESS_VERBOSE)
							System.out.println("(" 
+ Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile 
on " + location); //$NON-NLS-1$	//$NON-NLS-2$
							zip = new ZipFile
(location.toFile());
						zipFilePath = (Path) 
this.resource.getFullPath().makeRelative();
						// absolute path relative to 
the workspace
					} else {
						if 
(JavaModelManager.ZIP_ACCESS_VERBOSE)
							System.out.println("(" 
+ Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile 
on " + this.indexPath); //$NON-NLS-1$	//$NON-NLS-2$
						zip = new ZipFile
(this.indexPath.toFile());
						zipFilePath = (Path) 
this.indexPath;
						// path is already canonical 
since coming from a library classpath entry
					}
				} catch (IOException e) {
					// if zip couldn't be found or read 
properly; replace the index in the cache with an empty one
					manager.recreateIndex(this.indexPath);
					return true;
				}
Comment 5 Jerome Lanneluc CLA 2003-06-23 05:24:14 EDT
What we observed was: 
- AddJarFileToIndex.execute(...) called getIndex(indexPath, false, false)
- IndexManager.getIndex(...) didn't have an in-memmory index (indexes.get(Path) 
returns null). 
- symatrically its state was UNKNOWN, this caused a call to rebuildIndex(...)
- rebuildIndex(...) changed the state to 'REBUILDING_STATE' and posted another 
AddJarFileToIndex job for the same jar
- back in AddJarFileToIndex.execute(...), it tried to open the jar and failed 
with an IOException.
- the catch IOException block removed the index and its state: it was back to 
UNKNOWN
- when ran, the second posted job did the same, thus the infinite loop
Comment 6 Kent Johnson CLA 2003-06-23 09:43:21 EDT
That cannot happen since every update job calls aboutToUpdateIndex which makes 
sure that the state is changed from UNKNOWN to UPDATE or REBUILD, so getIndex 
only sees indexes in an UNKNOWN state from query jobs.
Comment 7 Kent Johnson CLA 2003-06-23 14:10:50 EDT
Put in protection for Rebuild jobs to ensure they do not cause another rebuild 
job to be added when they call getIndex IFF the index is no longer in a Rebuild 
state.
Comment 8 David Audel CLA 2003-07-17 05:50:44 EDT
Verified.