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