Bug 405942 - Please adapt Eclipse to the new Runtime.exec behavior in Java 1.7.0_21 and Java 1.6.0_45
Summary: Please adapt Eclipse to the new Runtime.exec behavior in Java 1.7.0_21 and Ja...
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.3   Edit
Hardware: PC Windows 8
: P1 blocker (vote)
Target Milestone: 4.3 RC3   Edit
Assignee: Platform-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 419808 (view as bug list)
Depends on:
Blocks: 408987 419032 419033 419034 419036 429546 463949
  Show dependency tree
 
Reported: 2013-04-18 02:51 EDT by Dietmar Hechensteiner CLA
Modified: 2015-04-05 20:17 EDT (History)
8 users (show)

See Also:
john.arthorne: review+
markus.kell.r: review+
manju656: review+


Attachments
Log about this error (342.27 KB, application/octet-stream)
2013-05-22 18:17 EDT, Freddy Rojas CLA
no flags Details
Fix for org.eclipse.ui.browser (2.89 KB, patch)
2013-05-23 10:36 EDT, Dani Megert CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dietmar Hechensteiner CLA 2013-04-18 02:51:23 EDT
Sample Error Log

!ENTRY org.eclipse.ui.browser 4 0 2013-04-18 08:44:05.419
!MESSAGE Launching C:\Program Files (x86)\Mozilla Firefox\firefox.exe has failed.
!STACK 0
java.io.IOException: Cannot run program "C:\Program": CreateProcess error=2, Das System kann die angegebene Datei nicht finden
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1042)
	at java.lang.Runtime.exec(Runtime.java:615)
	at java.lang.Runtime.exec(Runtime.java:448)
	at java.lang.Runtime.exec(Runtime.java:345)
	at org.eclipse.ui.internal.browser.browsers.MozillaBrowser$BrowserThread.openBrowser(MozillaBrowser.java:94)
	at org.eclipse.ui.internal.browser.browsers.MozillaBrowser$BrowserThread.run(MozillaBrowser.java:165)
Caused by: java.io.IOException: CreateProcess error=2, Das System kann die angegebene Datei nicht finden
	at java.lang.ProcessImpl.create(Native Method)
	at java.lang.ProcessImpl.<init>(ProcessImpl.java:288)
	at java.lang.ProcessImpl.start(ProcessImpl.java:133)
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1023)
	... 5 more
Comment 1 Paul Webster CLA 2013-04-19 07:05:42 EDT
What's the new behaviour (as opposed to what happened before)?

PW
Comment 3 Freddy Rojas CLA 2013-05-22 18:17:31 EDT
Created attachment 231340 [details]
Log about this error

It happens when I try to use Firefox as external browser. It doesn't happen when I use Google Chrome or Internet Explorer. This bug is caused in both Windows 7 and Windows 8 64-bit and Firefox is 32-bit.
Comment 4 Freddy Rojas CLA 2013-05-22 18:22:17 EDT
!ENTRY org.eclipse.wst.common.project.facet.core 4 0 2013-05-21 23:04:24.554
!MESSAGE Project facet jst.ejb has not been defined. It is used in plugin org.eclipse.jst.server.core.
!SESSION 2013-05-22 16:16:09.142 -----------------------------------------------
eclipse.buildId=M20130204-1200
java.version=1.7.0_21
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=es_CO
Framework arguments:  -product org.eclipse.epp.package.jee.product
Command-line arguments:  -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product

!ENTRY org.eclipse.egit.ui 2 0 2013-05-22 16:17:11.393
!MESSAGE Warning: EGit couldn't detect the installation path "gitPrefix" of native Git. Hence EGit can't respect system level
Git settings which might be configured in ${gitPrefix}/etc/gitconfig under the native Git installation directory.
The most important of these settings is core.autocrlf. Git for Windows by default sets this parameter to true in
this system level configuration. The Git installation location can be configured on the
Team > Git > Configuration preference page's 'System Settings' tab.
This warning can be switched off on the Team > Git > Confirmations and Warnings preference page.

!ENTRY org.eclipse.egit.ui 2 0 2013-05-22 16:17:11.408
!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git
user global configuration and to define the default location to store repositories: 'C:\Users\Freddy'. If this is
not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and
EGit might behave differently since they see different configuration options.
This warning can be switched off on the Team > Git > Confirmations and Warnings preference page.

