Kaydet (Commit) 0ec4ca54 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Let JavaVirtualMachine::getJavaVm start the VM it already found

Since b6995199 "Drop support for /etc/opt/ure
and ~/.ure from LibreOffice 4" there is no place any more where a plain URE will
store information about a selected JVM, so JavaVirtualMachine::getJavaVM will
go into an endless loop of jfw_startVM -> JFW_E_NO_SELECT ->
jfw_findAndSelectJRE -> jfw_startVM -> ...  The solution is to pass the JavaInfo
determined by jfw_findAndSelectJRE into the second invocation of jfw_startVM
(for which the parameter list of the latter needed to be changed), instead of
relying on jfw_findAndSelectJRE and jfw_startVM implicitly communicating that
information via user configuration files.

Change-Id: I5799f04c457e8a849c67ed827dc5e134c6563362
(cherry picked from commit e5546342)
üst 6f14709d
......@@ -482,6 +482,8 @@ JVMFWK_DLLPUBLIC javaFrameworkError SAL_CALL jfw_getJavaInfoByPath(
created and JFW_E_NEED_RESTART error is returned. If a VM is already running
then a JFW_E_RUNNING_JVM is returned.</p>
@param pInfo
[in] optional pointer to a specific JRE; must be caller-freed if not NULL
@param arOptions
[in] the array containing additional start arguments or NULL.
@param nSize
......@@ -516,9 +518,9 @@ JVMFWK_DLLPUBLIC javaFrameworkError SAL_CALL jfw_getJavaInfoByPath(
JFW_E_FAILED_VERSION the &quot;Default Mode&quot; is active. The JRE determined by
<code>JAVA_HOME</code>does not meet the version requirements.
*/
JVMFWK_DLLPUBLIC javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions,
sal_Int32 nSize, JavaVM **ppVM,
JNIEnv **ppEnv);
JVMFWK_DLLPUBLIC javaFrameworkError SAL_CALL jfw_startVM(
JavaInfo const * pInfo, JavaVMOption * arOptions, sal_Int32 nSize,
JavaVM ** ppVM, JNIEnv ** ppEnv);
/** determines the JRE that is to be used.
......
......@@ -25,6 +25,7 @@
#include "osl/module.hxx"
#include "jvmfwk/framework.h"
#include "jvmfwk/vendorplugin.h"
#include <cassert>
#include <vector>
#include <functional>
#include <algorithm>
......@@ -290,10 +291,12 @@ javaFrameworkError SAL_CALL jfw_findAllJREs(JavaInfo ***pparInfo, sal_Int32 *pSi
#endif
}
javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions, sal_Int32 cOptions,
JavaVM **ppVM, JNIEnv **ppEnv)
javaFrameworkError SAL_CALL jfw_startVM(
JavaInfo const * pInfo, JavaVMOption * arOptions, sal_Int32 cOptions,
JavaVM ** ppVM, JNIEnv ** ppEnv)
{
#ifndef SOLAR_JAVA
(void) pInfo;
(void) arOptions;
(void) cOptions;
(void) ppVM;
......@@ -320,84 +323,89 @@ javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions, sal_Int32 cOpti
std::vector<rtl::OString> vmParams;
rtl::OString sUserClassPath;
jfw::CJavaInfo aInfo;
jfw::JFW_MODE mode = jfw::getMode();
if (mode == jfw::JFW_MODE_APPLICATION)
if (pInfo == NULL)
{
const jfw::MergedSettings settings;
if (sal_False == settings.getEnabled())
return JFW_E_JAVA_DISABLED;
aInfo.attach(settings.createJavaInfo());
//check if a Java has ever been selected
if (aInfo == NULL)
return JFW_E_NO_SELECT;
jfw::JFW_MODE mode = jfw::getMode();
if (mode == jfw::JFW_MODE_APPLICATION)
{
const jfw::MergedSettings settings;
if (sal_False == settings.getEnabled())
return JFW_E_JAVA_DISABLED;
aInfo.attach(settings.createJavaInfo());
//check if a Java has ever been selected
if (aInfo == NULL)
return JFW_E_NO_SELECT;
#ifdef WNT
//Because on Windows there is no system setting that we can use to determine
//if Assistive Technology Tool support is needed, we ship a .reg file that the
//user can use to create a registry setting. When the user forgets to set
//the key before he starts the office then a JRE may be selected without access bridge.
//When he later sets the key then we select a JRE with accessibility support but
//only if the user has not manually changed the selected JRE in the options dialog.
if (jfw::isAccessibilitySupportDesired())
{
// If no JRE has been selected then we do not select one. This function shall then
//return JFW_E_NO_SELECT
if (aInfo != NULL &&
(aInfo->nFeatures & JFW_FEATURE_ACCESSBRIDGE) == 0)
//Because on Windows there is no system setting that we can use to determine
//if Assistive Technology Tool support is needed, we ship a .reg file that the
//user can use to create a registry setting. When the user forgets to set
//the key before he starts the office then a JRE may be selected without access bridge.
//When he later sets the key then we select a JRE with accessibility support but
//only if the user has not manually changed the selected JRE in the options dialog.
if (jfw::isAccessibilitySupportDesired())
{
//has the user manually selected a JRE?
if (settings.getJavaInfoAttrAutoSelect() == true)
// If no JRE has been selected then we do not select one. This function shall then
//return JFW_E_NO_SELECT
if (aInfo != NULL &&
(aInfo->nFeatures & JFW_FEATURE_ACCESSBRIDGE) == 0)
{
// if not then the automatism has previously selected a JRE
//without accessibility support. We return JFW_E_NO_SELECT
//to cause that we search for another JRE. The search code will
//then prefer a JRE with accessibility support.
return JFW_E_NO_SELECT;
//has the user manually selected a JRE?
if (settings.getJavaInfoAttrAutoSelect() == true)
{
// if not then the automatism has previously selected a JRE
//without accessibility support. We return JFW_E_NO_SELECT
//to cause that we search for another JRE. The search code will
//then prefer a JRE with accessibility support.
return JFW_E_NO_SELECT;
}
}
}
}
#endif
//check if the javavendors.xml has changed after a Java was selected
rtl::OString sVendorUpdate = jfw::getElementUpdated();
//check if the javavendors.xml has changed after a Java was selected
rtl::OString sVendorUpdate = jfw::getElementUpdated();
if (sVendorUpdate != settings.getJavaInfoAttrVendorUpdate())
return JFW_E_INVALID_SETTINGS;
if (sVendorUpdate != settings.getJavaInfoAttrVendorUpdate())
return JFW_E_INVALID_SETTINGS;
//check if JAVA is disabled
//If Java is enabled, but it was disabled when this process was started
// then no preparational work, such as setting the LD_LIBRARY_PATH, was
//done. Therefore if a JRE needs it it must not be started.
if (g_bEnabledSwitchedOn &&
//check if JAVA is disabled
//If Java is enabled, but it was disabled when this process was started
// then no preparational work, such as setting the LD_LIBRARY_PATH, was
//done. Therefore if a JRE needs it it must not be started.
if (g_bEnabledSwitchedOn &&
(aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
return JFW_E_NEED_RESTART;
//Check if the selected Java was set in this process. If so it
//must not have the requirments flag JFW_REQUIRE_NEEDRESTART
if ((aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART)
&&
(jfw::wasJavaSelectedInSameProcess() == true))
return JFW_E_NEED_RESTART;
vmParams = settings.getVmParametersUtf8();
sUserClassPath = jfw::makeClassPathOption(settings.getUserClassPath());
} // end mode FWK_MODE_OFFICE
else if (mode == jfw::JFW_MODE_DIRECT)
{
errcode = jfw_getSelectedJRE(&aInfo.pInfo);
if (errcode != JFW_E_NONE)
return errcode;
//In direct mode the options are specified by bootstrap variables
//of the form UNO_JAVA_JFW_PARAMETER_1 .. UNO_JAVA_JFW_PARAMETER_n
vmParams = jfw::BootParams::getVMParameters();
sUserClassPath =
"-Djava.class.path=" + jfw::BootParams::getClasspath();
return JFW_E_NEED_RESTART;
//Check if the selected Java was set in this process. If so it
//must not have the requirments flag JFW_REQUIRE_NEEDRESTART
if ((aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART)
&&
(jfw::wasJavaSelectedInSameProcess() == true))
return JFW_E_NEED_RESTART;
vmParams = settings.getVmParametersUtf8();
sUserClassPath = jfw::makeClassPathOption(settings.getUserClassPath());
} // end mode FWK_MODE_OFFICE
else if (mode == jfw::JFW_MODE_DIRECT)
{
errcode = jfw_getSelectedJRE(&aInfo.pInfo);
if (errcode != JFW_E_NONE)
return errcode;
//In direct mode the options are specified by bootstrap variables
//of the form UNO_JAVA_JFW_PARAMETER_1 .. UNO_JAVA_JFW_PARAMETER_n
vmParams = jfw::BootParams::getVMParameters();
sUserClassPath =
"-Djava.class.path=" + jfw::BootParams::getClasspath();
}
else
OSL_ASSERT(0);
pInfo = aInfo.pInfo;
}
else
OSL_ASSERT(0);
assert(pInfo != NULL);
//get the function jfw_plugin_startJavaVirtualMachine
jfw::VendorSettings aVendorSettings;
rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(aInfo.getVendor());
rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(pInfo->sVendor);
#ifndef DISABLE_DYNLOADING
osl::Module modulePlugin(sLibPath);
......@@ -454,7 +462,7 @@ javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions, sal_Int32 cOpti
//start Java
JavaVM *pVm = NULL;
SAL_INFO("jvmfwk", "starting java");
javaPluginError plerr = (*pFunc)(aInfo, arOpt, index, & pVm, ppEnv);
javaPluginError plerr = (*pFunc)(pInfo, arOpt, index, & pVm, ppEnv);
if (plerr == JFW_PLUGIN_E_VM_CREATION_FAILED)
{
errcode = JFW_E_VM_CREATION_FAILED;
......@@ -677,13 +685,13 @@ javaFrameworkError SAL_CALL jfw_findAndSelectJRE(JavaInfo **pInfo)
jfw::NodeJava javaNode(jfw::NodeJava::USER);
javaNode.setJavaInfo(aCurrentInfo,true);
javaNode.write();
//remember that this JRE was selected in this process
jfw::setJavaSelected();
if (pInfo !=NULL)
{
//copy to out param
*pInfo = aCurrentInfo.cloneJavaInfo();
//remember that this JRE was selected in this process
jfw::setJavaSelected();
}
}
else
......
......@@ -78,6 +78,7 @@
#include <time.h>
#include <memory>
#include <vector>
#include "boost/noncopyable.hpp"
#include "boost/scoped_array.hpp"
#define OUSTR(x) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x ))
......@@ -703,6 +704,23 @@ JavaVirtualMachine::getSupportedServiceNames()
return serviceGetSupportedServiceNames();
}
namespace {
struct JavaInfoGuard: private boost::noncopyable {
JavaInfoGuard(): info(0) {}
~JavaInfoGuard() { jfw_freeJavaInfo(info); }
void clear() {
jfw_freeJavaInfo(info);
info = 0;
}
JavaInfo * info;
};
}
css::uno::Any SAL_CALL
JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
throw (css::uno::RuntimeException)
......@@ -727,6 +745,7 @@ JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
if (aId != aProcessId)
return css::uno::Any();
JavaInfoGuard info;
while (!m_xVirtualMachine.is()) // retry until successful
{
// This is the second attempt to create Java. m_bDontCreateJvm is
......@@ -773,7 +792,7 @@ JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
if (getenv("STOC_FORCE_NO_JRE"))
errcode = JFW_E_NO_SELECT;
else
errcode = jfw_startVM(arOptions, index, & m_pJavaVm,
errcode = jfw_startVM(info.info, arOptions, index, & m_pJavaVm,
& pMainThreadEnv);
bool bStarted = false;
......@@ -784,7 +803,8 @@ JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
{
// No Java configured. We silenty run the java configuration
// Java.
javaFrameworkError errFind = jfw_findAndSelectJRE( NULL );
info.clear();
javaFrameworkError errFind = jfw_findAndSelectJRE(&info.info);
if (getenv("STOC_FORCE_NO_JRE"))
errFind = JFW_E_NO_JAVA_FOUND;
if (errFind == JFW_E_NONE)
......@@ -861,7 +881,9 @@ JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
if (bExist == sal_False
&& ! (pJavaInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
{
javaFrameworkError errFind = jfw_findAndSelectJRE( NULL );
info.clear();
javaFrameworkError errFind = jfw_findAndSelectJRE(
&info.info);
if (errFind == JFW_E_NONE)
{
continue;
......
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