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