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