Bug 156307 - JavaElement.getURLContents() hack breaks "Open External Javadoc"
Summary: JavaElement.getURLContents() hack breaks "Open External Javadoc"
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: 3.3 M6   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-09-06 00:22 EDT by Frederic Plante CLA
Modified: 2007-03-21 10:13 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Frederic Plante CLA 2006-09-06 00:22:41 EDT
The finally clause of JavaElement.getURLContents() contains a hack whose reported purpose is to avoid leaking file handles.

if (connection2 != null) {
  try {
	connection2.getJarFile().close();
  } catch(IOException e) {
	// ignore
  } catch(IllegalStateException e) {
	/*
	 * ignore. Can happen in case the stream.close() did close the jar file
	 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=140750
	 */
  }
}

Unfortunately, this breaks the ability to "open external Javadoc".

Scenario:

Precondition:
  a) A plug-in exposes some API
  b) It does not provide source
  b) It uses the pde.javadoc extension-point

Step 1) Open Java Editor and type in the name of a class that is exposed
Step 2) Select the class name
Step 3) Shift+F2 -> Will open Javadoc in browser -> Great!
Step 4) Type '.' after the class name + Ctrl+Space -> Content Assist -> Great!
Step 5) Select the class name
Step 6) Shift+F2 again -> Will open browser... but no Javadoc -> Bug

Commenting the code above resolves the problem.

Before commenting out, playing with the content assist often resulted in some IllegalStateException and/or the Javadoc hover stopped working.

Please consider for 3.2.1 since this renders the new Javadoc functionality pretty much useless as-is. The latter is important for commercial products which cannot ship source code.
Comment 1 Olivier Thomann CLA 2006-09-06 11:44:32 EDT

*** This bug has been marked as a duplicate of 147771 ***
Comment 2 Frederic Plante CLA 2006-09-06 12:14:59 EDT
This is not a duplicate (at least from a use case standpoint). I can reproduce the problem described below without the IllegalStateException.
Comment 3 Olivier Thomann CLA 2006-09-06 14:41:09 EDT
Step 3) Shift+F2 doesn't do anything. It says something like the javadoc location is not properly set up.
Comment 4 Frederic Plante CLA 2006-09-06 14:45:53 EDT
Are you sure you setup your plug-in properly in a) b) c) ?

Also, when testing such functionality, be sure to deploy your plug-in as opposed to run it from the workspace.
Comment 5 Olivier Thomann CLA 2006-09-06 15:23:51 EDT
On step 3, I get this url
http://127.0.0.1:61975/help/nftopic/jar:file:/D:/eclipse/M0823/eclipse/plugins/test2_1.0.0/doc.zip!/p/p1/A.html
And this ends up with an empty javadoc.
Comment 6 Frederic Plante CLA 2006-09-06 15:30:09 EDT
That's what I get in step 6)
Comment 7 Olivier Thomann CLA 2006-09-06 15:39:32 EDT
Commenting out the code you mentionned doesn't change anything. So I doubt that I reproduced your problem.
Comment 8 Wassim Melhem CLA 2006-09-07 01:05:22 EDT
Olivier,

The javadoc location is set correctly on the JAR, but for some reason, shift-F2 only works when source is attached.

here is a test case on I20060906-1200 that uses jdt.core source/javadoc as example.

Scenario A: jdt.core source/javadoc are available
1. Launch a runtime workbench on a fresh workspace
2. Create a new plug-in project.  Press Finish on the Plug-in Content page of the wizard.  No need for templates.
3. Open the Activator java file.  In any method, type: "JavaCore.getEncoding()"
4. Select "JavaCore" from 3, and press Shift-F2.  Browser opens with javadoc pointing to the right html.  all good.
5. shut down runtime workbench.

Scenario B: sabotage soure location of jdt.core, leave javadoc unchanged
1. Go to the <eclipse_installation>/plugins/org.eclipse.jdt.source_xxxx/src/org.eclipse.jdt.core_3.3.0.v_711 and append 'olivier' to the name of the directory (ie. org.eclipse.jdt.core_3.3.0.v_711olivier'.  This will prevent PDE to not be able to locate the source code.

2. Launch a runtime workbench on workspace from scenario A.

3. When you press Shift-F2 on JavaCore this time around, the browser will open but it will contain nothing.  Not good.  
Comment 9 Frederic Plante CLA 2006-09-07 08:41:47 EDT
The configuration I used in step 3), which worked, did not contain the source code. "Open External Javadoc" works without source code.

