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