LibreOffice Module bridges (master)  1
jni_base.h
Go to the documentation of this file.
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 #pragma once
21 
22 #include <sal/config.h>
23 
24 #include <cassert>
25 
28 
29 #include <osl/diagnose.h>
30 
31 #include <rtl/alloc.h>
32 #include <rtl/ustring.hxx>
33 #include <sal/log.hxx>
34 #include <utility>
35 
36 #include <uno/environment.h>
37 #include <typelib/typedescription.h>
38 
39 
40 namespace jni_uno
41 {
42 
43 class JNI_info;
44 
46 {
47  OUString m_message;
48 
49  explicit BridgeRuntimeError( OUString message )
50  : m_message(std::move( message ))
51  {}
52 };
53 
54 
56 {
58  JNIEnv * m_env;
59  jobject m_class_loader;
60 
61  JNI_context( JNI_context const & ) = delete;
62  JNI_context& operator = ( JNI_context const &) = delete;
63 
64  void java_exc_occurred() const;
65 public:
66  explicit JNI_context(
67  JNI_info const * jni_info, JNIEnv * env, jobject class_loader )
68  : m_jni_info( jni_info ),
69  m_env( env ),
70  m_class_loader( class_loader )
71  {}
72 
73  JNI_info const * get_info() const
74  { return m_jni_info; }
75 
76  JNIEnv * operator -> () const
77  { return m_env; }
78  JNIEnv * get_jni_env() const
79  { return m_env; }
80 
81  // does not handle exceptions, *classClass will be null if exception
82  // occurred:
83  void getClassForName(jclass * classClass, jmethodID * methodForName) const;
84 
85  // if inException, does not handle exceptions, in which case returned value
86  // will be null if exception occurred:
87  jclass findClass(
88  char const * name, jclass classClass, jmethodID methodForName,
89  bool inException) const;
90 
91  inline void ensure_no_exception() const; // throws BridgeRuntimeError
92  inline bool assert_no_exception() const; // asserts and clears exception
93 
94  OUString get_stack_trace( jobject jo_exc = nullptr ) const;
95 };
96 
98 {
99  if (m_env->ExceptionCheck())
100  {
102  }
103 }
104 
106 {
107  if (m_env->ExceptionCheck())
108  {
109  SAL_WARN("bridges", "unexpected java exception occurred");
110 #if OSL_DEBUG_LEVEL > 0
111  m_env->ExceptionDescribe();
112 #endif
113  m_env->ExceptionClear();
114  return false;
115  }
116  return true;
117 }
118 
119 
122  public JNI_context
123 {
124  JNI_guarded_context( JNI_guarded_context const & ) = delete;
126 
127 public:
129  JNI_info const * jni_info,
131  : AttachGuard( vm_access->getVirtualMachine() ),
132  JNI_context(
133  jni_info, AttachGuard::getEnvironment(),
134  static_cast< jobject >(vm_access->getClassLoader()) )
135  {}
136 };
137 
138 
140 {
142  jobject m_jo;
143 
144 public:
145  explicit JLocalAutoRef( JNI_context const & jni )
146  : m_jni( jni ),
147  m_jo( nullptr )
148  {}
149  explicit JLocalAutoRef( JNI_context const & jni, jobject jo )
150  : m_jni( jni ),
151  m_jo( jo )
152  {}
153  inline JLocalAutoRef( JLocalAutoRef & auto_ref );
154  inline ~JLocalAutoRef();
155 
156  jobject get() const
157  { return m_jo; }
158  bool is() const
159  { return (nullptr != m_jo); }
160  inline jobject release();
161  inline void reset( jobject jo );
162  inline JLocalAutoRef & operator = ( JLocalAutoRef & auto_ref );
163 };
164 
166 {
167  if (nullptr != m_jo)
168  m_jni->DeleteLocalRef( m_jo );
169 }
170 
172  : m_jni( auto_ref.m_jni ),
173  m_jo( auto_ref.m_jo )
174 {
175  auto_ref.m_jo = nullptr;
176 }
177 
178 inline jobject JLocalAutoRef::release()
179 {
180  jobject jo = m_jo;
181  m_jo = nullptr;
182  return jo;
183 }
184 
185 inline void JLocalAutoRef::reset( jobject jo )
186 {
187  if (jo != m_jo)
188  {
189  if (nullptr != m_jo)
190  m_jni->DeleteLocalRef( m_jo );
191  m_jo = jo;
192  }
193 }
194 
196 {
197  assert( m_jni.get_jni_env() == auto_ref.m_jni.get_jni_env() );
198  reset( auto_ref.m_jo );
199  auto_ref.m_jo = nullptr;
200  return *this;
201 }
202 
203 
204 
205 struct rtl_mem
206 {
207  static void * operator new ( size_t nSize )
208  { return std::malloc( nSize ); }
209  static void operator delete ( void * mem )
210  { std::free( mem ); }
211  static void * operator new ( size_t, void * mem )
212  { return mem; }
213  static void operator delete ( void *, void * )
214  {}
215 
216  static inline rtl_mem * allocate( std::size_t bytes );
217 };
218 
219 inline rtl_mem * rtl_mem::allocate( std::size_t bytes )
220 {
221  void * p = std::malloc( bytes );
222  if (nullptr == p)
223  throw BridgeRuntimeError( "out of memory!" );
224  return static_cast<rtl_mem *>(p);
225 }
226 
227 
229 {
231 
232  TypeDescr( TypeDescr const & ) = delete;
233  TypeDescr& operator = ( TypeDescr const & ) = delete;
234 
235 public:
236  inline explicit TypeDescr( typelib_TypeDescriptionReference * td_ref );
238  { TYPELIB_DANGER_RELEASE( m_td ); }
239 
241  { return m_td; }
242 };
243 
244 inline TypeDescr::TypeDescr( typelib_TypeDescriptionReference * td_ref )
245  : m_td( nullptr )
246 {
247  TYPELIB_DANGER_GET( &m_td, td_ref );
248  if (nullptr == m_td)
249  {
250  throw BridgeRuntimeError(
251  "cannot get comprehensive type description for " +
252  OUString::unacquired( &td_ref->pTypeName ) );
253  }
254 }
255 
256 }
257 
258 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void java_exc_occurred() const
Definition: jni_bridge.cxx:276
JNI_context(JNI_info const *jni_info, JNIEnv *env, jobject class_loader)
Definition: jni_base.h:66
JNIEnv * get_jni_env() const
Definition: jni_base.h:78
std::vector< sal_uInt8 > bytes
JLocalAutoRef(JNI_context const &jni, jobject jo)
Definition: jni_base.h:149
JNI_context(JNI_context const &)=delete
bool assert_no_exception() const
Definition: jni_base.h:105
jobject m_class_loader
Definition: jni_base.h:59
JNI_info const * get_info() const
Definition: jni_base.h:73
OUString get_stack_trace(jobject jo_exc=nullptr) const
Definition: jni_bridge.cxx:377
TypeDescr(TypeDescr const &)=delete
JNI_info const * m_jni_info
Definition: jni_base.h:57
void ensure_no_exception() const
Definition: jni_base.h:97
bool is() const
Definition: jni_base.h:158
void reset(jobject jo)
Definition: jni_base.h:185
JLocalAutoRef(JNI_context const &jni)
Definition: jni_base.h:145
typelib_TypeDescription * m_td
Definition: jni_base.h:230
JNI_guarded_context & operator=(JNI_guarded_context const &)=delete
JNI_guarded_context(JNI_guarded_context const &)=delete
jclass findClass(char const *name, jclass classClass, jmethodID methodForName, bool inException) const
Definition: jni_bridge.cxx:356
JNI_guarded_context(JNI_info const *jni_info, rtl::Reference< jvmaccess::UnoVirtualMachine > const &vm_access)
Definition: jni_base.h:128
JLocalAutoRef & operator=(JLocalAutoRef &auto_ref)
Definition: jni_base.h:195
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:52
friend friend class AttachGuard
AttachGuard(rtl::Reference< VirtualMachine > xMachine)
JNIEnv * operator->() const
Definition: jni_base.h:76
BridgeRuntimeError(OUString message)
Definition: jni_base.h:49
void getClassForName(jclass *classClass, jmethodID *methodForName) const
Definition: jni_bridge.cxx:343
void * p
#define SAL_WARN(area, stream)
static rtl_mem * allocate(std::size_t bytes)
Definition: jni_base.h:219
JNI_context const & m_jni
Definition: jni_base.h:141
TypeDescr & operator=(TypeDescr const &)=delete
JNI_context & operator=(JNI_context const &)=delete
char const * name