Comment 10 Olivier Thomann CLA 2006-09-08 15:55:52 EDT
I cannot reproduce your step 3).
I don't get anything.
I'll try to debug Wassim's test case.
Comment 11 Larry Isaacs CLA 2006-10-17 12:08:22 EDT
We are seeing this issue as well and agree with Frederic Plants assessment that "this renders the new Javadoc functionality pretty much useless as-is".  I am able to reproduce with Wassim's Scenario B, though key to triggering the failure is to hover over the JavaCore to display the Javadoc in the popup window prior to using Shift-F2.  This invokes the code cited at the beginning of this report and leads to the problem.  

However, I think worse than the impact on Shift-F2 is that all other attempts to display Javadoc from the same jar (or zip) will fail.  Add a statement like "IJavaElement temp;" and then hover over the "IJavaElement" after the popup for "JavaCore" was displayed.  No popup appears.  If your "eclipse.ini" contains "-consolelog", then you will see the expected "java.lang.IllegalStateException: zip file closed".  Once upon a time the getURLContents() method contained:

if ("jar".equals(docUrl.getProtocol())) { //$NON-NLS-1$
	// if jar protocol is using a cache, some file descriptors are left behind and the resource cannot be deleted
	connection.setUseCaches(false);
}

This was removed at revision 1.115, though the fix proposed for bug 122506 did not include it's removal.  If getURLContents() is going to close the jar file, wouldn't calling "setUseCaches(false)" be required.  As currently written, the Javadoc popup gets one shot at a single entry in a Javadoc archive before other popups and Shift-F2 stop working.

During investigation, I discovered there is kind of a workaround.  In our case, the zip containing our Javadoc is also hooked into the help system.  The Help system manipulates the URLConnection.defaultUseCaches so it is possible can make it false.  Specifically, org.eclipse.help.internal.util.ResourceLocator.openFromZip() calls both URLConnection.setDefaultUseCaches() and URLConnection.setUseCaches() with false.  Thus, if we open the help contents, access our zip, and then close the help, then URLConnection.useCaches defaults false and Javadoc popups and Shift-F2 work again.  Because org.eclipse.help.internal.protocols.HelpURLConnection's constructor calls setDefaultUseCaches(), opening the help contents to something else can set the default true again, and Javadoc popups and Shift-F2 return to being broken.

I think it would be appropriate for getURLContents() to control it's own destiny and call URLConnection.setUseCaches() with the appropriate value so it's not left up to what the help system left as the default.  It should at least set it false for jar files if the jar file is going to be closed.
Comment 12 Olivier Thomann CLA 2006-10-20 14:09:35 EDT
I released the proposed change:
 connection.setUseCaches(false);
Please let me know if the next integration build fixed your issue. I leave it open till I get a confirmation that it works now without the workaround.
Comment 13 Olivier Thomann CLA 2006-10-31 14:21:19 EST
No feedback on this one?
Comment 14 Larry Isaacs CLA 2006-10-31 14:27:51 EST
Sorry. So far I've only downloaded the build.  Testing it is fairly high on the to-do list, but I've got a work deadline and testing related to the imminent release of Web Tools 1.5.2.  I should be able to get to it late today or tomorrow.
Comment 15 Larry Isaacs CLA 2006-11-01 09:09:08 EST
Verified in the I20061024-0800 build and more recent I20061031-0656 build that in Scenario B, hovering over two different classes from jdt.core successfully display without throwing the "zip file closed" exception.  Thanks.
Comment 16 Olivier Thomann CLA 2007-02-09 11:12:19 EST
So, ok to close ?
Comment 17 Larry Isaacs CLA 2007-02-09 11:47:54 EST
I verified again using M4 (don't have karma to mark verified).  It's okay by me to verify and close.
Comment 18 Olivier Thomann CLA 2007-02-09 11:53:51 EST
I'll close as as part of 3.3M6 then it will go through the verification loop before 3.3M6.
Released for 3.3M6.
Comment 19 David Audel CLA 2007-03-21 10:13:52 EDT
Verified by Larry Isaacs.