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_bridges.hxx" 30 31 #include <sal/alloca.h> 32 33 #include "jni_bridge.h" 34 //#include "jni_finalizer.h" 35 36 #include <rtl/ustrbuf.hxx> 37 38 #include <algorithm> 39 40 41 using namespace ::rtl; 42 43 namespace jni_uno 44 { 45 46 //______________________________________________________________________________ 47 jobject Bridge::map_to_java( 48 JNI_context const & jni, 49 uno_Interface * pUnoI, JNI_interface_type_info const * info ) const 50 { 51 // get oid 52 rtl_uString * pOid = 0; 53 (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI ); 54 OSL_ASSERT( 0 != pOid ); 55 OUString oid( pOid, SAL_NO_ACQUIRE ); 56 57 // opt getRegisteredInterface() 58 JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) ); 59 jvalue args[ 2 ]; 60 args[ 0 ].l = jo_oid.get(); 61 args[ 1 ].l = info->m_type; 62 jobject jo_iface = jni->CallObjectMethodA( 63 m_jni_info->m_object_java_env, 64 m_jni_info->m_method_IEnvironment_getRegisteredInterface, args ); 65 jni.ensure_no_exception(); 66 67 if (0 == jo_iface) // no registered iface 68 { 69 // register uno interface 70 (*m_uno_env->registerInterface)( 71 m_uno_env, reinterpret_cast< void ** >( &pUnoI ), 72 oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() ); 73 74 // create java and register java proxy 75 jvalue args2[ 7 ]; 76 acquire(); 77 args2[ 0 ].j = reinterpret_cast< sal_Int64 >( this ); 78 (*pUnoI->acquire)( pUnoI ); 79 args2[ 1 ].l = m_jni_info->m_object_java_env; 80 args2[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI ); 81 typelib_typedescription_acquire( info->m_td.get() ); 82 args2[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() ); 83 args2[ 4 ].l = info->m_type; 84 args2[ 5 ].l = jo_oid.get(); 85 args2[ 6 ].l = info->m_proxy_ctor; 86 jo_iface = jni->CallStaticObjectMethodA( 87 m_jni_info->m_class_JNI_proxy, 88 m_jni_info->m_method_JNI_proxy_create, args2 ); 89 jni.ensure_no_exception(); 90 } 91 92 OSL_ASSERT( 0 != jo_iface ); 93 return jo_iface; 94 } 95 96 97 //______________________________________________________________________________ 98 void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const 99 { 100 if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass) 101 { 102 #if OSL_DEBUG_LEVEL > 0 103 // append java stack trace to Message member 104 reinterpret_cast< ::com::sun::star::uno::Exception * >( 105 uno_exc->pData )->Message += jni.get_stack_trace(); 106 #endif 107 108 #if OSL_DEBUG_LEVEL > 1 109 { 110 OUStringBuffer buf( 128 ); 111 buf.appendAscii( 112 RTL_CONSTASCII_STRINGPARAM("exception occured java->uno: [") ); 113 buf.append( OUString::unacquired( &uno_exc->pType->pTypeName ) ); 114 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); 115 buf.append( 116 reinterpret_cast< ::com::sun::star::uno::Exception const * >( 117 uno_exc->pData )->Message ); 118 OString cstr_msg( 119 OUStringToOString( 120 buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); 121 OSL_TRACE( cstr_msg.getStr() ); 122 } 123 #endif 124 // signal exception 125 jvalue java_exc; 126 try 127 { 128 map_to_java( 129 jni, &java_exc, uno_exc->pData, uno_exc->pType, 0, 130 true /* in */, false /* no out */ ); 131 } 132 catch (...) 133 { 134 uno_any_destruct( uno_exc, 0 ); 135 throw; 136 } 137 uno_any_destruct( uno_exc, 0 ); 138 139 JLocalAutoRef jo_exc( jni, java_exc.l ); 140 jint res = jni->Throw( (jthrowable) jo_exc.get() ); 141 if (0 != res) 142 { 143 // call toString() 144 JLocalAutoRef jo_descr( 145 jni, jni->CallObjectMethodA( 146 jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) ); 147 jni.ensure_no_exception(); 148 OUStringBuffer buf( 128 ); 149 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( 150 "throwing java exception failed: ") ); 151 buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) ); 152 buf.append( jni.get_stack_trace() ); 153 throw BridgeRuntimeError( buf.makeStringAndClear() ); 154 } 155 } 156 else 157 { 158 OUString message( 159 OUSTR("thrown exception is no uno exception: ") + 160 OUString::unacquired( &uno_exc->pType->pTypeName ) + 161 jni.get_stack_trace() ); 162 uno_any_destruct( uno_exc, 0 ); 163 throw BridgeRuntimeError( message ); 164 } 165 } 166 167 union largest 168 { 169 sal_Int64 n; 170 double d; 171 void * p; 172 uno_Any a; 173 }; 174 175 //______________________________________________________________________________ 176 jobject Bridge::call_uno( 177 JNI_context const & jni, 178 uno_Interface * pUnoI, typelib_TypeDescription * member_td, 179 typelib_TypeDescriptionReference * return_type, 180 sal_Int32 nParams, typelib_MethodParameter const * pParams, 181 jobjectArray jo_args /* may be 0 */ ) const 182 { 183 // return mem 184 sal_Int32 return_size; 185 switch (return_type->eTypeClass) { 186 case typelib_TypeClass_VOID: 187 return_size = 0; 188 break; 189 190 case typelib_TypeClass_STRUCT: 191 case typelib_TypeClass_EXCEPTION: 192 return_size = std::max( 193 TypeDescr(return_type).get()->nSize, 194 static_cast< sal_Int32 >(sizeof (largest))); 195 break; 196 197 default: 198 return_size = sizeof (largest); 199 break; 200 } 201 202 #ifdef BROKEN_ALLOCA 203 char * mem = (char *) malloc( 204 #else 205 char * mem = (char *) alloca( 206 #endif 207 (nParams * sizeof (void *)) + 208 return_size + (nParams * sizeof (largest)) ); 209 void ** uno_args = (void **) mem; 210 void * uno_ret = return_size == 0 ? 0 : (mem + (nParams * sizeof (void *))); 211 largest * uno_args_mem = (largest *) 212 (mem + (nParams * sizeof (void *)) + return_size); 213 214 OSL_ASSERT( (0 == nParams) || (nParams == jni->GetArrayLength( jo_args )) ); 215 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 216 { 217 typelib_MethodParameter const & param = pParams[ nPos ]; 218 typelib_TypeDescriptionReference * type = param.pTypeRef; 219 220 uno_args[ nPos ] = &uno_args_mem[ nPos ]; 221 if (typelib_TypeClass_STRUCT == type->eTypeClass || 222 typelib_TypeClass_EXCEPTION == type->eTypeClass) 223 { 224 TypeDescr td( type ); 225 if (sal::static_int_cast< sal_uInt32 >(td.get()->nSize) 226 > sizeof (largest)) 227 #ifdef BROKEN_ALLOCA 228 uno_args[ nPos ] = malloc( td.get()->nSize ); 229 #else 230 uno_args[ nPos ] = alloca( td.get()->nSize ); 231 #endif 232 } 233 234 if (param.bIn) 235 { 236 try 237 { 238 JLocalAutoRef jo_arg( 239 jni, jni->GetObjectArrayElement( jo_args, nPos ) ); 240 jni.ensure_no_exception(); 241 jvalue java_arg; 242 java_arg.l = jo_arg.get(); 243 map_to_uno( 244 jni, uno_args[ nPos ], java_arg, type, 0, 245 false /* no assign */, sal_False != param.bOut, 246 true /* special wrapped integral types */ ); 247 } 248 catch (...) 249 { 250 // cleanup uno in args 251 for ( sal_Int32 n = 0; n < nPos; ++n ) 252 { 253 typelib_MethodParameter const & p = pParams[ n ]; 254 if (p.bIn) 255 { 256 uno_type_destructData( 257 uno_args[ n ], p.pTypeRef, 0 ); 258 } 259 #ifdef BROKEN_ALLOCA 260 if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ]) 261 free( uno_args[ nPos ] ); 262 #endif 263 } 264 #ifdef BROKEN_ALLOCA 265 free( mem ); 266 #endif 267 throw; 268 } 269 } 270 } 271 272 uno_Any uno_exc_holder; 273 uno_Any * uno_exc = &uno_exc_holder; 274 // call binary uno 275 (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc ); 276 277 if (0 == uno_exc) 278 { 279 // convert out args; destruct uno args 280 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 281 { 282 typelib_MethodParameter const & param = pParams[ nPos ]; 283 typelib_TypeDescriptionReference * type = param.pTypeRef; 284 if (param.bOut) 285 { 286 try 287 { 288 // get out holder array[ 1 ] 289 JLocalAutoRef jo_out_holder( 290 jni, jni->GetObjectArrayElement( jo_args, nPos ) ); 291 jni.ensure_no_exception(); 292 jvalue java_arg; 293 java_arg.l = jo_out_holder.get(); 294 map_to_java( 295 jni, &java_arg, uno_args[ nPos ], type, 0, 296 true /* in */, true /* out holder */ ); 297 } 298 catch (...) 299 { 300 // cleanup further uno args 301 for ( sal_Int32 n = nPos; n < nParams; ++n ) 302 { 303 uno_type_destructData( 304 uno_args[ n ], pParams[ n ].pTypeRef, 0 ); 305 #ifdef BROKEN_ALLOCA 306 if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ]) 307 free( uno_args[ nPos ] ); 308 #endif 309 } 310 // cleanup uno return value 311 uno_type_destructData( uno_ret, return_type, 0 ); 312 #ifdef BROKEN_ALLOCA 313 free( mem ); 314 #endif 315 throw; 316 } 317 } 318 if (typelib_TypeClass_DOUBLE < type->eTypeClass && 319 typelib_TypeClass_ENUM != type->eTypeClass) // opt 320 { 321 uno_type_destructData( uno_args[ nPos ], type, 0 ); 322 #ifdef BROKEN_ALLOCA 323 if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ]) 324 free( uno_args[ nPos ] ); 325 #endif 326 } 327 } 328 329 if (typelib_TypeClass_VOID != return_type->eTypeClass) 330 { 331 // convert uno return value 332 jvalue java_ret; 333 try 334 { 335 map_to_java( 336 jni, &java_ret, uno_ret, return_type, 0, 337 true /* in */, false /* no out */, 338 true /* special_wrapped_integral_types */ ); 339 } 340 catch (...) 341 { 342 uno_type_destructData( uno_ret, return_type, 0 ); 343 #ifdef BROKEN_ALLOCA 344 free( mem ); 345 #endif 346 throw; 347 } 348 if (typelib_TypeClass_DOUBLE < return_type->eTypeClass && 349 typelib_TypeClass_ENUM != return_type->eTypeClass) // opt 350 { 351 uno_type_destructData( uno_ret, return_type, 0 ); 352 } 353 #ifdef BROKEN_ALLOCA 354 free( mem ); 355 #endif 356 return java_ret.l; 357 } 358 #ifdef BROKEN_ALLOCA 359 free( mem ); 360 #endif 361 return 0; // void return 362 } 363 else // exception occured 364 { 365 // destruct uno in args 366 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 367 { 368 typelib_MethodParameter const & param = pParams[ nPos ]; 369 if (param.bIn) 370 uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 ); 371 #ifdef BROKEN_ALLOCA 372 if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ]) 373 free( uno_args[ nPos ] ); 374 #endif 375 } 376 377 handle_uno_exc( jni, uno_exc ); 378 #ifdef BROKEN_ALLOCA 379 free( mem ); 380 #endif 381 return 0; 382 } 383 } 384 385 } 386 387 using namespace ::jni_uno; 388 389 extern "C" 390 { 391 392 //------------------------------------------------------------------------------ 393 JNIEXPORT jobject 394 JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call( 395 JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, jstring, 396 jstring jo_method, jobjectArray jo_args /* may be 0 */ ) 397 SAL_THROW_EXTERN_C() 398 { 399 Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle ); 400 JNI_info const * jni_info = bridge->m_jni_info; 401 JNI_context jni( 402 jni_info, jni_env, 403 static_cast< jobject >( 404 reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >( 405 bridge->m_java_env->pContext )->getClassLoader() ) ); 406 407 OUString method_name; 408 409 try 410 { 411 method_name = jstring_to_oustring( jni, jo_method ); 412 #if OSL_DEBUG_LEVEL > 1 413 { 414 OUStringBuffer trace_buf( 64 ); 415 trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("java->uno call: ") ); 416 trace_buf.append( method_name ); 417 trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") ); 418 JLocalAutoRef jo_oid( 419 jni, jni->GetObjectField( 420 jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) ); 421 trace_buf.append( jstring_to_oustring( jni, (jstring) jo_oid.get() ) ); 422 OString cstr_msg( 423 OUStringToOString( 424 trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); 425 OSL_TRACE( cstr_msg.getStr() ); 426 } 427 #endif 428 429 // special IQueryInterface.queryInterface() 430 if (method_name.equalsAsciiL( 431 RTL_CONSTASCII_STRINGPARAM("queryInterface") )) 432 { 433 // oid 434 JLocalAutoRef jo_oid( 435 jni, jni->GetObjectField( 436 jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) ); 437 // type 438 JLocalAutoRef jo_type( 439 jni, jni->GetObjectArrayElement( jo_args, 0 ) ); 440 jni.ensure_no_exception(); 441 442 JLocalAutoRef jo_type_name( 443 jni, jni->GetObjectField( 444 jo_type.get(), jni_info->m_field_Type__typeName ) ); 445 if (! jo_type_name.is()) 446 { 447 throw BridgeRuntimeError( 448 OUSTR("incomplete type object: no type name!") + 449 jni.get_stack_trace() ); 450 } 451 OUString type_name( 452 jstring_to_oustring( jni, (jstring) jo_type_name.get() ) ); 453 JNI_type_info const * info = 454 jni_info->get_type_info( jni, type_name ); 455 if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass) 456 { 457 throw BridgeRuntimeError( 458 OUSTR("queryInterface() call demands an INTERFACE type!") ); 459 } 460 JNI_interface_type_info const * iface_info = 461 static_cast< JNI_interface_type_info const * >( info ); 462 463 // getRegisteredInterface() already tested in JNI_proxy: 464 // perform queryInterface call on binary uno interface 465 uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >( 466 jni->GetLongField( 467 jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); 468 469 uno_Any uno_ret; 470 void * uno_args[] = { &iface_info->m_td.get()->pWeakRef }; 471 uno_Any uno_exc_holder; 472 uno_Any * uno_exc = &uno_exc_holder; 473 // call binary uno 474 (*pUnoI->pDispatcher)( 475 pUnoI, jni_info->m_XInterface_queryInterface_td.get(), 476 &uno_ret, uno_args, &uno_exc ); 477 if (0 == uno_exc) 478 { 479 jobject jo_ret = 0; 480 if (typelib_TypeClass_INTERFACE == uno_ret.pType->eTypeClass) 481 { 482 uno_Interface * pUnoRet = 483 (uno_Interface *) uno_ret.pReserved; 484 if (0 != pUnoRet) 485 { 486 try 487 { 488 jo_ret = 489 bridge->map_to_java( jni, pUnoRet, iface_info ); 490 } 491 catch (...) 492 { 493 uno_any_destruct( &uno_ret, 0 ); 494 throw; 495 } 496 } 497 } 498 uno_any_destruct( &uno_ret, 0 ); 499 return jo_ret; 500 } 501 else 502 { 503 bridge->handle_uno_exc( jni, uno_exc ); 504 return 0; 505 } 506 } 507 508 typelib_InterfaceTypeDescription * td = 509 reinterpret_cast< typelib_InterfaceTypeDescription * >( 510 jni->GetLongField( 511 jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) ); 512 uno_Interface * pUnoI = 513 reinterpret_cast< uno_Interface * >( 514 jni->GetLongField( 515 jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); 516 517 typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers; 518 for ( sal_Int32 nPos = td->nAllMembers; nPos--; ) 519 { 520 // try to avoid getting typedescription as long as possible, 521 // because of a Mutex.acquire() in 522 // typelib_typedescriptionreference_getDescription() 523 typelib_TypeDescriptionReference * member_type = 524 ppAllMembers[ nPos ]; 525 526 // check method_name against fully qualified type_name 527 // of member_type; type_name is of the form 528 // <name> "::" <method_name> *(":@" <idx> "," <idx> ":" <name>) 529 OUString const & type_name = 530 OUString::unacquired( &member_type->pTypeName ); 531 sal_Int32 offset = type_name.indexOf( ':' ) + 2; 532 OSL_ASSERT( 533 offset >= 2 && offset < type_name.getLength() 534 && type_name[offset - 1] == ':' ); 535 sal_Int32 remainder = type_name.getLength() - offset; 536 if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass) 537 { 538 if ((method_name.getLength() == remainder 539 || (method_name.getLength() < remainder 540 && type_name[offset + method_name.getLength()] == ':')) 541 && type_name.match(method_name, offset)) 542 { 543 TypeDescr member_td( member_type ); 544 typelib_InterfaceMethodTypeDescription * method_td = 545 reinterpret_cast< 546 typelib_InterfaceMethodTypeDescription * >( 547 member_td.get() ); 548 return bridge->call_uno( 549 jni, pUnoI, member_td.get(), 550 method_td->pReturnTypeRef, 551 method_td->nParams, method_td->pParams, 552 jo_args ); 553 } 554 } 555 else // attribute 556 { 557 OSL_ASSERT( 558 typelib_TypeClass_INTERFACE_ATTRIBUTE == 559 member_type->eTypeClass ); 560 561 if (method_name.getLength() >= 3 562 && (method_name.getLength() - 3 == remainder 563 || (method_name.getLength() - 3 < remainder 564 && type_name[ 565 offset + (method_name.getLength() - 3)] == ':')) 566 && method_name[1] == 'e' && method_name[2] == 't' 567 && rtl_ustr_compare_WithLength( 568 type_name.getStr() + offset, 569 method_name.getLength() - 3, 570 method_name.getStr() + 3, 571 method_name.getLength() - 3) == 0) 572 { 573 if ('g' == method_name[ 0 ]) 574 { 575 TypeDescr member_td( member_type ); 576 typelib_InterfaceAttributeTypeDescription * attr_td = 577 reinterpret_cast< 578 typelib_InterfaceAttributeTypeDescription * >( 579 member_td.get() ); 580 return bridge->call_uno( 581 jni, pUnoI, member_td.get(), 582 attr_td->pAttributeTypeRef, 583 0, 0, 584 jo_args ); 585 } 586 else if ('s' == method_name[ 0 ]) 587 { 588 TypeDescr member_td( member_type ); 589 typelib_InterfaceAttributeTypeDescription * attr_td = 590 reinterpret_cast< 591 typelib_InterfaceAttributeTypeDescription * >( 592 member_td.get() ); 593 if (! attr_td->bReadOnly) 594 { 595 typelib_MethodParameter param; 596 param.pTypeRef = attr_td->pAttributeTypeRef; 597 param.bIn = sal_True; 598 param.bOut = sal_False; 599 return bridge->call_uno( 600 jni, pUnoI, member_td.get(), 601 jni_info->m_void_type.getTypeLibType(), 602 1, ¶m, 603 jo_args ); 604 } 605 } 606 } 607 } 608 } 609 // the thing that should not be... no method info found! 610 OUStringBuffer buf( 64 ); 611 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( 612 "calling undeclared function on interface ") ); 613 buf.append( OUString::unacquired( 614 &((typelib_TypeDescription *)td)->pTypeName ) ); 615 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") ); 616 buf.append( method_name ); 617 buf.append( jni.get_stack_trace() ); 618 throw BridgeRuntimeError( buf.makeStringAndClear() ); 619 } 620 catch (BridgeRuntimeError & err) 621 { 622 OUStringBuffer buf( 128 ); 623 buf.appendAscii( 624 RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] " 625 "Java calling UNO method ") ); 626 buf.append( method_name ); 627 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") ); 628 buf.append( err.m_message ); 629 // notify RuntimeException 630 OString cstr_msg( 631 OUStringToOString( 632 buf.makeStringAndClear(), RTL_TEXTENCODING_JAVA_UTF8 ) ); 633 OSL_ENSURE( 0, cstr_msg.getStr() ); 634 if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr()) 635 != 0) 636 { 637 OSL_ASSERT( false ); 638 } 639 return 0; 640 } 641 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &) 642 { 643 OString cstr_msg( 644 OString( RTL_CONSTASCII_STRINGPARAM( 645 "[jni_uno bridge error] " 646 "attaching current thread to java failed!") ) + 647 OUStringToOString( 648 jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8 ) ); 649 OSL_ENSURE( 0, cstr_msg.getStr() ); 650 if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr()) 651 != 0) 652 { 653 OSL_ASSERT( false ); 654 } 655 return 0; 656 } 657 } 658 659 //------------------------------------------------------------------------------ 660 JNIEXPORT void 661 JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J( 662 JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle ) 663 SAL_THROW_EXTERN_C() 664 { 665 Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle ); 666 JNI_info const * jni_info = bridge->m_jni_info; 667 JNI_context jni( 668 jni_info, jni_env, 669 static_cast< jobject >( 670 reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >( 671 bridge->m_java_env->pContext )->getClassLoader() ) ); 672 673 uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >( 674 jni->GetLongField( 675 jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); 676 typelib_TypeDescription * td = 677 reinterpret_cast< typelib_TypeDescription * >( 678 jni->GetLongField( 679 jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) ); 680 681 #if OSL_DEBUG_LEVEL > 1 682 { 683 JLocalAutoRef jo_oid( 684 jni, jni->GetObjectField( 685 jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) ); 686 OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) ); 687 OString cstr_msg( 688 OUStringToOString( 689 OUSTR("freeing java uno proxy: ") + oid, 690 RTL_TEXTENCODING_ASCII_US ) ); 691 OSL_TRACE( cstr_msg.getStr() ); 692 } 693 #endif 694 // revoke from uno env; has already been revoked from java env 695 (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI ); 696 // release receiver 697 (*pUnoI->release)( pUnoI ); 698 // release typedescription handle 699 typelib_typedescription_release( td ); 700 // release bridge handle 701 bridge->release(); 702 } 703 704 } 705