/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: framework.cxx,v $ * * $Revision: 1.27 $ * * last change: $Author: obo $ $Date: 2006-09-16 17:47:52 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_jvmfwk.hxx" #include "boost/scoped_array.hpp" #include "rtl/ustring.hxx" #include "rtl/bootstrap.hxx" #include "osl/thread.hxx" #include "osl/module.hxx" #include "jvmfwk/framework.h" #include "jvmfwk/vendorplugin.h" #include #include #include #include "framework.hxx" #include "fwkutil.hxx" #include "elements.hxx" #include "fwkbase.hxx" #ifdef WNT /** The existence of the file useatjava.txt decides if a Java should be used that supports accessibility tools. */ #define USE_ACCESSIBILITY_FILE "useatjava.txt" #endif #define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME" namespace { JavaVM * g_pJavaVM = NULL; bool g_bEnabledSwitchedOn = false; sal_Bool areEqualJavaInfo( JavaInfo const * pInfoA,JavaInfo const * pInfoB) { return jfw_areEqualJavaInfo(pInfoA, pInfoB); } } javaFrameworkError SAL_CALL jfw_findAllJREs(JavaInfo ***pparInfo, sal_Int32 *pSize) { javaFrameworkError retVal = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); javaFrameworkError errcode = JFW_E_NONE; if (pparInfo == NULL || pSize == NULL) return JFW_E_INVALID_ARG; jfw::VendorSettings aVendorSettings; //Get a list of plugins which provide Java information std::vector vecPlugins = aVendorSettings.getPluginData(); //Create a vector that holds the libraries, which will be later //dynamically loaded; boost::scoped_array sarModules; sarModules.reset(new osl::Module[vecPlugins.size()]); osl::Module * arModules = sarModules.get(); //Add the JavaInfos found by jfw_plugin_getAllJavaInfos to the vector //Make sure that the contents are destroyed if this //function returns with an error std::vector vecInfo; //Add the JavaInfos found by jfw_plugin_getJavaInfoByPath to this vector //Make sure that the contents are destroyed if this //function returns with an error std::vector vecInfoManual; typedef std::vector::iterator it_info; //get the list of paths to jre locations which have been //added manually jfw::CNodeJava node; node.loadFromSettings(); const std::vector& vecJRELocations = node.getJRELocations(); //Use every plug-in library to get Java installations. typedef std::vector::const_iterator ci_pl; 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); arModules[cModule].load(library.sPath); osl::Module & pluginLib = arModules[cModule]; if (pluginLib.is() == sal_False) { rtl::OString msg = rtl::OUStringToOString( library.sPath, osl_getThreadTextEncoding()); fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \ "Modify the javavendors.xml accordingly!\n", msg.getStr()); return JFW_E_NO_PLUGIN; } jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc = (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos"))); OSL_ASSERT(getAllJavaFunc); if (getAllJavaFunc == NULL) return JFW_E_ERROR; //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) return JFW_E_ERROR; for (int j = 0; j < cInfos; j++) vecInfo.push_back(jfw::CJavaInfo::createWrapper(arInfos[j])); rtl_freeMemory(arInfos); //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( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath"))); OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc); if (jfw_plugin_getJavaInfoByPathFunc == NULL) return JFW_E_ERROR; typedef std::vector::const_iterator citLoc; //Check every manually added location for (citLoc ii = vecJRELocations.begin(); ii != vecJRELocations.end(); ii++) { rtl::OUString sLocation = rtl::OStringToOUString(*ii, RTL_TEXTENCODING_UTF8); jfw::CJavaInfo aInfo; plerr = (*jfw_plugin_getJavaInfoByPathFunc)( sLocation.pData, library.sVendor.pData, versionInfo.sMinVersion.pData, versionInfo.sMaxVersion.pData, versionInfo.getExcludeVersions(), versionInfo.getExcludeVersionSize(), & aInfo.pInfo); if (plerr == JFW_PLUGIN_E_NO_JRE) continue; if (plerr == JFW_PLUGIN_E_FAILED_VERSION) continue; else if (plerr !=JFW_PLUGIN_E_NONE) return JFW_E_ERROR; if (aInfo) { //Was this JRE already added?. Different plugins could detect //the same JRE it_info it_duplicate = std::find_if(vecInfoManual.begin(), vecInfoManual.end(), std::bind2nd(std::ptr_fun(areEqualJavaInfo), aInfo)); if (it_duplicate == vecInfoManual.end()) vecInfoManual.push_back(aInfo); } } } //Make sure vecInfoManual contains only JavaInfos for the vendors for which //there is a javaSelection/plugins/library entry in the javavendors.xml //To obtain the JavaInfos for the manually added JRE locations the function //jfw_getJavaInfoByPath is called which can return a JavaInfo of any vendor. std::vector vecInfoManual2; for (it_info ivm = vecInfoManual.begin(); ivm != vecInfoManual.end(); ivm++) { for (ci_pl ii = vecPlugins.begin(); ii != vecPlugins.end(); ii++) { if ( ii->sVendor.equals((*ivm)->sVendor)) { vecInfoManual2.push_back(*ivm); break; } } } //Check which JavaInfo from vector vecInfoManual2 is already //contained in vecInfo. If it already exists then remove it from //vecInfoManual2 for (it_info j = vecInfo.begin(); j != vecInfo.end(); j++) { it_info it_duplicate = std::find_if(vecInfoManual2.begin(), vecInfoManual2.end(), std::bind2nd(std::ptr_fun(areEqualJavaInfo), *j)); if (it_duplicate != vecInfoManual2.end()) vecInfoManual2.erase(it_duplicate); } //create an fill the array of JavaInfo* sal_Int32 nSize = vecInfo.size() + vecInfoManual2.size(); *pparInfo = (JavaInfo**) rtl_allocateMemory( nSize * sizeof(JavaInfo*)); if (*pparInfo == NULL) return JFW_E_ERROR; typedef std::vector::iterator it; int index = 0; //Add the automatically detected JREs for (it k = vecInfo.begin(); k != vecInfo.end(); k++) (*pparInfo)[index++] = k->detach(); //Add the manually detected JREs for (it l = vecInfoManual2.begin(); l != vecInfoManual2.end(); l++) (*pparInfo)[index++] = l->detach(); *pSize = nSize; return errcode; } catch (jfw::FrameworkException& e) { retVal = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return retVal; } javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions, sal_Int32 cOptions, JavaVM **ppVM, JNIEnv **ppEnv) { #ifndef SOLAR_JAVA return JFW_E_ERROR; #else javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); //We keep this pointer so we can determine if a VM has already //been created. if (g_pJavaVM != NULL) return JFW_E_RUNNING_JVM; if (ppVM == NULL) return JFW_E_INVALID_ARG; jfw::CNodeJava javaSettings; jfw::CJavaInfo aInfo; jfw::JFW_MODE mode = jfw::getMode(); if (mode == jfw::JFW_MODE_APPLICATION) { //check if Java is disabled sal_Bool bEnabled = sal_False; if ((errcode = jfw_getEnabled(&bEnabled)) == JFW_E_NONE) { if (bEnabled == sal_False) return JFW_E_JAVA_DISABLED; } else { return errcode; } #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()) { jfw::CJavaInfo info; javaFrameworkError err = JFW_E_NONE; if ((err = jfw_getSelectedJRE( & info.pInfo)) != JFW_E_NONE) return err; // If no JRE has been selected then we do no select one. This function shall then //return JFW_E_NO_SELECT if (info != NULL && (info->nFeatures & JFW_FEATURE_ACCESSBRIDGE) == 0) { //has the user manually selected a JRE? jfw::CNodeJava settings; settings.loadFromSettings(); if (settings.getJavaInfoAttrAutoSelect() == true) { //The currently selected JRE has no access bridge if ((err = jfw_findAndSelectJRE(NULL)) != JFW_E_NONE) return err; } } } #endif javaSettings.loadFromSettings(); //get the current java setting (javaInfo) aInfo = jfw::CJavaInfo::createWrapper(javaSettings.createJavaInfo()); //check if a Java has ever been selected if (aInfo == NULL) return JFW_E_NO_SELECT; //check if the javavendors.xml has changed after a Java was selected rtl::OString sVendorUpdate = jfw::getElementUpdated(); if (sVendorUpdate != javaSettings.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 && (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; } // end mode FWK_MODE_OFFICE else if (mode == jfw::JFW_MODE_DIRECT) { errcode = jfw_getSelectedJRE(&aInfo.pInfo); if (errcode != JFW_E_NONE) return errcode; } else OSL_ASSERT(0); //get the function jfw_plugin_startJavaVirtualMachine jfw::VendorSettings aVendorSettings; rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(aInfo.getVendor()); osl::Module modulePlugin(sLibPath); if ( ! modulePlugin) return JFW_E_NO_PLUGIN; rtl::OUString sFunctionName( RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_startJavaVirtualMachine")); jfw_plugin_startJavaVirtualMachine_ptr pFunc = (jfw_plugin_startJavaVirtualMachine_ptr) osl_getFunctionSymbol(modulePlugin, sFunctionName.pData); if (pFunc == NULL) return JFW_E_ERROR; // create JavaVMOptions array that is passed to the plugin // it contains the classpath and all options set in the //options dialog //In direct mode the options are specified by bootstrap variables //of the form UNO_JAVA_JFW_PARAMETER_1 .. UNO_JAVA_JFW_PARAMETER_n if (cOptions > 0 && arOptions == NULL) return JFW_E_INVALID_ARG; std::vector vecDirectModeOptions = jfw::BootParams::getVMParameters(); boost::scoped_array sarJOptions; if (mode == jfw::JFW_MODE_APPLICATION) sarJOptions.reset(new JavaVMOption[cOptions + 2 + javaSettings.getVmParameters().size()]); else // direct mode sarJOptions.reset(new JavaVMOption[cOptions + 2 + vecDirectModeOptions.size()]); JavaVMOption * arOpt = sarJOptions.get(); if (! arOpt) return JFW_E_ERROR; //The first argument is the classpath rtl::OString sOptionClassPath = jfw::makeClassPathOption(javaSettings); arOpt[0].optionString= (char*) sOptionClassPath.getStr(); arOpt[0].extraInfo = NULL; // Set a flag that this JVM has been created via the JNI Invocation API // (used, for example, by UNO remote bridges to share a common thread pool // factory among Java and native bridge implementations): arOpt[1].optionString = (char *) "-Dorg.openoffice.native="; arOpt[1].extraInfo = 0; //add the options set by options dialog typedef std::vector::const_iterator cit; std::vector params; if (mode == jfw::JFW_MODE_APPLICATION) params = javaSettings.getVmParameters(); else // JFW_MODE_DIRECT params = vecDirectModeOptions; int index = 2; for (cit i = params.begin(); i != params.end(); i ++) { arOpt[index].optionString= (char*) i->getStr(); arOpt[index].extraInfo = 0; index ++; } //add all options of the arOptions argument for (int ii = 0; ii < cOptions; ii++) { arOpt[index].optionString = arOptions[ii].optionString; arOpt[index].extraInfo = arOptions[ii].extraInfo; index++; } //start Java JavaVM *pVm = NULL; javaPluginError plerr = (*pFunc)(aInfo, arOpt, index, & pVm, ppEnv); if (plerr == JFW_PLUGIN_E_VM_CREATION_FAILED) { errcode = JFW_E_VM_CREATION_FAILED; } else if (plerr != JFW_PLUGIN_E_NONE ) { errcode = JFW_E_ERROR; } else { g_pJavaVM = pVm; *ppVM = pVm; } OSL_ASSERT(plerr != JFW_PLUGIN_E_WRONG_VENDOR); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; #endif } /** 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 */ javaFrameworkError SAL_CALL jfw_findAndSelectJRE(JavaInfo **pInfo) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; sal_uInt64 nFeatureFlags = 0; jfw::CJavaInfo aCurrentInfo; //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 vecPlugins = aVendorSettings.getPluginData(); //Create a vector that holds the libraries, which will be later //dynamically loaded; boost::scoped_array sarModules; sarModules.reset(new osl::Module[vecPlugins.size()]); osl::Module * arModules = sarModules.get(); //Use every plug-in library to get Java installations. At the first usable //Java the loop will break typedef std::vector::const_iterator ci_pl; 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); 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( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos"))); 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) { rtl_freeMemory(arInfos); continue; } 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().getLength() == 0) 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) { //the just found Java implements all required features //currently there is only accessibility!!! aCurrentInfo = pJInfo; bInfoFound = true; break; } } //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 jfw::CNodeJava node; node.loadFromSettings(); const std::vector & vecJRELocations = node.getJRELocations(); //use every plug-in to determine the JavaInfo objects bool bInfoFound = false; for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); i++) { const jfw::PluginLibrary & library = *i; jfw::VersionInfo versionInfo = aVendorSettings.getVersionInformation(library.sVendor); 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( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath"))); OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc); if (jfw_plugin_getJavaInfoByPathFunc == NULL) return JFW_E_ERROR; typedef std::vector::const_iterator citLoc; for (citLoc it = vecJRELocations.begin(); it != vecJRELocations.end(); it++) { rtl::OUString sLocation = rtl::OStringToOUString(*it, RTL_TEXTENCODING_UTF8); jfw::CJavaInfo aInfo; javaPluginError err = (*jfw_plugin_getJavaInfoByPathFunc)( sLocation.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().getLength() == 0) 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) { jfw::CNodeJava javaNode; javaNode.setJavaInfo(aCurrentInfo,true); javaNode.writeSettings(); if (pInfo !=NULL) { //copy to out param *pInfo = aCurrentInfo.cloneJavaInfo(); //remember that this JRE was selected in this process jfw::setJavaSelected(); } } else { errcode = JFW_E_NO_JAVA_FOUND; } } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } sal_Bool SAL_CALL jfw_areEqualJavaInfo( JavaInfo const * pInfoA,JavaInfo const * pInfoB) { if (pInfoA == pInfoB) return sal_True; if (pInfoA == NULL || pInfoB == NULL) return sal_False; rtl::OUString sVendor(pInfoA->sVendor); rtl::OUString sLocation(pInfoA->sLocation); rtl::OUString sVersion(pInfoA->sVersion); rtl::ByteSequence sData(pInfoA->arVendorData); if (sVendor.equals(pInfoB->sVendor) == sal_True && sLocation.equals(pInfoB->sLocation) == sal_True && sVersion.equals(pInfoB->sVersion) == sal_True && pInfoA->nFeatures == pInfoB->nFeatures && pInfoA->nRequirements == pInfoB->nRequirements && sData == pInfoB->arVendorData) { return sal_True; } return sal_False; } void SAL_CALL jfw_freeJavaInfo(JavaInfo *pInfo) { if (pInfo == NULL) return; rtl_uString_release(pInfo->sVendor); rtl_uString_release(pInfo->sLocation); rtl_uString_release(pInfo->sVersion); rtl_byte_sequence_release(pInfo->arVendorData); rtl_freeMemory(pInfo); } javaFrameworkError SAL_CALL jfw_getSelectedJRE(JavaInfo **ppInfo) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (ppInfo == NULL) return JFW_E_INVALID_ARG; if (jfw::getMode() == jfw::JFW_MODE_DIRECT) { rtl::OUString sJRE = jfw::BootParams::getJREHome(); jfw::CJavaInfo aInfo; if ((errcode = jfw_getJavaInfoByPath(sJRE.pData, & aInfo.pInfo)) != JFW_E_NONE) throw jfw::FrameworkException( JFW_E_CONFIGURATION, rtl::OString( "[Java framework] The JRE specified by the bootstrap " "variable UNO_JAVA_JFW_JREHOME or UNO_JAVA_JFW_ENV_JREHOME " " could not be recognized. Check the values and make sure that you " "use a plug-in library that can recognize that JRE.")); *ppInfo = aInfo.detach(); return JFW_E_NONE; } jfw::CNodeJava aSettings; aSettings.loadFromSettings(); jfw::CJavaInfo aInfo; aInfo.attach(aSettings.createJavaInfo()); if (! aInfo) { *ppInfo = NULL; return JFW_E_NONE; } //If the javavendors.xml has changed, then the current selected //Java is not valid anymore // /java/javaInfo/@vendorUpdate != javaSelection/updated (javavendors.xml) rtl::OString sUpdated = jfw::getElementUpdated(); if (sUpdated.equals(aSettings.getJavaInfoAttrVendorUpdate()) == sal_False) return JFW_E_INVALID_SETTINGS; *ppInfo = aInfo.detach(); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_isVMRunning(sal_Bool *bRunning) { osl::MutexGuard guard(jfw::getFwkMutex()); if (bRunning == NULL) return JFW_E_INVALID_ARG; if (g_pJavaVM == NULL) *bRunning = sal_False; else *bRunning = sal_True; return JFW_E_NONE; } javaFrameworkError SAL_CALL jfw_getJavaInfoByPath( rtl_uString *pPath, JavaInfo **ppInfo) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (pPath == NULL || ppInfo == NULL) return JFW_E_INVALID_ARG; jfw::VendorSettings aVendorSettings; //Get a list of plugins which provide Java information std::vector vecPlugins = aVendorSettings.getPluginData(); //Create a vector that holds the libraries, which will be later //dynamically loaded; boost::scoped_array sarModules; sarModules.reset(new osl::Module[vecPlugins.size()]); osl::Module * arModules = sarModules.get(); typedef std::vector::const_iterator CIT_VENDOR; std::vector vecVendors = aVendorSettings.getSupportedVendors(); //Use every plug-in library to determine if the path represents a //JRE. If a plugin recognized it then the loop will break typedef std::vector::const_iterator ci_pl; 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); arModules[cModule].load(library.sPath); osl::Module & pluginLib = arModules[cModule]; if (pluginLib.is() == sal_False) { rtl::OString msg = rtl::OUStringToOString( library.sPath, osl_getThreadTextEncoding()); fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \ "Modify the javavendors.xml accordingly!\n", msg.getStr()); return JFW_E_NO_PLUGIN; } jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc = (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath"))); OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc); if (jfw_plugin_getJavaInfoByPathFunc == NULL) continue; //ask the plugin if this is a JRE. //If so check if it meets the version requirements. //Only if it does return a JavaInfo JavaInfo* pInfo = NULL; javaPluginError plerr = (*jfw_plugin_getJavaInfoByPathFunc)( pPath, library.sVendor.pData, versionInfo.sMinVersion.pData, versionInfo.sMaxVersion.pData, versionInfo.getExcludeVersions(), versionInfo.getExcludeVersionSize(), & pInfo); if (plerr == JFW_PLUGIN_E_NONE) { //check if the vendor of the found JRE is supported if (vecVendors.size() == 0) { //vendor does not matter *ppInfo = pInfo; break; } else { rtl::OUString sVendor(pInfo->sVendor); CIT_VENDOR ivendor = std::find(vecVendors.begin(), vecVendors.end(), sVendor); if (ivendor != vecVendors.end()) { *ppInfo = pInfo; } else { *ppInfo = NULL; errcode = JFW_E_NOT_RECOGNIZED; } break; } } else if(plerr == JFW_PLUGIN_E_FAILED_VERSION) {//found JRE but it has the wrong version *ppInfo = NULL; errcode = JFW_E_FAILED_VERSION; break; } else if (plerr == JFW_PLUGIN_E_NO_JRE) {// plugin does not recognize this path as belonging to JRE continue; } OSL_ASSERT(0); } if (*ppInfo == NULL && errcode != JFW_E_FAILED_VERSION) errcode = JFW_E_NOT_RECOGNIZED; } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_setSelectedJRE(JavaInfo const *pInfo) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; //check if pInfo is the selected JRE JavaInfo *currentInfo = NULL; errcode = jfw_getSelectedJRE( & currentInfo); if (errcode != JFW_E_NONE && errcode != JFW_E_INVALID_SETTINGS) return errcode; if (jfw_areEqualJavaInfo(currentInfo, pInfo) == sal_False) { jfw::CNodeJava node; node.setJavaInfo(pInfo, false); node.writeSettings(); //remember that the JRE was selected in this process jfw::setJavaSelected(); } } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_setEnabled(sal_Bool bEnabled) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; jfw::CNodeJava node; if (g_bEnabledSwitchedOn == false && bEnabled == sal_True) { //When the process started then Enabled was false. //This is first time enabled is set to true. //That means, no preparational work has been done, such as setting the //LD_LIBRARY_PATH, etc. //check if Enabled is false; node.loadFromSettings(); if (node.getEnabled() == sal_False) g_bEnabledSwitchedOn = true; } node.setEnabled(bEnabled); node.writeSettings(); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_getEnabled(sal_Bool *pbEnabled) { javaFrameworkError errcode = JFW_E_NONE; try { if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; osl::MutexGuard guard(jfw::getFwkMutex()); if (pbEnabled == NULL) return JFW_E_INVALID_ARG; jfw::CNodeJava node; node.loadFromSettings(); *pbEnabled = node.getEnabled(); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_setVMParameters( rtl_uString * * arOptions, sal_Int32 nLen) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; jfw::CNodeJava node; if (arOptions == NULL && nLen != 0) return JFW_E_INVALID_ARG; node.setVmParameters(arOptions, nLen); node.writeSettings(); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_getVMParameters( rtl_uString *** parOptions, sal_Int32 * pLen) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; if (parOptions == NULL || pLen == NULL) return JFW_E_INVALID_ARG; jfw::CNodeJava node; node.loadFromSettings(); node.getVmParametersArray(parOptions, pLen); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_setUserClassPath(rtl_uString * pCp) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; jfw::CNodeJava node; if (pCp == NULL) return JFW_E_INVALID_ARG; node.setUserClassPath(pCp); node.writeSettings(); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_getUserClassPath(rtl_uString ** ppCP) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; if (ppCP == NULL) return JFW_E_INVALID_ARG; jfw::CNodeJava node; node.loadFromSettings(); *ppCP = node.getUserClassPath().pData; rtl_uString_acquire(*ppCP); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_addJRELocation(rtl_uString * sLocation) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; jfw::CNodeJava node; if (sLocation == NULL) return JFW_E_INVALID_ARG; node.loadFromSettings(); node.addJRELocation(sLocation); node.writeSettings(); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_setJRELocations( rtl_uString ** arLocations, sal_Int32 nLen) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; jfw::CNodeJava node; if (arLocations == NULL && nLen != 0) return JFW_E_INVALID_ARG; node.setJRELocations(arLocations, nLen); node.writeSettings(); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } javaFrameworkError SAL_CALL jfw_getJRELocations( rtl_uString *** parLocations, sal_Int32 *pLen) { javaFrameworkError errcode = JFW_E_NONE; try { osl::MutexGuard guard(jfw::getFwkMutex()); if (jfw::getMode() == jfw::JFW_MODE_DIRECT) return JFW_E_DIRECT_MODE; if (parLocations == NULL || pLen == NULL) return JFW_E_INVALID_ARG; jfw::CNodeJava node; node.loadFromSettings(); node.getJRELocations(parLocations, pLen); } catch (jfw::FrameworkException& e) { errcode = e.errorCode; fprintf(stderr, e.message.getStr()); OSL_ENSURE(0, e.message.getStr()); } return errcode; } void SAL_CALL jfw_lock() { osl::Mutex * mutex = jfw::getFwkMutex(); mutex->acquire(); } void SAL_CALL jfw_unlock() { osl::Mutex * mutex = jfw::getFwkMutex(); mutex->release(); } namespace jfw { CJavaInfo::CJavaInfo(): pInfo(0) { } CJavaInfo::CJavaInfo(const CJavaInfo & info) { pInfo = copyJavaInfo(info.pInfo); } CJavaInfo::CJavaInfo(::JavaInfo * info, _transfer_ownership) { pInfo = info; } CJavaInfo CJavaInfo::createWrapper(::JavaInfo* info) { return CJavaInfo(info, TRANSFER); } void CJavaInfo::attach(::JavaInfo * info) { jfw_freeJavaInfo(pInfo); pInfo = info; } ::JavaInfo * CJavaInfo::detach() { JavaInfo * tmp = pInfo; pInfo = NULL; return tmp; } CJavaInfo::CJavaInfo(const ::JavaInfo* info): pInfo(0) { pInfo = copyJavaInfo(info); } CJavaInfo::~CJavaInfo() { jfw_freeJavaInfo(pInfo); } CJavaInfo::operator ::JavaInfo* () { return pInfo; } JavaInfo * CJavaInfo::copyJavaInfo(const JavaInfo * pInfo) { if (pInfo == NULL) return NULL; JavaInfo* newInfo = (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo)); if (newInfo) { rtl_copyMemory(newInfo, pInfo, sizeof(JavaInfo)); rtl_uString_acquire(pInfo->sVendor); rtl_uString_acquire(pInfo->sLocation); rtl_uString_acquire(pInfo->sVersion); rtl_byte_sequence_acquire(pInfo->arVendorData); } return newInfo; } JavaInfo* CJavaInfo::cloneJavaInfo() const { if (pInfo == NULL) return NULL; return copyJavaInfo(pInfo); } CJavaInfo & CJavaInfo::operator = (const CJavaInfo& info) { if (&info == this) return *this; jfw_freeJavaInfo(pInfo); pInfo = copyJavaInfo(info.pInfo); return *this; } CJavaInfo & CJavaInfo::operator = (const ::JavaInfo* info) { if (info == pInfo) return *this; jfw_freeJavaInfo(pInfo); pInfo = copyJavaInfo(info); return *this; } const ::JavaInfo* CJavaInfo::operator ->() const { return pInfo; } CJavaInfo::operator JavaInfo const * () const { return pInfo; } // ::JavaInfo** CJavaInfo::operator & () // { // return & pInfo; // } rtl::OUString CJavaInfo::getVendor() const { if (pInfo) return rtl::OUString(pInfo->sVendor); else return rtl::OUString(); } rtl::OUString CJavaInfo::getLocation() const { if (pInfo) return rtl::OUString(pInfo->sLocation); else return rtl::OUString(); } rtl::OUString CJavaInfo::getVersion() const { if (pInfo) return rtl::OUString(pInfo->sVersion); else return rtl::OUString(); } sal_uInt64 CJavaInfo::getFeatures() const { if (pInfo) return pInfo->nFeatures; else return 0l; } sal_uInt64 CJavaInfo::getRequirements() const { if (pInfo) return pInfo->nRequirements; else return 0l; } rtl::ByteSequence CJavaInfo::getVendorData() const { if (pInfo) return rtl::ByteSequence(pInfo->arVendorData); else return rtl::ByteSequence(); } }