summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2014-09-10 14:56:25 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2014-10-06 11:09:05 +0200
commit4e98212a0faab7540d383c4210f32567fa640e9e (patch)
tree8c381b1bc615155423110afddf17fb9fd8526259
parentf6eca82c58ebff172b3a4b8a82a2b3db88696ab1 (diff)
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) Change-Id: I3a3ade25322def0c0432b369848f13a6b82034a1 Conflicts: include/jvmfwk/framework.h jvmfwk/source/framework.cxx
-rw-r--r--include/jvmfwk/framework.h34
-rw-r--r--jvmfwk/source/framework.cxx375
2 files changed, 253 insertions, 156 deletions
diff --git a/include/jvmfwk/framework.h b/include/jvmfwk/framework.h
index c404a9591158..6b1921e06906 100644
--- a/include/jvmfwk/framework.h
+++ b/include/jvmfwk/framework.h
@@ -72,8 +72,8 @@ 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
- of Jar files should be knows by a class loader. If a jar file depends on another
+ <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
to add files to the class path which is to be used by all users then one can use
@@ -341,12 +341,25 @@ 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
+ 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 <JavaInfo></code> objects that are related to the PATH variable
+ are examined.
+ If no suitable <code>JavaInfo</code> object is found, 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
<code>JFW_FEATURE_ACCESSBRIDGE</code> in the member <code>nFeatures</code>
@@ -355,13 +368,12 @@ JVMFWK_DLLPUBLIC javaFrameworkError SAL_CALL jfw_isVMRunning(sal_Bool *bRunning)
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>
+ <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.
diff --git a/jvmfwk/source/framework.cxx b/jvmfwk/source/framework.cxx
index c138f7ecbb63..7a2919730431 100644
--- a/jvmfwk/source/framework.cxx
+++ b/jvmfwk/source/framework.cxx
@@ -462,9 +462,12 @@ javaFrameworkError SAL_CALL jfw_startVM(
/** We do not use here jfw_findAllJREs and then check if a JavaInfo
meets the requirements, because that means using all plug-ins, which
- may take quite a while. The implementation uses one plug-in and if
- it already finds a suitable JRE then it is done and does not need to
- load another plug-in
+ may take quite a while. The implementation first inspects JAVA_HOME and
+ PATH environment variables. If no suitable JavaInfo is found there, it uses
+ one plug-in and if it already finds a suitable JRE then it is done and
+ does not need to load another plug-in.
+ Nevertheless, several plug-ins might be used for inspecting JAVA_HOME
+ and PATH for Java installations.
*/
javaFrameworkError SAL_CALL jfw_findAndSelectJRE(JavaInfo **pInfo)
{
@@ -476,175 +479,257 @@ javaFrameworkError SAL_CALL jfw_findAndSelectJRE(JavaInfo **pInfo)
return JFW_E_DIRECT_MODE;
sal_uInt64 nFeatureFlags = 0;
jfw::CJavaInfo aCurrentInfo;
-//Determine if accessibility support is needed
+ //Determine if accessibility support is needed
bool bSupportAccessibility = jfw::isAccessibilitySupportDesired();
nFeatureFlags = bSupportAccessibility ?
JFW_FEATURE_ACCESSBRIDGE : 0L;
-
- //Get a list of services which provide Java information
- jfw::VendorSettings aVendorSettings;
- std::vector<jfw::PluginLibrary> vecPlugins =
- aVendorSettings.getPluginData();
-#ifndef DISABLE_DYNLOADING
- //Create a vector that holds the libraries, which will be later
- //dynamically loaded;
- boost::scoped_array<osl::Module> sarModules;
- sarModules.reset(new osl::Module[vecPlugins.size()]);
- osl::Module * arModules = sarModules.get();
-#endif
- //Use every plug-in library to get Java installations. At the first usable
- //Java the loop will break
- typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
- int cModule = 0;
- for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i, ++cModule)
+ // 'bInfoFound' indicates whether a Java installation has been found
+ // that supports all desired features
+ bool bInfoFound = false;
+
+ // first inspect JAVA installation that the JAVA_HOME
+ // environment variable points to (if it is set)
+ char *szJavaHome= getenv("JAVA_HOME");
+ if(szJavaHome)
{
- const jfw::PluginLibrary & library = *i;
- jfw::VersionInfo versionInfo =
- aVendorSettings.getVersionInformation(library.sVendor);
-#ifndef DISABLE_DYNLOADING
- arModules[cModule].load(library.sPath);
- osl::Module & pluginLib = arModules[cModule];
- if (pluginLib.is() == sal_False)
- return JFW_E_NO_PLUGIN;
-
- jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
- (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol(
- OUString("jfw_plugin_getAllJavaInfos"));
-#else
- jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
- jfw_plugin_getAllJavaInfos;
-#endif
- OSL_ASSERT(getAllJavaFunc);
- if (getAllJavaFunc == NULL)
- continue;
-
- //get all installations of one vendor according to minVersion,
- //maxVersion and excludeVersions
- sal_Int32 cInfos = 0;
- JavaInfo** arInfos = NULL;
- javaPluginError plerr = (*getAllJavaFunc)(
- library.sVendor.pData,
- versionInfo.sMinVersion.pData,
- versionInfo.sMaxVersion.pData,
- versionInfo.getExcludeVersions(),
- versionInfo.getExcludeVersionSize(),
- & arInfos,
- & cInfos);
-
- if (plerr != JFW_PLUGIN_E_NONE)
- continue;
- //iterate over all installations to find the best which has
- //all features
- if (cInfos == 0)
+ OUString sHome(szJavaHome, strlen(szJavaHome), osl_getThreadTextEncoding());
+ OUString sHomeUrl;
+ if(osl::File::getFileURLFromSystemPath(sHome, sHomeUrl) == osl::File::E_None)
{
- rtl_freeMemory(arInfos);
- continue;
+ if(!sHomeUrl.isEmpty())
+ {
+ JavaInfo* pHomeInfo = NULL;
+ if (jfw_getJavaInfoByPath(sHomeUrl.pData, &pHomeInfo) == JFW_E_NONE)
+ {
+ aCurrentInfo = pHomeInfo;
+
+ // compare features
+ // if the user does not require any features (nFeatureFlags = 0)
+ // or the Java installation provides all features, then this installation is used
+ if ((pHomeInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
+ {
+ bInfoFound = true;
+ }
+ jfw_freeJavaInfo(pHomeInfo);
+ }
+ }
}
- bool bInfoFound = false;
- for (int ii = 0; ii < cInfos; ii++)
- {
- JavaInfo* pJInfo = arInfos[ii];
+ }
- //We remember the very first installation in aCurrentInfo
- if (aCurrentInfo.getLocation().isEmpty())
- aCurrentInfo = pJInfo;
- // compare features
- // If the user does not require any features (nFeatureFlags = 0)
- // then the first installation is used
- if ((pJInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
+ // if no Java installation providing all features was detected by using JAVA_HOME,
+ // query PATH for Java installations
+ if (!bInfoFound)
+ {
+ char *szPath= getenv("PATH");
+ if(szPath)
+ {
+ OUString usAllPath(szPath, strlen(szPath), osl_getThreadTextEncoding());
+ sal_Int32 nIndex = 0;
+ do
{
- //the just found Java implements all required features
- //currently there is only accessibility!!!
- aCurrentInfo = pJInfo;
- bInfoFound = true;
- break;
+ OUString usToken = usAllPath.getToken( 0, SAL_PATHSEPARATOR, nIndex );
+ OUString usFileUrl;
+ if(osl::File::getFileURLFromSystemPath(usToken, usFileUrl) == osl::File::E_None)
+ {
+ if(!usFileUrl.isEmpty())
+ {
+ JavaInfo* pJInfo = NULL;
+ if (jfw_getJavaInfoByPath(usFileUrl.pData, &pJInfo) == JFW_E_NONE)
+ {
+ // if the current Java installation implements all required features: use it
+ if ((pJInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
+ {
+ aCurrentInfo = pJInfo;
+ bInfoFound = true;
+ }
+ else if ((JavaInfo*) pJInfo == NULL)
+ {
+ // current Java installation does not provide all features
+ // but no Java installation has been detected before
+ // -> remember the current one until one is found
+ // that provides all features
+ aCurrentInfo = pJInfo;
+ }
+
+ jfw_freeJavaInfo(pJInfo);
+ }
+ }
+ }
}
+ while ( nIndex >= 0 && !bInfoFound);
}
- //The array returned by jfw_plugin_getAllJavaInfos must be freed as well as
- //its contents
- for (int j = 0; j < cInfos; j++)
- jfw_freeJavaInfo(arInfos[j]);
- rtl_freeMemory(arInfos);
-
- if (bInfoFound == true)
- break;
- //All Java installations found by the current plug-in lib
- //do not provide the required features. Try the next plug-in
}
- if ((JavaInfo*) aCurrentInfo == NULL)
- {//The plug-ins did not find a suitable Java. Now try the paths which have been
- //added manually.
- //get the list of paths to jre locations which have been added manually
- const jfw::MergedSettings settings;
- //node.loadFromSettings();
- const std::vector<OUString> & vecJRELocations =
- settings.getJRELocations();
- //use every plug-in to determine the JavaInfo objects
- bool bInfoFound = false;
- for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i)
+
+ // if no suitable Java installation has been found yet:
+ // first iterate over plugins to find a suitable Java installation,
+ // then try paths that have been added manually
+ typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
+ if (!bInfoFound)
+ {
+ //Get a list of services which provide Java information
+ jfw::VendorSettings aVendorSettings;
+ std::vector<jfw::PluginLibrary> vecPlugins =
+ aVendorSettings.getPluginData();
+#ifndef DISABLE_DYNLOADING
+ //Create a vector that holds the libraries, which will be later
+ //dynamically loaded;
+ boost::scoped_array<osl::Module> sarModules;
+ sarModules.reset(new osl::Module[vecPlugins.size()]);
+ osl::Module * arModules = sarModules.get();
+#endif
+ //Use every plug-in library to get Java installations. At the first usable
+ //Java the loop will break
+ int cModule = 0;
+ for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i, ++cModule)
{
const jfw::PluginLibrary & library = *i;
jfw::VersionInfo versionInfo =
aVendorSettings.getVersionInformation(library.sVendor);
#ifndef DISABLE_DYNLOADING
- osl::Module pluginLib(library.sPath);
+ arModules[cModule].load(library.sPath);
+ osl::Module & pluginLib = arModules[cModule];
if (pluginLib.is() == sal_False)
return JFW_E_NO_PLUGIN;
- //Check if the current plugin can detect JREs at the location
- // of the paths added by jfw_setJRELocations or jfw_addJRELocation
- //get the function from the plugin
- jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
- (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
- OUString("jfw_plugin_getJavaInfoByPath"));
+
+ jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
+ (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol(
+ OUString("jfw_plugin_getAllJavaInfos"));
#else
- jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
- jfw_plugin_getJavaInfoByPath;
+ jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
+ jfw_plugin_getAllJavaInfos;
#endif
- OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
- if (jfw_plugin_getJavaInfoByPathFunc == NULL)
- return JFW_E_ERROR;
+ OSL_ASSERT(getAllJavaFunc);
+ if (getAllJavaFunc == NULL)
+ continue;
- typedef std::vector<OUString>::const_iterator citLoc;
- for (citLoc it = vecJRELocations.begin();
- it != vecJRELocations.end(); ++it)
+ //get all installations of one vendor according to minVersion,
+ //maxVersion and excludeVersions
+ sal_Int32 cInfos = 0;
+ JavaInfo** arInfos = NULL;
+ javaPluginError plerr = (*getAllJavaFunc)(
+ library.sVendor.pData,
+ versionInfo.sMinVersion.pData,
+ versionInfo.sMaxVersion.pData,
+ versionInfo.getExcludeVersions(),
+ versionInfo.getExcludeVersionSize(),
+ & arInfos,
+ & cInfos);
+
+ if (plerr != JFW_PLUGIN_E_NONE)
+ continue;
+ //iterate over all installations to find the best which has
+ //all features
+ if (cInfos == 0)
{
- jfw::CJavaInfo aInfo;
- javaPluginError err = (*jfw_plugin_getJavaInfoByPathFunc)(
- it->pData,
- library.sVendor.pData,
- versionInfo.sMinVersion.pData,
- versionInfo.sMaxVersion.pData,
- versionInfo.getExcludeVersions(),
- versionInfo.getExcludeVersionSize(),
- & aInfo.pInfo);
- if (err == JFW_PLUGIN_E_NO_JRE)
- continue;
- if (err == JFW_PLUGIN_E_FAILED_VERSION)
- continue;
- else if (err !=JFW_PLUGIN_E_NONE)
- return JFW_E_ERROR;
+ rtl_freeMemory(arInfos);
+ continue;
+ }
+ for (int ii = 0; ii < cInfos; ii++)
+ {
+ JavaInfo* pJInfo = arInfos[ii];
- if (aInfo)
+ //We remember the very first installation in aCurrentInfo
+ // if no JavaInfo was found before
+ if (aCurrentInfo.getLocation().isEmpty())
+ aCurrentInfo = pJInfo;
+ // compare features
+ // If the user does not require any features (nFeatureFlags = 0)
+ // then the first installation is used
+ if ((pJInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
{
- //We remember the very first installation in aCurrentInfo
- if (aCurrentInfo.getLocation().isEmpty())
- aCurrentInfo = aInfo;
- // compare features
- // If the user does not require any features (nFeatureFlags = 0)
- // then the first installation is used
- if ((aInfo.getFeatures() & nFeatureFlags) == nFeatureFlags)
- {
- //the just found Java implements all required features
- //currently there is only accessibility!!!
- aCurrentInfo = aInfo;
- bInfoFound = true;
- break;
- }
+ //the just found Java implements all required features
+ //currently there is only accessibility!!!
+ aCurrentInfo = pJInfo;
+ bInfoFound = true;
+ break;
}
- }//end iterate over paths
+ }
+ //The array returned by jfw_plugin_getAllJavaInfos must be freed as well as
+ //its contents
+ for (int j = 0; j < cInfos; j++)
+ jfw_freeJavaInfo(arInfos[j]);
+ rtl_freeMemory(arInfos);
+
if (bInfoFound == true)
break;
- }// end iterate plug-ins
+ //All Java installations found by the current plug-in lib
+ //do not provide the required features. Try the next plug-in
+ }
+
+ if ((JavaInfo*) aCurrentInfo == NULL)
+ {//The plug-ins did not find a suitable Java. Now try the paths which have been
+ //added manually.
+ //get the list of paths to jre locations which have been added manually
+ const jfw::MergedSettings settings;
+ //node.loadFromSettings();
+ const std::vector<OUString> & vecJRELocations =
+ settings.getJRELocations();
+ //use every plug-in to determine the JavaInfo objects
+ for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i)
+ {
+ const jfw::PluginLibrary & library = *i;
+ jfw::VersionInfo versionInfo =
+ aVendorSettings.getVersionInformation(library.sVendor);
+#ifndef DISABLE_DYNLOADING
+ osl::Module pluginLib(library.sPath);
+ if (pluginLib.is() == sal_False)
+ return JFW_E_NO_PLUGIN;
+ //Check if the current plugin can detect JREs at the location
+ // of the paths added by jfw_setJRELocations or jfw_addJRELocation
+ //get the function from the plugin
+ jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
+ (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
+ OUString("jfw_plugin_getJavaInfoByPath"));
+#else
+ jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
+ jfw_plugin_getJavaInfoByPath;
+#endif
+ OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
+ if (jfw_plugin_getJavaInfoByPathFunc == NULL)
+ return JFW_E_ERROR;
+
+ typedef std::vector<OUString>::const_iterator citLoc;
+ for (citLoc it = vecJRELocations.begin();
+ it != vecJRELocations.end(); ++it)
+ {
+ jfw::CJavaInfo aInfo;
+ javaPluginError err = (*jfw_plugin_getJavaInfoByPathFunc)(
+ it->pData,
+ library.sVendor.pData,
+ versionInfo.sMinVersion.pData,
+ versionInfo.sMaxVersion.pData,
+ versionInfo.getExcludeVersions(),
+ versionInfo.getExcludeVersionSize(),
+ & aInfo.pInfo);
+ if (err == JFW_PLUGIN_E_NO_JRE)
+ continue;
+ if (err == JFW_PLUGIN_E_FAILED_VERSION)
+ continue;
+ else if (err !=JFW_PLUGIN_E_NONE)
+ return JFW_E_ERROR;
+
+ if (aInfo)
+ {
+ //We remember the very first installation in aCurrentInfo
+ if (aCurrentInfo.getLocation().isEmpty())
+ aCurrentInfo = aInfo;
+ // compare features
+ // If the user does not require any features (nFeatureFlags = 0)
+ // then the first installation is used
+ if ((aInfo.getFeatures() & nFeatureFlags) == nFeatureFlags)
+ {
+ //the just found Java implements all required features
+ //currently there is only accessibility!!!
+ aCurrentInfo = aInfo;
+ bInfoFound = true;
+ break;
+ }
+ }
+ }//end iterate over paths
+ if (bInfoFound == true)
+ break;
+ }// end iterate plug-ins
+ }
}
if ((JavaInfo*) aCurrentInfo)
{