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