Kaydet (Commit) 40138cee authored tarafından Michael Weghorn's avatar Michael Weghorn Kaydeden (comit) Stephan Bergmann

fdo#83753: consider JAVA_HOME and PATH when selecting JRE

adapted algorithm that selects the Java runtime to be used so that
Java installations associated with the JAVA_HOME and PATH
environment variables are preferred over others

Java installations are now analysed in the following order:
* installation that the JAVA_HOME environment
    variable refers to (if it is set)
* Java installations in PATH
* other Java installation (algorithm that was used before)
Signed-off-by: 's avatarStephan Bergmann <sbergman@redhat.com>

Conflicts:
	jvmfwk/source/framework.cxx

Change-Id: I3a3ade25322def0c0432b369848f13a6b82034a1
üst 86910c87
......@@ -72,7 +72,7 @@ extern "C" {
necessary to specify the bootstrap parameter <code>UNO_JAVA_JFW_SHARED_DATA</code>.
</p>
<p>Setting the class path used by a Java VM should not be necesarry. The locations
<p>Setting the class path used by a Java VM should not be necessary. The locations
of Jar files should be known by a class loader. If a jar file depends on another
jar file then it can be referenced in the manifest file of the first jar. However,
a user may add jars to the class path by using this API. If it becomes necessary
......@@ -320,16 +320,11 @@ JVMFWK_DLLPUBLIC javaFrameworkError SAL_CALL jfw_isVMRunning(sal_Bool *bRunning)
/** detects a suitable JRE and configures the framework to use it.
<p>Which JREs can be used is determined by the file javavendors.xml,
which contains version requirements, as well as information about available
plug-in libraries. Only these libraries are responsible for locating JRE
installations.</p>
which contains version requirements.</p>
<p>
JREs can be provided by different vendors. In order to find the JREs of
a certain vendor a plug-in library must be provided. There must be only one
library for one vendor. The names of locations of those libraries have to
be put into the javavendors.xml file.<br/>
The function uses the plug-in libraries to obtain information about JRE
installation and checks if they there is one among them that supports
JREs can be provided by different vendors.
The function obtains information about JRE installations and checks if
there is one among them that supports
a set of features (currently only accessibilty is possible). If none was
found then it also uses a list of paths, which have been registered
by <code>jfw_addJRELocation</code>
......@@ -342,27 +337,36 @@ JVMFWK_DLLPUBLIC javaFrameworkError SAL_CALL jfw_isVMRunning(sal_Bool *bRunning)
<p>
While determining a proper JRE this function takes into account if a
user requires support for assistive technology tools. If user
need that support they have to set up their system accordingly. When support
for assistive technology is required, then the lists of
need that support they have to set up their system accordingly.</p>
<p>
If the JAVA_HOME environment variable is set, this function prefers
the JRE which the variable refers to over other JREs.
If JAVA_HOME is not set or does not refer to a suitable JRE,
the PATH environment variable is inspected and the respective JREs
are checked for their suitability next.</p>
<p>
When support for assistive technology is required, then the
<code>JavaInfo</code> objects,
which are provided by the <code>getJavaInfo</code> functions of the plug-ins, are
examined for a suitable JRE. That is, the <code>JavaInfo</code> objects
from the list
obtained from the first plug-in, are examined. If no <code>JavaInfo</code>
object has the flag
which are provided by the <code>getJavaInfo</code> functions, are
examined for a suitable JRE.
That is, the <code>JavaInfo</code> object that refers to the JRE referred to
by JAVA_HOME is examined. If it does not have the flag
<code>JFW_FEATURE_ACCESSBRIDGE</code> in the member <code>nFeatures</code>
then the
next plug-in is used to obtain a list of <code>JavaInfo</code> objects.
then the <JavaInfo></code> objects that are related to the PATH variable
are examined.
If no suitable <code>JavaInfo</code> object is found, all <code>JavaInfo</code>
objects - representing Java installations on the system -, are examined.
As long as no <code>JavaInfo</code> object has the flag
<code>JFW_FEATURE_ACCESSBRIDGE</code> in the member <code>nFeatures</code>, more
<code>JavaInfo</code> objects are examined.
This goes on until a <code>JavaInfo</code> object was found which
represents a suitable JRE. Or neither plug-in provided such a
<code>JavaInfo</code> object. In that case the first
<code>JavaInfo</code> object from the first plug-in is used to determine
the JRE which is to be used.</p>
represents a suitable JRE. Or no such <code>JavaInfo</code> object was found.
In that case the first <code>JavaInfo</code> object that was detected
by the algorithm described above is used to determine the JRE which is to be used.</p>
<p>
If there is no need for the support of assistive technology tools then
the first <code>JavaInfo</code> object from the list obtained by the
first plug-in is used. If this plug-in does not find any JREs then the
next plug-in is used, and so on.</p>
the first <code>JavaInfo</code> object that is detected by the algorithm
as described above is used.</p>
@param ppInfo
[out] a <code>JavaInfo</code> pointer, representing the selected JRE.
......
......@@ -24,6 +24,9 @@
#include <jvmfwk/framework.h>
#include <rtl/ustring.h>
#include "jni.h"
#include <vector>
#include <utility>
#include "../source/elements.hxx"
/**
@file
......@@ -168,6 +171,81 @@ javaPluginError jfw_plugin_getJavaInfoByPath(
sal_Int32 nSizeExcludeList,
JavaInfo ** ppInfo);
/** obtains information for a JRE referenced by the JAVA_HOME environment variable.
<p>If the JAVA_HOME environment variable is set and points to a JRE whoose vendor
matches the requirements given by vecVendorInfos (i.e. it has a vendor that is
given in vecVendorInfos and the version requirements for the vendor are met),
then this function shall return a JavaInfo object for this JRE.</p>
@param vecVendorInfos
[in] vector specifying the vendor and version requirements that the JRE must fulfill.
The vector contains pairs of vendors and the respective version requirements
for those vendors. The JRE must support the requirements of one given pair in the
vector (i.e. it must be of one of the vendors and meet the version requirements
- minVersion, maxVersion, excludeVersions - for that specific vendor).
@param ppInfo
[out] if the JAVA_HOME environment variable is set and points to a suitable
JRE, then then <code>ppInfo</code> contains
on return a pointer to its <code>JavaInfo</code> object.
@return
JFW_PLUGIN_E_NONE the function ran successfully.</br>
JFW_PLUGIN_E_INVALID_ARG an argument was not valid, for example
<code>ppInfo</code> is an invalid pointer.
JFW_PLUGIN_E_NO_JRE no suitable JRE could be detected at the given location. However, that
does not mean necessarily that there is no JRE. There could be a JRE but it has
a vendor which is not supported by this API implementation or it does not
meet the version requirements.
*/
javaPluginError jfw_plugin_getJavaInfoFromJavaHome(
std::vector<std::pair<OUString, jfw::VersionInfo>> const& vecVendorInfos,
JavaInfo ** ppInfo);
/** obtains information about installations of Java Runtime Environments (JREs)
whose executable is in the PATH.
<p>The function gathers information about available JREs which are on the PATH
(PATH environment variable) and meet the vendor and version requirements given by
<code>vecVendorInfos</code> (i.e. they have a vendor that is given in
<code>vecVendorInfos</code> and the version requirements for the vendor are met).
</p>
<p>
The JavaInfo structures returned in <code>vecJavaInfosFromPath</code> should be ordered
according to their occurrence in the PATH. The one that is the first one on the PATH
is also the first element in the vector.</p>
<p>
The function allocates memory for all the JavaInfo objects returned
in <code>vecJavaInfosFromPath</code>. The caller must free each JavaInfo object by calling
<code>jfw_freeJavaInfo</code> (#include "jvmfwk/framework.h").
</p>
@param vecVendorInfos
[in] vector specifying the vendor and version requirements that the JRE must fulfill.
The vector contains pairs of vendors and the respective version requirements
for those vendors. The JRE must support the requirements of one given pair in the
vector (i.e. it must be of one of the vendors and meet the version requirements
- minVersion, maxVersion, excludeVersions - for that specific vendor).
@param vecJavaInfosFromPath
[out] if the function runs successfully then <code>vecJavaInfosFromPath</code>
contains on return a vector of pointers to <code>JavaInfo</code> objects.
On return of this function, <code>vecJavaInfosFromPath</code> references
a newly created vector rather than the same vector as before with
the <code>JavaInfo</code> objects inserted into the existing vector.
@return
JFW_PLUGIN_E_NONE the function ran successfully and at least one JRE
that meets the requirements was found.</br>
JFW_PLUGIN_E_NO_JRE no JavaInfo that meets the version criteria was found
when inspecting the PATH
*/
javaPluginError jfw_plugin_getJavaInfosFromPath(
std::vector<std::pair<OUString, jfw::VersionInfo>> const& vecVendorInfos,
std::vector<JavaInfo*> & vecJavaInfosFromPath);
/** starts a Java Virtual Machine.
<p>The caller should provide all essential JavaVMOptions, such as the
......
......@@ -404,6 +404,105 @@ javaPluginError jfw_plugin_getJavaInfoByPath(
return errorcode;
}
javaPluginError jfw_plugin_getJavaInfoFromJavaHome(
std::vector<pair<OUString, jfw::VersionInfo>> const& vecVendorInfos,
JavaInfo ** ppInfo)
{
if (!ppInfo)
return JFW_PLUGIN_E_INVALID_ARG;
rtl::Reference<VendorBase> infoJavaHome = getJavaInfoFromJavaHome();
if (!infoJavaHome.is())
return JFW_PLUGIN_E_NO_JRE;
//Check if the detected JRE matches the version requirements
typedef std::vector<pair<OUString, jfw::VersionInfo>>::const_iterator ci_pl;
for (ci_pl vendorInfo = vecVendorInfos.begin(); vendorInfo != vecVendorInfos.end(); ++vendorInfo)
{
const OUString& vendor = vendorInfo->first;
jfw::VersionInfo versionInfo = vendorInfo->second;
if (vendor.equals(infoJavaHome->getVendor()))
{
javaPluginError errorcode = checkJavaVersionRequirements(
infoJavaHome,
versionInfo.sMinVersion,
versionInfo.sMaxVersion,
versionInfo.getExcludeVersions(),
versionInfo.getExcludeVersionSize());
if (errorcode == JFW_PLUGIN_E_NONE)
{
*ppInfo = createJavaInfo(infoJavaHome);
return JFW_PLUGIN_E_NONE;
}
}
}
return JFW_PLUGIN_E_NO_JRE;
}
javaPluginError jfw_plugin_getJavaInfosFromPath(
std::vector<std::pair<OUString, jfw::VersionInfo>> const& vecVendorInfos,
std::vector<JavaInfo*> & javaInfosFromPath)
{
// find JREs from PATH
vector<rtl::Reference<VendorBase>> vecInfosFromPath;
createJavaInfoFromPath(vecInfosFromPath);
vector<rtl::Reference<VendorBase> > vecVerifiedInfos;
// copy JREs that meet version requirements to vecVerifiedInfos
typedef vector<rtl::Reference<VendorBase> >::iterator it;
for (it i= vecInfosFromPath.begin(); i != vecInfosFromPath.end(); ++i)
{
const rtl::Reference<VendorBase>& cur = *i;
typedef std::vector<pair<OUString, jfw::VersionInfo>>::const_iterator ci_pl;
for (ci_pl vendorInfo = vecVendorInfos.begin(); vendorInfo != vecVendorInfos.end(); ++vendorInfo)
{
const OUString& vendor = vendorInfo->first;
jfw::VersionInfo versionInfo = vendorInfo->second;
if (vendor.equals(cur->getVendor()))
{
javaPluginError errorcode = checkJavaVersionRequirements(
cur,
versionInfo.sMinVersion,
versionInfo.sMaxVersion,
versionInfo.getExcludeVersions(),
versionInfo.getExcludeVersionSize());
if (errorcode == JFW_PLUGIN_E_NONE)
{
vecVerifiedInfos.push_back(*i);
}
}
}
}
if (vecVerifiedInfos.empty())
return JFW_PLUGIN_E_NO_JRE;
// Now vecVerifiedInfos contains all those JREs which meet the version requirements
// Transfer them into the vector that is passed out.
vector<JavaInfo*> infosFromPath;
typedef vector<rtl::Reference<VendorBase> >::const_iterator cit;
for (cit ii = vecVerifiedInfos.begin(); ii != vecVerifiedInfos.end(); ++ii)
{
infosFromPath.push_back(createJavaInfo(*ii));
}
javaInfosFromPath = infosFromPath;
return JFW_PLUGIN_E_NONE;
}
#if defined(WNT)
// Load msvcr71.dll using an explicit full path from where it is
......
......@@ -1131,7 +1131,8 @@ void createJavaInfoFromPath(vector<rtl::Reference<VendorBase> >& vecInfos)
}
}
void createJavaInfoFromJavaHome(vector<rtl::Reference<VendorBase> >& vecInfos)
rtl::Reference<VendorBase> getJavaInfoFromJavaHome()
{
// Get Java from JAVA_HOME environment
......@@ -1142,11 +1143,28 @@ void createJavaInfoFromJavaHome(vector<rtl::Reference<VendorBase> >& vecInfos)
char *szJavaHome= getenv("JAVA_HOME");
if(szJavaHome)
{
OUString sHome(szJavaHome,strlen(szJavaHome),osl_getThreadTextEncoding());
OUString sHome(szJavaHome, strlen(szJavaHome), osl_getThreadTextEncoding());
OUString sHomeUrl;
if(File::getFileURLFromSystemPath(sHome, sHomeUrl) == File::E_None)
{
getJREInfoByPath(sHomeUrl, vecInfos);
return getJREInfoByPath(sHomeUrl);
}
}
return NULL;
}
void createJavaInfoFromJavaHome(vector<rtl::Reference<VendorBase> >& vecInfos)
{
rtl::Reference<VendorBase> aInfo = getJavaInfoFromJavaHome();
if (aInfo.is())
{
vector<rtl::Reference<VendorBase> >::const_iterator it_impl= std::find_if(
vecInfos.begin(),vecInfos.end(), InfoFindSame(aInfo->getHome()));
if(it_impl == vecInfos.end())
{
vecInfos.push_back(aInfo);
}
}
}
......
......@@ -39,6 +39,12 @@ bool getJREInfoFromBinPath(
const OUString& path, std::vector<rtl::Reference<VendorBase> > & vecInfos);
inline OUString getDirFromFile(const OUString& usFilePath);
void createJavaInfoFromPath(std::vector<rtl::Reference<VendorBase> >& vecInfos);
/* Returns a VendorBase object if JAVA_HOME environment variable points
to a JRE.
*/
rtl::Reference<VendorBase> getJavaInfoFromJavaHome();
void createJavaInfoFromJavaHome(std::vector<rtl::Reference<VendorBase> > &vecInfos);
void createJavaInfoDirScan(std::vector<rtl::Reference<VendorBase> >& vecInfos);
#ifdef WNT
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment