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 //______________________________________________________________________________
map_to_java(JNI_context const & jni,uno_Interface * pUnoI,JNI_interface_type_info const * info) const43 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 //______________________________________________________________________________
handle_uno_exc(JNI_context const & jni,uno_Any * uno_exc) const94 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 occured 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 //______________________________________________________________________________
call_uno(JNI_context const & jni,uno_Interface * pUnoI,typelib_TypeDescription * member_td,typelib_TypeDescriptionReference * return_type,sal_Int32 nParams,typelib_MethodParameter const * pParams,jobjectArray jo_args) const172 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 occured
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
Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call(JNIEnv * jni_env,jobject jo_proxy,jlong bridge_handle,jstring,jstring jo_method,jobjectArray jo_args)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
Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J(JNIEnv * jni_env,jobject jo_proxy,jlong bridge_handle)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