1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_jvmfwk.hxx" 30*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 31*cdf0e10cSrcweir #include <stdio.h> 32*cdf0e10cSrcweir #endif 33*cdf0e10cSrcweir #include <string.h> 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include "boost/scoped_array.hpp" 36*cdf0e10cSrcweir #include "osl/diagnose.h" 37*cdf0e10cSrcweir #include "rtl/ustring.hxx" 38*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 39*cdf0e10cSrcweir #include "osl/module.hxx" 40*cdf0e10cSrcweir #include "osl/mutex.hxx" 41*cdf0e10cSrcweir #include "osl/thread.hxx" 42*cdf0e10cSrcweir #include "osl/file.hxx" 43*cdf0e10cSrcweir #include "rtl/instance.hxx" 44*cdf0e10cSrcweir #include "osl/getglobalmutex.hxx" 45*cdf0e10cSrcweir #include <setjmp.h> 46*cdf0e10cSrcweir #include <signal.h> 47*cdf0e10cSrcweir #include <stack> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir #include "jni.h" 50*cdf0e10cSrcweir #include "rtl/byteseq.hxx" 51*cdf0e10cSrcweir #include "jvmfwk/vendorplugin.h" 52*cdf0e10cSrcweir #include "util.hxx" 53*cdf0e10cSrcweir #include "sunversion.hxx" 54*cdf0e10cSrcweir #include "vendorlist.hxx" 55*cdf0e10cSrcweir #include "diagnostics.h" 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 58*cdf0e10cSrcweir #define SUN_MICRO "Sun Microsystems Inc." 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir using namespace osl; 61*cdf0e10cSrcweir using namespace rtl; 62*cdf0e10cSrcweir using namespace std; 63*cdf0e10cSrcweir using namespace jfw_plugin; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir namespace { 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir struct PluginMutex: public ::rtl::Static<osl::Mutex, PluginMutex> {}; 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir #if defined UNX 70*cdf0e10cSrcweir OString getPluginJarPath( 71*cdf0e10cSrcweir const OUString & sVendor, 72*cdf0e10cSrcweir const OUString& sLocation, 73*cdf0e10cSrcweir const OUString& sVersion) 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir OString ret; 76*cdf0e10cSrcweir OUString sName1(RTL_CONSTASCII_USTRINGPARAM("javaplugin.jar")); 77*cdf0e10cSrcweir OUString sName2(RTL_CONSTASCII_USTRINGPARAM("plugin.jar")); 78*cdf0e10cSrcweir OUString sPath; 79*cdf0e10cSrcweir if (sVendor.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SUN_MICRO)))) 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir SunVersion ver142("1.4.2-ea"); 82*cdf0e10cSrcweir SunVersion ver150("1.5.0-ea"); 83*cdf0e10cSrcweir SunVersion ver(sVersion); 84*cdf0e10cSrcweir OSL_ASSERT(ver142 && ver150 && ver); 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir OUString sName; 87*cdf0e10cSrcweir if (ver < ver142) 88*cdf0e10cSrcweir { 89*cdf0e10cSrcweir sName = sName1; 90*cdf0e10cSrcweir } 91*cdf0e10cSrcweir else if (ver < ver150) 92*cdf0e10cSrcweir {//this will cause ea, beta etc. to have plugin.jar in path. 93*cdf0e10cSrcweir //but this does not harm. 1.5.0-beta < 1.5.0 94*cdf0e10cSrcweir sName = sName2; 95*cdf0e10cSrcweir } 96*cdf0e10cSrcweir if (sName.getLength()) 97*cdf0e10cSrcweir { 98*cdf0e10cSrcweir sName = sLocation + OUSTR("/lib/") + sName; 99*cdf0e10cSrcweir OSL_VERIFY( 100*cdf0e10cSrcweir osl_getSystemPathFromFileURL(sName.pData, & sPath.pData) 101*cdf0e10cSrcweir == osl_File_E_None); 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir else 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir char sep[] = {SAL_PATHSEPARATOR, 0}; 107*cdf0e10cSrcweir OUString sName(sLocation + OUSTR("/lib/") + sName1); 108*cdf0e10cSrcweir OUString sPath1; 109*cdf0e10cSrcweir OUString sPath2; 110*cdf0e10cSrcweir if (osl_getSystemPathFromFileURL(sName.pData, & sPath1.pData) 111*cdf0e10cSrcweir == osl_File_E_None) 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir sName = sLocation + OUSTR("/lib/") + sName2; 114*cdf0e10cSrcweir if (osl_getSystemPathFromFileURL(sName.pData, & sPath2.pData) 115*cdf0e10cSrcweir == osl_File_E_None) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir sPath = sPath1 + OUString::createFromAscii(sep) + sPath2; 118*cdf0e10cSrcweir } 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir OSL_ASSERT(sPath.getLength()); 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir ret = rtl::OUStringToOString(sPath, osl_getThreadTextEncoding()); 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir return ret; 125*cdf0e10cSrcweir } 126*cdf0e10cSrcweir #endif // UNX 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir JavaInfo* createJavaInfo(const rtl::Reference<VendorBase> & info) 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir JavaInfo* pInfo = (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo)); 132*cdf0e10cSrcweir if (pInfo == NULL) 133*cdf0e10cSrcweir return NULL; 134*cdf0e10cSrcweir rtl::OUString sVendor = info->getVendor(); 135*cdf0e10cSrcweir pInfo->sVendor = sVendor.pData; 136*cdf0e10cSrcweir rtl_uString_acquire(sVendor.pData); 137*cdf0e10cSrcweir rtl::OUString sHome = info->getHome(); 138*cdf0e10cSrcweir pInfo->sLocation = sHome.pData; 139*cdf0e10cSrcweir rtl_uString_acquire(pInfo->sLocation); 140*cdf0e10cSrcweir rtl::OUString sVersion = info->getVersion(); 141*cdf0e10cSrcweir pInfo->sVersion = sVersion.pData; 142*cdf0e10cSrcweir rtl_uString_acquire(pInfo->sVersion); 143*cdf0e10cSrcweir pInfo->nFeatures = info->supportsAccessibility() ? 1 : 0; 144*cdf0e10cSrcweir pInfo->nRequirements = info->needsRestart() ? JFW_REQUIRE_NEEDRESTART : 0; 145*cdf0e10cSrcweir rtl::OUStringBuffer buf(1024); 146*cdf0e10cSrcweir buf.append(info->getRuntimeLibrary()); 147*cdf0e10cSrcweir if (info->getLibraryPaths().getLength() > 0) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir buf.appendAscii("\n"); 150*cdf0e10cSrcweir buf.append(info->getLibraryPaths()); 151*cdf0e10cSrcweir buf.appendAscii("\n"); 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir rtl::OUString sVendorData = buf.makeStringAndClear(); 155*cdf0e10cSrcweir rtl::ByteSequence byteSeq( (sal_Int8*) sVendorData.pData->buffer, 156*cdf0e10cSrcweir sVendorData.getLength() * sizeof(sal_Unicode)); 157*cdf0e10cSrcweir pInfo->arVendorData = byteSeq.get(); 158*cdf0e10cSrcweir rtl_byte_sequence_acquire(pInfo->arVendorData); 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir return pInfo; 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir rtl::OUString getRuntimeLib(const rtl::ByteSequence & data) 164*cdf0e10cSrcweir { 165*cdf0e10cSrcweir const sal_Unicode* chars = (sal_Unicode*) data.getConstArray(); 166*cdf0e10cSrcweir sal_Int32 len = data.getLength(); 167*cdf0e10cSrcweir rtl::OUString sData(chars, len / 2); 168*cdf0e10cSrcweir //the runtime lib is on the first line 169*cdf0e10cSrcweir sal_Int32 index = 0; 170*cdf0e10cSrcweir rtl::OUString aToken = sData.getToken( 0, '\n', index); 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir return aToken; 173*cdf0e10cSrcweir } 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir jmp_buf jmp_jvm_abort; 176*cdf0e10cSrcweir sig_atomic_t g_bInGetJavaVM = 0; 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir extern "C" void JNICALL abort_handler() 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir // If we are within JNI_CreateJavaVM then we jump back into getJavaVM 181*cdf0e10cSrcweir if( g_bInGetJavaVM != 0 ) 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir fprintf( stderr, "JavaVM: JNI_CreateJavaVM called _exit, caught by abort_handler in javavm.cxx\n"); 184*cdf0e10cSrcweir longjmp( jmp_jvm_abort, 0); 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir extern "C" 191*cdf0e10cSrcweir javaPluginError jfw_plugin_getAllJavaInfos( 192*cdf0e10cSrcweir rtl_uString *sVendor, 193*cdf0e10cSrcweir rtl_uString *sMinVersion, 194*cdf0e10cSrcweir rtl_uString *sMaxVersion, 195*cdf0e10cSrcweir rtl_uString * *arExcludeList, 196*cdf0e10cSrcweir sal_Int32 nLenList, 197*cdf0e10cSrcweir JavaInfo*** parJavaInfo, 198*cdf0e10cSrcweir sal_Int32 *nLenInfoList) 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir OSL_ASSERT(sVendor); 201*cdf0e10cSrcweir OSL_ASSERT(sMinVersion); 202*cdf0e10cSrcweir OSL_ASSERT(sMaxVersion); 203*cdf0e10cSrcweir OSL_ASSERT(parJavaInfo); 204*cdf0e10cSrcweir OSL_ASSERT(parJavaInfo); 205*cdf0e10cSrcweir OSL_ASSERT(nLenInfoList); 206*cdf0e10cSrcweir if (!sVendor || !sMinVersion || !sMaxVersion || !parJavaInfo || !nLenInfoList) 207*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir //nLenlist contains the number of element in arExcludeList. 210*cdf0e10cSrcweir //If no exclude list is provided then nLenList must be 0 211*cdf0e10cSrcweir OSL_ASSERT( ! (arExcludeList == NULL && nLenList > 0)); 212*cdf0e10cSrcweir if (arExcludeList == NULL && nLenList > 0) 213*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir OUString ouVendor(sVendor); 216*cdf0e10cSrcweir OUString ouMinVer(sMinVersion); 217*cdf0e10cSrcweir OUString ouMaxVer(sMaxVersion); 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir OSL_ASSERT(ouVendor.getLength() > 0); 220*cdf0e10cSrcweir if (ouVendor.getLength() == 0) 221*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir JavaInfo** arInfo = NULL; 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir //Find all JREs 226*cdf0e10cSrcweir vector<rtl::Reference<VendorBase> > vecInfos = 227*cdf0e10cSrcweir getAllJREInfos(); 228*cdf0e10cSrcweir vector<rtl::Reference<VendorBase> > vecVerifiedInfos; 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir typedef vector<rtl::Reference<VendorBase> >::iterator it; 231*cdf0e10cSrcweir for (it i= vecInfos.begin(); i != vecInfos.end(); i++) 232*cdf0e10cSrcweir { 233*cdf0e10cSrcweir const rtl::Reference<VendorBase>& cur = *i; 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir if (ouVendor.equals(cur->getVendor()) == sal_False) 236*cdf0e10cSrcweir continue; 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir if (ouMinVer.getLength() > 0) 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir try 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir if (cur->compareVersions(sMinVersion) == -1) 243*cdf0e10cSrcweir continue; 244*cdf0e10cSrcweir } 245*cdf0e10cSrcweir catch (MalformedVersionException&) 246*cdf0e10cSrcweir { 247*cdf0e10cSrcweir //The minVersion was not recognized as valid for this vendor. 248*cdf0e10cSrcweir JFW_ENSURE( 249*cdf0e10cSrcweir 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") 250*cdf0e10cSrcweir + ouMinVer + OUSTR(" for vendor: ") + cur->getVendor() 251*cdf0e10cSrcweir + OUSTR(" .Check minimum Version.") ); 252*cdf0e10cSrcweir return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir if (ouMaxVer.getLength() > 0) 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir try 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir if (cur->compareVersions(sMaxVersion) == 1) 261*cdf0e10cSrcweir continue; 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir catch (MalformedVersionException&) 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir //The maxVersion was not recognized as valid for this vendor. 266*cdf0e10cSrcweir JFW_ENSURE( 267*cdf0e10cSrcweir 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") 268*cdf0e10cSrcweir + ouMaxVer + OUSTR(" for vendor: ") + cur->getVendor() 269*cdf0e10cSrcweir + OUSTR(" .Check maximum Version.") ); 270*cdf0e10cSrcweir return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir if (arExcludeList > 0) 275*cdf0e10cSrcweir { 276*cdf0e10cSrcweir bool bExclude = false; 277*cdf0e10cSrcweir for (int j = 0; j < nLenList; j++) 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir rtl::OUString sExVer(arExcludeList[j]); 280*cdf0e10cSrcweir try 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir if (cur->compareVersions(sExVer) == 0) 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir bExclude = true; 285*cdf0e10cSrcweir break; 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir catch (MalformedVersionException&) 289*cdf0e10cSrcweir { 290*cdf0e10cSrcweir //The excluded version was not recognized as valid for this vendor. 291*cdf0e10cSrcweir JFW_ENSURE( 292*cdf0e10cSrcweir 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") 293*cdf0e10cSrcweir + sExVer + OUSTR(" for vendor: ") + cur->getVendor() 294*cdf0e10cSrcweir + OUSTR(" .Check excluded versions.") ); 295*cdf0e10cSrcweir return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir } 298*cdf0e10cSrcweir if (bExclude == true) 299*cdf0e10cSrcweir continue; 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir vecVerifiedInfos.push_back(*i); 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir //Now vecVerifiedInfos contains all those JREs which meet the version requirements 304*cdf0e10cSrcweir //Transfer them into the array that is passed out. 305*cdf0e10cSrcweir arInfo = (JavaInfo**) rtl_allocateMemory(vecVerifiedInfos.size() * sizeof (JavaInfo*)); 306*cdf0e10cSrcweir int j = 0; 307*cdf0e10cSrcweir typedef vector<rtl::Reference<VendorBase> >::const_iterator cit; 308*cdf0e10cSrcweir for (cit ii = vecVerifiedInfos.begin(); ii != vecVerifiedInfos.end(); ii++, j++) 309*cdf0e10cSrcweir { 310*cdf0e10cSrcweir arInfo[j] = createJavaInfo(*ii); 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir *nLenInfoList = vecVerifiedInfos.size(); 313*cdf0e10cSrcweir 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir *parJavaInfo = arInfo; 316*cdf0e10cSrcweir return JFW_PLUGIN_E_NONE; 317*cdf0e10cSrcweir } 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir extern "C" 320*cdf0e10cSrcweir javaPluginError jfw_plugin_getJavaInfoByPath( 321*cdf0e10cSrcweir rtl_uString *path, 322*cdf0e10cSrcweir rtl_uString *sVendor, 323*cdf0e10cSrcweir rtl_uString *sMinVersion, 324*cdf0e10cSrcweir rtl_uString *sMaxVersion, 325*cdf0e10cSrcweir rtl_uString * *arExcludeList, 326*cdf0e10cSrcweir sal_Int32 nLenList, 327*cdf0e10cSrcweir JavaInfo ** ppInfo) 328*cdf0e10cSrcweir { 329*cdf0e10cSrcweir javaPluginError errcode = JFW_PLUGIN_E_NONE; 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir OSL_ASSERT(path); 332*cdf0e10cSrcweir OSL_ASSERT(sVendor); 333*cdf0e10cSrcweir OSL_ASSERT(sMinVersion); 334*cdf0e10cSrcweir OSL_ASSERT(sMaxVersion); 335*cdf0e10cSrcweir if (!path || !sVendor || !sMinVersion || !sMaxVersion || !ppInfo) 336*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 337*cdf0e10cSrcweir OUString ouPath(path); 338*cdf0e10cSrcweir OSL_ASSERT(ouPath.getLength() > 0); 339*cdf0e10cSrcweir if (ouPath.getLength() == 0) 340*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir //nLenlist contains the number of element in arExcludeList. 343*cdf0e10cSrcweir //If no exclude list is provided then nLenList must be 0 344*cdf0e10cSrcweir OSL_ASSERT( ! (arExcludeList == NULL && nLenList > 0)); 345*cdf0e10cSrcweir if (arExcludeList == NULL && nLenList > 0) 346*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir OUString ouVendor(sVendor); 349*cdf0e10cSrcweir OUString ouMinVer(sMinVersion); 350*cdf0e10cSrcweir OUString ouMaxVer(sMaxVersion); 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir OSL_ASSERT(ouVendor.getLength() > 0); 353*cdf0e10cSrcweir if (ouVendor.getLength() == 0) 354*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir rtl::Reference<VendorBase> aVendorInfo = getJREInfoByPath(ouPath); 357*cdf0e10cSrcweir if (aVendorInfo.is() == sal_False) 358*cdf0e10cSrcweir return JFW_PLUGIN_E_NO_JRE; 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir //Check if the detected JRE matches the version requirements 361*cdf0e10cSrcweir if (ouVendor.equals(aVendorInfo->getVendor()) == sal_False) 362*cdf0e10cSrcweir return JFW_PLUGIN_E_NO_JRE; 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir if (ouMinVer.getLength() > 0) 365*cdf0e10cSrcweir { 366*cdf0e10cSrcweir int nRes = 0; 367*cdf0e10cSrcweir try 368*cdf0e10cSrcweir { 369*cdf0e10cSrcweir nRes = aVendorInfo->compareVersions(ouMinVer); 370*cdf0e10cSrcweir } 371*cdf0e10cSrcweir catch (MalformedVersionException&) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir //The minVersion was not recognized as valid for this vendor. 374*cdf0e10cSrcweir JFW_ENSURE( 375*cdf0e10cSrcweir 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") 376*cdf0e10cSrcweir + ouMinVer + OUSTR(" for vendor: ") + aVendorInfo->getVendor() 377*cdf0e10cSrcweir + OUSTR(" .Check minimum Version.") ); 378*cdf0e10cSrcweir return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir if (nRes < 0) 381*cdf0e10cSrcweir return JFW_PLUGIN_E_FAILED_VERSION; 382*cdf0e10cSrcweir } 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir if (ouMaxVer.getLength() > 0) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir int nRes = 0; 387*cdf0e10cSrcweir try 388*cdf0e10cSrcweir { 389*cdf0e10cSrcweir nRes = aVendorInfo->compareVersions(ouMaxVer); 390*cdf0e10cSrcweir } 391*cdf0e10cSrcweir catch (MalformedVersionException&) 392*cdf0e10cSrcweir { 393*cdf0e10cSrcweir //The maxVersion was not recognized as valid for this vendor. 394*cdf0e10cSrcweir JFW_ENSURE( 395*cdf0e10cSrcweir 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") 396*cdf0e10cSrcweir + ouMaxVer + OUSTR(" for vendor: ") + aVendorInfo->getVendor() 397*cdf0e10cSrcweir + OUSTR(" .Check maximum Version.") ); 398*cdf0e10cSrcweir return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir if (nRes > 0) 401*cdf0e10cSrcweir return JFW_PLUGIN_E_FAILED_VERSION; 402*cdf0e10cSrcweir } 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir if (arExcludeList > 0) 405*cdf0e10cSrcweir { 406*cdf0e10cSrcweir for (int i = 0; i < nLenList; i++) 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir rtl::OUString sExVer(arExcludeList[i]); 409*cdf0e10cSrcweir int nRes = 0; 410*cdf0e10cSrcweir try 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir nRes = aVendorInfo->compareVersions(sExVer); 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir catch (MalformedVersionException&) 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir //The excluded version was not recognized as valid for this vendor. 417*cdf0e10cSrcweir JFW_ENSURE( 418*cdf0e10cSrcweir 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") 419*cdf0e10cSrcweir + sExVer + OUSTR(" for vendor: ") + aVendorInfo->getVendor() 420*cdf0e10cSrcweir + OUSTR(" .Check excluded versions.") ); 421*cdf0e10cSrcweir return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir if (nRes == 0) 424*cdf0e10cSrcweir return JFW_PLUGIN_E_FAILED_VERSION; 425*cdf0e10cSrcweir } 426*cdf0e10cSrcweir } 427*cdf0e10cSrcweir *ppInfo = createJavaInfo(aVendorInfo); 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir return errcode; 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir /** starts a Java Virtual Machine. 433*cdf0e10cSrcweir <p> 434*cdf0e10cSrcweir The function shall ensure, that the VM does not abort the process 435*cdf0e10cSrcweir during instantiation. 436*cdf0e10cSrcweir </p> 437*cdf0e10cSrcweir */ 438*cdf0e10cSrcweir extern "C" 439*cdf0e10cSrcweir javaPluginError jfw_plugin_startJavaVirtualMachine( 440*cdf0e10cSrcweir const JavaInfo *pInfo, 441*cdf0e10cSrcweir const JavaVMOption* arOptions, 442*cdf0e10cSrcweir sal_Int32 cOptions, 443*cdf0e10cSrcweir JavaVM ** ppVm, 444*cdf0e10cSrcweir JNIEnv ** ppEnv) 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir // unless guard is volatile the following warning occurs on gcc: 447*cdf0e10cSrcweir // warning: variable 't' might be clobbered by `longjmp' or `vfork' 448*cdf0e10cSrcweir volatile osl::MutexGuard guard(PluginMutex::get()); 449*cdf0e10cSrcweir // unless errcode is volatile the following warning occurs on gcc: 450*cdf0e10cSrcweir // warning: variable 'errcode' might be clobbered by `longjmp' or `vfork' 451*cdf0e10cSrcweir volatile javaPluginError errcode = JFW_PLUGIN_E_NONE; 452*cdf0e10cSrcweir if ( pInfo == NULL || ppVm == NULL || ppEnv == NULL) 453*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 454*cdf0e10cSrcweir //Check if the Vendor (pInfo->sVendor) is supported by this plugin 455*cdf0e10cSrcweir if ( ! isVendorSupported(pInfo->sVendor)) 456*cdf0e10cSrcweir return JFW_PLUGIN_E_WRONG_VENDOR; 457*cdf0e10cSrcweir rtl::OUString sRuntimeLib = getRuntimeLib(pInfo->arVendorData); 458*cdf0e10cSrcweir JFW_TRACE2(OUSTR("[Java framework] Using Java runtime library: ") 459*cdf0e10cSrcweir + sRuntimeLib + OUSTR(".\n")); 460*cdf0e10cSrcweir // On linux we load jvm with RTLD_GLOBAL. This is necessary for debugging, because 461*cdf0e10cSrcweir // libjdwp.so need a symbol (fork1) from libjvm which it only gets if the jvm is loaded 462*cdf0e10cSrcweir // witd RTLD_GLOBAL. On Solaris libjdwp.so is correctly linked with libjvm.so 463*cdf0e10cSrcweir oslModule moduleRt = 0; 464*cdf0e10cSrcweir #if defined(LINUX) 465*cdf0e10cSrcweir if ((moduleRt = osl_loadModule(sRuntimeLib.pData, 466*cdf0e10cSrcweir SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_NOW)) == 0 ) 467*cdf0e10cSrcweir #else 468*cdf0e10cSrcweir if ((moduleRt = osl_loadModule(sRuntimeLib.pData, SAL_LOADMODULE_DEFAULT)) == 0) 469*cdf0e10cSrcweir #endif 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir JFW_ENSURE(0, OUSTR("[Java framework]sunjavaplugin" SAL_DLLEXTENSION 472*cdf0e10cSrcweir " could not load Java runtime library: \n") 473*cdf0e10cSrcweir + sRuntimeLib + OUSTR("\n")); 474*cdf0e10cSrcweir JFW_TRACE0(OUSTR("[Java framework]sunjavaplugin" SAL_DLLEXTENSION 475*cdf0e10cSrcweir " could not load Java runtime library: \n") 476*cdf0e10cSrcweir + sRuntimeLib + OUSTR("\n")); 477*cdf0e10cSrcweir return JFW_PLUGIN_E_VM_CREATION_FAILED; 478*cdf0e10cSrcweir } 479*cdf0e10cSrcweir 480*cdf0e10cSrcweir #ifdef UNX 481*cdf0e10cSrcweir //Setting the JAVA_HOME is needed for awt 482*cdf0e10cSrcweir rtl::OUString javaHome(RTL_CONSTASCII_USTRINGPARAM("JAVA_HOME=")); 483*cdf0e10cSrcweir rtl::OUString sPathLocation; 484*cdf0e10cSrcweir osl_getSystemPathFromFileURL(pInfo->sLocation, & sPathLocation.pData); 485*cdf0e10cSrcweir javaHome += sPathLocation; 486*cdf0e10cSrcweir rtl::OString osJavaHome = rtl::OUStringToOString( 487*cdf0e10cSrcweir javaHome, osl_getThreadTextEncoding()); 488*cdf0e10cSrcweir putenv(strdup(osJavaHome.getStr())); 489*cdf0e10cSrcweir #endif 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir typedef jint JNICALL JNI_InitArgs_Type(void *); 492*cdf0e10cSrcweir typedef jint JNICALL JNI_CreateVM_Type(JavaVM **, JNIEnv **, void *); 493*cdf0e10cSrcweir rtl::OUString sSymbolCreateJava( 494*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("JNI_CreateJavaVM")); 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir JNI_CreateVM_Type * pCreateJavaVM = (JNI_CreateVM_Type *) osl_getFunctionSymbol( 497*cdf0e10cSrcweir moduleRt, sSymbolCreateJava.pData); 498*cdf0e10cSrcweir if (!pCreateJavaVM) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir OSL_ASSERT(0); 501*cdf0e10cSrcweir rtl::OString sLib = rtl::OUStringToOString( 502*cdf0e10cSrcweir sRuntimeLib, osl_getThreadTextEncoding()); 503*cdf0e10cSrcweir rtl::OString sSymbol = rtl::OUStringToOString( 504*cdf0e10cSrcweir sSymbolCreateJava, osl_getThreadTextEncoding()); 505*cdf0e10cSrcweir fprintf(stderr,"[Java framework]sunjavaplugin"SAL_DLLEXTENSION 506*cdf0e10cSrcweir "Java runtime library: %s does not export symbol %s !\n", 507*cdf0e10cSrcweir sLib.getStr(), sSymbol.getStr()); 508*cdf0e10cSrcweir return JFW_PLUGIN_E_VM_CREATION_FAILED; 509*cdf0e10cSrcweir } 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir // Some testing with Java 1.4 showed that JavaVMOption.optionString has to 512*cdf0e10cSrcweir // be encoded with the system encoding (i.e., osl_getThreadTextEncoding): 513*cdf0e10cSrcweir JavaVMInitArgs vm_args; 514*cdf0e10cSrcweir 515*cdf0e10cSrcweir boost::scoped_array<JavaVMOption> sarOptions( 516*cdf0e10cSrcweir new JavaVMOption[cOptions + 1]); 517*cdf0e10cSrcweir JavaVMOption * options = sarOptions.get(); 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir // We set an abort handler which is called when the VM calls _exit during 520*cdf0e10cSrcweir // JNI_CreateJavaVM. This happens when the LD_LIBRARY_PATH does not contain 521*cdf0e10cSrcweir // all some directories of the Java installation. This is necessary for 522*cdf0e10cSrcweir // all versions below 1.5.1 523*cdf0e10cSrcweir options[0].optionString= (char *) "abort"; 524*cdf0e10cSrcweir options[0].extraInfo= (void* )(sal_IntPtr)abort_handler; 525*cdf0e10cSrcweir rtl::OString sClassPathProp("-Djava.class.path="); 526*cdf0e10cSrcweir rtl::OString sClassPathOption; 527*cdf0e10cSrcweir for (int i = 0; i < cOptions; i++) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir #ifdef UNX 530*cdf0e10cSrcweir // Until java 1.5 we need to put a plugin.jar or javaplugin.jar (<1.4.2) 531*cdf0e10cSrcweir // in the class path in order to have applet support. 532*cdf0e10cSrcweir rtl::OString sClassPath = arOptions[i].optionString; 533*cdf0e10cSrcweir if (sClassPath.match(sClassPathProp, 0) == sal_True) 534*cdf0e10cSrcweir { 535*cdf0e10cSrcweir char sep[] = {SAL_PATHSEPARATOR, 0}; 536*cdf0e10cSrcweir OString sAddPath = getPluginJarPath(pInfo->sVendor, pInfo->sLocation,pInfo->sVersion); 537*cdf0e10cSrcweir if (sAddPath.getLength()) 538*cdf0e10cSrcweir sClassPathOption = sClassPath + rtl::OString(sep) + sAddPath; 539*cdf0e10cSrcweir else 540*cdf0e10cSrcweir sClassPathOption = sClassPath; 541*cdf0e10cSrcweir options[i+1].optionString = (char *) sClassPathOption.getStr(); 542*cdf0e10cSrcweir options[i+1].extraInfo = arOptions[i].extraInfo; 543*cdf0e10cSrcweir } 544*cdf0e10cSrcweir else 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir #endif 547*cdf0e10cSrcweir options[i+1].optionString = arOptions[i].optionString; 548*cdf0e10cSrcweir options[i+1].extraInfo = arOptions[i].extraInfo; 549*cdf0e10cSrcweir #ifdef UNX 550*cdf0e10cSrcweir } 551*cdf0e10cSrcweir #endif 552*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 553*cdf0e10cSrcweir JFW_TRACE2(OString("VM option: ") + OString(options[i+1].optionString) + 554*cdf0e10cSrcweir OString("\n")); 555*cdf0e10cSrcweir #endif 556*cdf0e10cSrcweir } 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir #ifdef MACOSX 559*cdf0e10cSrcweir vm_args.version= JNI_VERSION_1_4; // issue 88987 560*cdf0e10cSrcweir #else 561*cdf0e10cSrcweir vm_args.version= JNI_VERSION_1_2; 562*cdf0e10cSrcweir #endif 563*cdf0e10cSrcweir vm_args.options= options; 564*cdf0e10cSrcweir vm_args.nOptions= cOptions + 1; 565*cdf0e10cSrcweir vm_args.ignoreUnrecognized= JNI_TRUE; 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir /* We set a global flag which is used by the abort handler in order to 568*cdf0e10cSrcweir determine whether it is should use longjmp to get back into this function. 569*cdf0e10cSrcweir That is, the abort handler determines if it is on the same stack as this function 570*cdf0e10cSrcweir and then jumps back into this function. 571*cdf0e10cSrcweir */ 572*cdf0e10cSrcweir g_bInGetJavaVM = 1; 573*cdf0e10cSrcweir jint err; 574*cdf0e10cSrcweir JavaVM * pJavaVM = 0; 575*cdf0e10cSrcweir memset( jmp_jvm_abort, 0, sizeof(jmp_jvm_abort)); 576*cdf0e10cSrcweir int jmpval= setjmp( jmp_jvm_abort ); 577*cdf0e10cSrcweir /* If jmpval is not "0" then this point was reached by a longjmp in the 578*cdf0e10cSrcweir abort_handler, which was called indirectly by JNI_CreateVM. 579*cdf0e10cSrcweir */ 580*cdf0e10cSrcweir if( jmpval == 0) 581*cdf0e10cSrcweir { 582*cdf0e10cSrcweir //returns negative number on failure 583*cdf0e10cSrcweir err= pCreateJavaVM(&pJavaVM, ppEnv, &vm_args); 584*cdf0e10cSrcweir g_bInGetJavaVM = 0; 585*cdf0e10cSrcweir } 586*cdf0e10cSrcweir else 587*cdf0e10cSrcweir // set err to a positive number, so as or recognize that an abort (longjmp) 588*cdf0e10cSrcweir //occurred 589*cdf0e10cSrcweir err= 1; 590*cdf0e10cSrcweir 591*cdf0e10cSrcweir if(err != 0) 592*cdf0e10cSrcweir { 593*cdf0e10cSrcweir rtl::OUString message; 594*cdf0e10cSrcweir if( err < 0) 595*cdf0e10cSrcweir { 596*cdf0e10cSrcweir fprintf(stderr,"[Java framework] sunjavaplugin"SAL_DLLEXTENSION 597*cdf0e10cSrcweir "Can not create Java Virtual Machine\n"); 598*cdf0e10cSrcweir errcode = JFW_PLUGIN_E_VM_CREATION_FAILED; 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir else if( err > 0) 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir fprintf(stderr,"[Java framework] sunjavaplugin"SAL_DLLEXTENSION 603*cdf0e10cSrcweir "Can not create JavaVirtualMachine, abort handler was called.\n"); 604*cdf0e10cSrcweir errcode = JFW_PLUGIN_E_VM_CREATION_FAILED; 605*cdf0e10cSrcweir } 606*cdf0e10cSrcweir } 607*cdf0e10cSrcweir else 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir *ppVm = pJavaVM; 610*cdf0e10cSrcweir JFW_TRACE2("[Java framework] sunjavaplugin"SAL_DLLEXTENSION " has created a VM.\n"); 611*cdf0e10cSrcweir } 612*cdf0e10cSrcweir 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir return errcode; 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir 617*cdf0e10cSrcweir extern "C" 618*cdf0e10cSrcweir javaPluginError jfw_plugin_existJRE(const JavaInfo *pInfo, sal_Bool *exist) 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir javaPluginError ret = JFW_PLUGIN_E_NONE; 621*cdf0e10cSrcweir if (!pInfo || !exist) 622*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 623*cdf0e10cSrcweir ::rtl::OUString sLocation(pInfo->sLocation); 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir if (sLocation.getLength() == 0) 626*cdf0e10cSrcweir return JFW_PLUGIN_E_INVALID_ARG; 627*cdf0e10cSrcweir ::osl::DirectoryItem item; 628*cdf0e10cSrcweir ::osl::File::RC rc_item = ::osl::DirectoryItem::get(sLocation, item); 629*cdf0e10cSrcweir if (::osl::File::E_None == rc_item) 630*cdf0e10cSrcweir { 631*cdf0e10cSrcweir *exist = sal_True; 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir else if (::osl::File::E_NOENT == rc_item) 634*cdf0e10cSrcweir { 635*cdf0e10cSrcweir *exist = sal_False; 636*cdf0e10cSrcweir } 637*cdf0e10cSrcweir else 638*cdf0e10cSrcweir { 639*cdf0e10cSrcweir ret = JFW_PLUGIN_E_ERROR; 640*cdf0e10cSrcweir } 641*cdf0e10cSrcweir #ifdef MACOSX 642*cdf0e10cSrcweir //We can have the situation that the JavaVM runtime library is not 643*cdf0e10cSrcweir //contained within JAVA_HOME. Then the check for JAVA_HOME would return 644*cdf0e10cSrcweir //true although the runtime library may not be loadable. 645*cdf0e10cSrcweir if (ret == JFW_PLUGIN_E_NONE && *exist == sal_True) 646*cdf0e10cSrcweir { 647*cdf0e10cSrcweir rtl::OUString sRuntimeLib = getRuntimeLib(pInfo->arVendorData); 648*cdf0e10cSrcweir JFW_TRACE2(OUSTR("[Java framework] Checking existence of Java runtime library.\n")); 649*cdf0e10cSrcweir 650*cdf0e10cSrcweir ::osl::DirectoryItem itemRt; 651*cdf0e10cSrcweir ::osl::File::RC rc_itemRt = ::osl::DirectoryItem::get(sRuntimeLib, itemRt); 652*cdf0e10cSrcweir if (::osl::File::E_None == rc_itemRt) 653*cdf0e10cSrcweir { 654*cdf0e10cSrcweir *exist = sal_True; 655*cdf0e10cSrcweir JFW_TRACE2(OUSTR("[Java framework] Java runtime library exist: ") 656*cdf0e10cSrcweir + sRuntimeLib + OUSTR("\n")); 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir } 659*cdf0e10cSrcweir else if (::osl::File::E_NOENT == rc_itemRt) 660*cdf0e10cSrcweir { 661*cdf0e10cSrcweir *exist = sal_False; 662*cdf0e10cSrcweir JFW_TRACE2(OUSTR("[Java framework] Java runtime library does not exist: ") 663*cdf0e10cSrcweir + sRuntimeLib + OUSTR("\n")); 664*cdf0e10cSrcweir } 665*cdf0e10cSrcweir else 666*cdf0e10cSrcweir { 667*cdf0e10cSrcweir ret = JFW_PLUGIN_E_ERROR; 668*cdf0e10cSrcweir JFW_TRACE2(OUSTR("[Java framework] Error while looking for Java runtime library: ") 669*cdf0e10cSrcweir + sRuntimeLib + OUSTR(" \n")); 670*cdf0e10cSrcweir } 671*cdf0e10cSrcweir } 672*cdf0e10cSrcweir #endif 673*cdf0e10cSrcweir return ret; 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir 677