!ENTRY org.eclipse.wst.server.core 4 0 2013-05-22 16:18:28.522
!MESSAGE Could not publish to the server.
!STACK 0
java.lang.NullPointerException
	at org.eclipse.wst.server.http.core.internal.HttpServerBehaviour.publishModule(HttpServerBehaviour.java:95)
	at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publishModule(ServerBehaviourDelegate.java:1091)
	at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publishModules(ServerBehaviourDelegate.java:1183)
	at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publish(ServerBehaviourDelegate.java:987)
	at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publish(ServerBehaviourDelegate.java:774)
	at org.eclipse.wst.server.core.internal.Server.publishImpl(Server.java:3153)
	at org.eclipse.wst.server.core.internal.Server$PublishJob.run(Server.java:345)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)

!ENTRY org.eclipse.ui.browser 4 0 2013-05-22 16:19:18.585
!MESSAGE Launching C:\Program Files (x86)\Mozilla Firefox\firefox.exe has failed.
!STACK 0
java.io.IOException: Cannot run program "C:\Program": CreateProcess error=2, El sistema no puede encontrar el archivo especificado
	at java.lang.ProcessBuilder.start(Unknown Source)
	at java.lang.Runtime.exec(Unknown Source)
	at java.lang.Runtime.exec(Unknown Source)
	at java.lang.Runtime.exec(Unknown Source)
	at org.eclipse.ui.internal.browser.browsers.MozillaBrowser$BrowserThread.openBrowser(MozillaBrowser.java:94)
	at org.eclipse.ui.internal.browser.browsers.MozillaBrowser$BrowserThread.run(MozillaBrowser.java:165)
Caused by: java.io.IOException: CreateProcess error=2, El sistema no puede encontrar el archivo especificado
	at java.lang.ProcessImpl.create(Native Method)
	at java.lang.ProcessImpl.<init>(Unknown Source)
	at java.lang.ProcessImpl.start(Unknown Source)
	... 6 more

!ENTRY org.eclipse.ui.browser 4 0 2013-05-22 16:20:47.830
!MESSAGE Launching C:\Program Files (x86)\Mozilla Firefox\firefox.exe has failed.
!STACK 0
java.io.IOException: Cannot run program "C:\Program": CreateProcess error=2, El sistema no puede encontrar el archivo especificado
	at java.lang.ProcessBuilder.start(Unknown Source)
	at java.lang.Runtime.exec(Unknown Source)
	at java.lang.Runtime.exec(Unknown Source)
	at java.lang.Runtime.exec(Unknown Source)
	at org.eclipse.ui.internal.browser.browsers.MozillaBrowser$BrowserThread.openBrowser(MozillaBrowser.java:94)
	at org.eclipse.ui.internal.browser.browsers.MozillaBrowser$BrowserThread.run(MozillaBrowser.java:165)
Caused by: java.io.IOException: CreateProcess error=2, El sistema no puede encontrar el archivo especificado
	at java.lang.ProcessImpl.create(Native Method)
	at java.lang.ProcessImpl.<init>(Unknown Source)
	at java.lang.ProcessImpl.start(Unknown Source)
	... 6 more

!ENTRY org.eclipse.ui.browser 4 0 2013-05-22 16:22:40.087
!MESSAGE Launching C:\Program Files (x86)\Mozilla Firefox\firefox.exe has failed.
!STACK 0
java.io.IOException: Cannot run program "C:\Program": CreateProcess error=2, El sistema no puede encontrar el archivo especificado
	at java.lang.ProcessBuilder.start(Unknown Source)
	at java.lang.Runtime.exec(Unknown Source)
	at java.lang.Runtime.exec(Unknown Source)
	at java.lang.Runtime.exec(Unknown Source)
	at org.eclipse.ui.internal.browser.browsers.MozillaBrowser$BrowserThread.openBrowser(MozillaBrowser.java:94)
	at org.eclipse.ui.internal.browser.browsers.MozillaBrowser$BrowserThread.run(MozillaBrowser.java:165)
Caused by: java.io.IOException: CreateProcess error=2, El sistema no puede encontrar el archivo especificado
	at java.lang.ProcessImpl.create(Native Method)
	at java.lang.ProcessImpl.<init>(Unknown Source)
	at java.lang.ProcessImpl.start(Unknown Source)
	... 6 more
Comment 5 Dani Megert CLA 2013-05-23 09:09:54 EDT
We have to fix this for Kepler and not just for opening the Firefox browser: almost all programs on Windows are in "Program Files" or "Program Files (x86)" i.e. have a space in it. Any code that uses java.lang.Runtime.exec(String) to call a program from there, will fail on the latest Oracle JREs, both 32- and 64-bit.

We have to make a pass over the whole code base.
Comment 6 Dani Megert CLA 2013-05-23 10:35:21 EDT
Runtime.exec(String) specifies:

     * <p>More precisely, the <code>command</code> string is broken
     * into tokens using a {@link StringTokenizer} created by the call
     * <code>new {@link StringTokenizer}(command)</code> with no
     * further modification of the character categories.  The tokens
     * produced by the tokenizer are then placed in the new string
     * array <code>cmdarray</code>, in the same order.

