Bug 558832 - Provide support for determining the original value of the PATH environment variable
Summary: Provide support for determining the original value of the PATH environment va...
Status: NEW
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Launcher (show other bugs)
Version: 4.15   Edit
Hardware: PC Windows 7
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Sravan Kumar Lakkimsetti CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 546153
  Show dependency tree
 
Reported: 2020-01-06 07:13 EST by Ed Merks CLA
Modified: 2020-05-23 12:00 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 Ed Merks CLA 2020-01-06 07:13:32 EST
The Eclipse Installer ideally could determine if the JVM being used by the installer itself is the default one as determined by the original value of the PATH environment variable.  I.e., the installer should be able to determine whether it should or should not generate a -vm argument in the eclipse.ini:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=546153

Unfortunately the native launcher augments and modifies the PATH before it launches the Java process.

So we have horrible code like this, which works only for Windows and works only because we can determine (in a hacky way) how the native launcher has modified the original PATH to search only the original PATH.

https://git.eclipse.org/c/oomph/org.eclipse.oomph.git/tree/plugins/org.eclipse.oomph.jreinfo/src/org/eclipse/oomph/jreinfo/JREManager.java#n242

One easy fix/workaround would be if the native launcher recorded the original PATH in some other environment variable that the installer could inspect, e.g., perhaps as single as this this in eclipseMain.c:

    setenv("ORIGINAL_PATH", getenv("PATH"), 1);

Does this seem feasible?
Comment 1 Sravan Kumar Lakkimsetti CLA 2020-01-13 06:34:25 EST
Windows and Linux:
In launcher we search for java executable in the environment variable PATH. specific code is available in this method findSymlinkCommand https://git.eclipse.org/c/equinox/rt.equinox.framework.git/tree/features/org.eclipse.equinox.executable.feature/library/eclipseCommon.c#n179

Mac:
Launcher finds the default java with the following command
/usr/libexec/java_home -a <architecture>


There are two ways of loading Java for eclipse
1. Launcher starts a small launcher process then launches java in a separate process using java executable (not applicable to mac)
2. Launcher runs eclipse executable and loads java vm in the same process by loading jvm.lib library available in the java installation. (Mac uses this)

I don't think there is a common solution for this. 
 the default for linux and windows is to launch java in a separate process than launcher and in case of Mac load java in to the launcher process itself.

the specific code is available in the findSymlinkcommand method for windows and Linux and using java_home utility for mac
Comment 2 Ed Merks CLA 2020-01-13 10:11:14 EST
(In reply to Sravan Kumar Lakkimsetti from comment #1)
> Windows and Linux:
> In launcher we search for java executable in the environment variable PATH.
> specific code is available in this method findSymlinkCommand
> https://git.eclipse.org/c/equinox/rt.equinox.framework.git/tree/features/org.
> eclipse.equinox.executable.feature/library/eclipseCommon.c#n179
> 

Yes, I'm more familiar with that approach...
> Mac:
> Launcher finds the default java with the following command
> /usr/libexec/java_home -a <architecture>
> 

Ah, I see and we already use this to get the list of all Javas...

      ProcessBuilder builder = new ProcessBuilder();
      builder.command("/usr/libexec/java_home", "-X");

So on Mac these two would be sufficient to determine all the Javas and the default system Java...

> 
> There are two ways of loading Java for eclipse
> 1. Launcher starts a small launcher process then launches java in a separate
> process using java executable (not applicable to mac)

So only Windows and Linux do this and only this?


> 2. Launcher runs eclipse executable and loads java vm in the same process by
> loading jvm.lib library available in the java installation. (Mac uses this)
>

So only the Mac does this and only this.

> I don't think there is a common solution for this. 

No, that seems clear now.  Thanks.

>  the default for linux and windows is to launch java in a separate process
> than launcher and in case of Mac load java in to the launcher process itself.
> 

Hmm, so Windows and Linux might also launch in the same process via a linked library?  How does the user/product influence that behavior? 

In either of these cases (Windows/Linux, separate process/same process, I think the PATH itself is changed by the native code.  Certainly on Windows it's generally different from the value I see on the command line from which I've actually launched.  Does it make sense in these two cases to record the original PATH value in another environment variable so that the installer (Java application) can also look at the original PATH to replicate what the native launcher does in terms of finding the Java the system uses by default?

If not, can you think of any other or better way that the launched Java application on Windows and Linux can determine the default Java implementation of the original system?

> the specific code is available in the findSymlinkcommand method for windows
> and Linux and using java_home utility for mac
Comment 3 Sravan Kumar Lakkimsetti CLA 2020-01-14 06:06:01 EST
(In reply to Ed Merks from comment #2)
> (In reply to Sravan Kumar Lakkimsetti from comment #1)
> > There are two ways of loading Java for eclipse
> > 1. Launcher starts a small launcher process then launches java in a separate
> > process using java executable (not applicable to mac)
> 
> So only Windows and Linux do this and only this?
No Windows and Linux can use library approach it will be jvm.dll and libjvm.so
You need to provide absolute path to this library with -vm option
> 
> 
> > 2. Launcher runs eclipse executable and loads java vm in the same process by
> > loading jvm.lib library available in the java installation. (Mac uses this)
> >
> 
> So only the Mac does this and only this.
yes
> 
> > I don't think there is a common solution for this. 
> 
> No, that seems clear now.  Thanks.
> 
> >  the default for linux and windows is to launch java in a separate process
> > than launcher and in case of Mac load java in to the launcher process itself.
> > 
> 
> Hmm, so Windows and Linux might also launch in the same process via a linked
> library?  How does the user/product influence that behavior? 

I noticed some differences in handling splash screen. There are no other differences
> 
> In either of these cases (Windows/Linux, separate process/same process, I
> think the PATH itself is changed by the native code.  Certainly on Windows
> it's generally different from the value I see on the command line from which
> I've actually launched.  Does it make sense in these two cases to record the
> original PATH value in another environment variable so that the installer
> (Java application) can also look at the original PATH to replicate what the
> native launcher does in terms of finding the Java the system uses by default?
> 
> If not, can you think of any other or better way that the launched Java
> application on Windows and Linux can determine the default Java
> implementation of the original system?
> 
> > the specific code is available in the findSymlinkcommand method for windows
> > and Linux and using java_home utility for mac

I have one thought

Can do something like creating symbolic link to java folder inside eclipse folder? (applicable to windows and linux) need to be tested on windows though.

rationale here is 
for the first preference eclipse looks for a folder named jre in the eclipse  and uses jre/bin/java to launch eclipse.
If this location is corrupted due to removed target or upgraded launcher will use java from the path.

Will this solve the original problem?