Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 346624 - [Browser] With the SystemBrowserInstance, IWebBrowser#openURL() fails unless called on the Display Thread
Summary: [Browser] With the SystemBrowserInstance, IWebBrowser#openURL() fails unless ...
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.6.2   Edit
Hardware: PC Linux-GTK
: P3 normal (vote)
Target Milestone: 4.2.1   Edit
Assignee: Eric Moffatt CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-20 06:09 EDT by Martin Oberhuber CLA
Modified: 2012-08-30 13:27 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Oberhuber CLA 2011-05-20 06:09:14 EDT
CQ:WIND00277253

When the Web Browser is configured to use the System Browser, calling
    IWebBrowser#openURL()
on a Thread other than the Display thread fails with following message:

  "Could not open a Web Browser because there are none configured.
   Check the Web Browser Preferences."

This is highly confusing for end users, because one (or even more) web browsers are properly configured. It's also confusing for end users, becasue IWebBrowser#openURL() API does not mention that it must be called on the Display Thread.

The reason for the problem is, that SWT Program#findProgram() is used in SystemBrowserInstance, and that API only works on the Display Thread.
Comment 1 Martin Oberhuber CLA 2011-05-20 06:24:28 EDT
Steps to Reproduce:
1. On Linux-GTK, launch Eclipse
2. Window > Preferences > Help > Web Browser.
    - Verify that the System Web Browser is found.
3. Have some app/snippet run this snippet, which opens an URL from a 
   background Job:

   IProgressService ps = PlatformUI.getWorkbench().getProgressService();
   ps.busyCursorWhile(new IRunnableWithProgress() {
      public void run(IProgressMonitor monitor) 
             throws InvocationTargetException, InterruptedException {
         try {
            WebBrowserUtil.getExternalBrowser().openURL(url);
         } catch (PartInitException e) {
            throw new InvocationTargetException(e);
         }
      }
   });

For testing, this snippet can be put into HelpContentsAction#run(), then
Help > Help Contents exhibits the same problem.

I'm not sure what's the best way solving this problem, since the Display Thread may be blocked and this not available for syncExec(). The method is meant to be synchronous so asyncExec() may also not be a good idea. Perhaps the best approach is this:

- SystemBrowserInstance probes if running on Display Thread
  - If yes, then result of Program#findProgram("html") is cached
  - If no, then the cached result is used (cause it's known to fail otherwise)

This approach might work fine since in most cases it's called from the Display Thread. As an additional measure, IWebBrowser#openURL() could add documentation that it's recommended to be run on the Display Thread.
Comment 2 Prakash Rangaraj CLA 2011-05-29 16:12:33 EDT
Browser component is maintained by UA
Comment 3 Martin Oberhuber CLA 2011-07-29 12:42:01 EDT
Ping, I think as a first simple step to address this, IWebBrowser#openURL() should add documentation that it's recommended to be run on the Display Thread.

This would help clients do the right thing in the future. In fact, I think documenting this limitation which already exists is quite logical, since opening an URL in a Web Browser is a UI interaction.
Comment 4 Chris Goldthorpe CLA 2011-08-23 12:46:39 EDT
I think Martin's suggestion is a good one. Sending back to platform UI to add JavaDoc comments to org.eclipse.ui.browser.IWebBrowser, which is in the bundle org.eclipse.ui.workbench.
Comment 5 Eric Moffatt CLA 2011-10-11 16:00:52 EDT
Do either of you know if any similar restrictions apply to any of the other IWebBrowser methods ?

I'll take this one...I've marked it for M6 just to make sure it doesn't disappear off of my radar...
Comment 6 Chris Goldthorpe CLA 2011-10-11 16:31:15 EDT
getId() does not need to be run on the UI thread.

For consistency if we document the restriction that openURL() can only be called from the UI thread we should do the same for close().
Comment 7 Eric Moffatt CLA 2012-08-14 11:22:11 EDT
commit 38c313384663a3e47ff3f54831cd92d4dad0540e

Updated the javadoc as per Chris' comments...
Comment 8 Eric Moffatt CLA 2012-08-30 13:27:52 EDT
Verified (visually) in M20120829-1200.