So far, the implementation for Windows tried to be smart and was able to pass the right string to the native API. In the latest updates it now only treats the first element in the command array as the executable.

The general fix is to use the Runtime.exec(String[] cmdArray) API where
cmdArray[0] = the command
cmdArray[1..] = the parameters split with the StringTokenizer

In cases where we only have one parameter we can also use this pattern:
Runtime.exec(new String[] {command, parameter}).

If we assume that the implementations on all platforms use the StringTokenizer approach as specified by the Javadoc, then this fix works on all platforms and we don't have to make the fix Windows specific.
Comment 7 Dani Megert CLA 2013-05-23 10:36:08 EDT
Created attachment 231380 [details]
Fix for org.eclipse.ui.browser
Comment 8 John Arthorne CLA 2013-05-23 12:02:26 EDT
This fix looks good to me. I will do some more testing this afternoon.

We should able to use String.split instead of StringTokenizer to simplify the code a bit, but either approach works.
Comment 9 Dani Megert CLA 2013-05-23 12:03:42 EDT
(In reply to comment #8)
> This fix looks good to me. I will do some more testing this afternoon.
> 
> We should able to use String.split instead of StringTokenizer to simplify
> the code a bit, but either approach works.

I know, but wanted to be as close to the specified behavior, which uses StringTokenizer.

Once we have a reviewed fix, we can open bugs for the other components. I will take care of Platform UI.
Comment 10 Markus Keller CLA 2013-05-23 12:54:00 EDT
+1, the fix looks good and works with new and older JREs.

The StringTokenizer is explicitly specified in the crazy java.lang.Runtime#exec(String[,..]) APIs, so that's the safest fix at this time. I checked a few Linux and Mac VMs and they all use the StringTokenizer.

Unfortunately, there's no way to be fully correct on all platforms with a single API, see bug 387504 comment 13. Correct parsing on most platforms would use org.eclipse.debug.core.DebugPlugin#parseArguments(String), which also supports spaces/quotes/escapes in the arguments as specified by sh.

On Windows, the native CreateProcess API takes a complete "commandLine" string argument. Since Java doesn't offer a direct API for that, everything we do means we have to reverse-engineer the JRE's transformations and bugs (see bug 387504 comment 0).
Comment 11 Markus Keller CLA 2013-05-23 12:58:05 EDT
There's another change for this in the pipeline (on top of 7u21 etc.):
http://bugs.sun.com/view_bug.do?bug_id=8012453
Comment 12 Martin Oberhuber CLA 2013-05-24 10:39:04 EDT
(In reply to comment #10)
> On Windows, the native CreateProcess API takes a complete "commandLine"
> string argument. Since Java doesn't offer a direct API for that, everything
> we do means we have to reverse-engineer the JRE's transformations and bugs

Oracle recommends using ProcessBuilder which is available since Java 5, would that be an option ?

http://www.oracle.com/technetwork/java/javase/7u21-relnotes-1932873.html#jruntime
Comment 13 Markus Keller CLA 2013-05-24 11:09:08 EDT
All Runtime.exec(..) implementations already end up using a ProcessBuilder, so it doesn't matter which entry point we use (but Runtime.exec(..) is more convenient).

All implementation changes were in ProcessBuilder/ProcessImpl. The advice to use ProcessBuilder is a general advice, but it doesn't change anything for anyone affected by this change. The advice doesn't make much sense in these release notes (which on the other hand fail to tell that the behavior of the Runtime.exec(String[], ..) and ProcessBuilder APIs have also been changed).
Comment 14 Dani Megert CLA 2013-05-27 09:10:05 EDT
(In reply to comment #9)
> Once we have a reviewed fix, we can open bugs for the other components. I
> will take care of Platform UI.

The following cases:
    MozillaBrowserAdapter.BrowserThread.openBrowser(String)
    MozillaFactory.isAvailable()
in 'org.eclipse.help.base' are fine, because the factory is for Linux based Mozilla browsers only.


The usages in 'org.eclipse.ui.workbench':
    DefaultWebBrowser.openURL(URL)
    DefaultWebBrowser.openWebBrowser(String)
are also OK, because for Windows, we use Program.launch(String).
Comment 15 Martin Mathew CLA 2013-05-27 12:14:25 EDT
+1, the patch looks good. Tested using Java 1.7.0_21 and it works fine.
Comment 17 Dani Megert CLA 2013-05-28 16:23:56 EDT
Verified in I20130528-1200.
Comment 18 Paul Webster CLA 2013-10-25 08:41:59 EDT
*** Bug 419808 has been marked as a duplicate of this bug. ***