1/*
2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#ifndef JNI_UTIL_H
27#define JNI_UTIL_H
28
29#include "jni.h"
30#include "jlong.h"
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36/*
37 * This file contains utility functions that can be implemented in pure JNI.
38 *
39 * Caution: Callers of functions declared in this file should be
40 * particularly aware of the fact that these functions are convenience
41 * functions, and as such are often compound operations, each one of
42 * which may throw an exception. Therefore, the functions this file
43 * will often return silently if an exception has occurred, and callers
44 * must check for exception themselves.
45 */
46
47/* Throw a Java exception by name. Similar to SignalError. */
48JNIEXPORT void JNICALL
49JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg);
50
51/* Throw common exceptions */
52JNIEXPORT void JNICALL
53JNU_ThrowNullPointerException(JNIEnv *env, const char *msg);
54
55JNIEXPORT void JNICALL
56JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv *env, const char *msg);
57
58JNIEXPORT void JNICALL
59JNU_ThrowOutOfMemoryError(JNIEnv *env, const char *msg);
60
61JNIEXPORT void JNICALL
62JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg);
63
64JNIEXPORT void JNICALL
65JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg);
66
67JNIEXPORT void JNICALL
68JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg);
69
70JNIEXPORT void JNICALL
71JNU_ThrowInternalError(JNIEnv *env, const char *msg);
72
73JNIEXPORT void JNICALL
74JNU_ThrowIOException(JNIEnv *env, const char *msg);
75
76JNIEXPORT void JNICALL
77JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg);
78
79JNIEXPORT void JNICALL
80JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg);
81
82JNIEXPORT void JNICALL
83JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg);
84
85JNIEXPORT void JNICALL
86JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg);
87
88JNIEXPORT void JNICALL
89JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg);
90
91JNIEXPORT void JNICALL
92JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg);
93
94JNIEXPORT void JNICALL
95JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg);
96
97JNIEXPORT void JNICALL
98JNU_ThrowInstantiationException(JNIEnv *env, const char *msg);
99
100/* Throw an exception by name, using the string returned by
101 * getLastErrorString for the detail string. If the last-error
102 * string is NULL, use the given default detail string.
103 */
104JNIEXPORT void JNICALL
105JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name,
106 const char *defaultDetail);
107
108/* Throw an exception by name, using a given message and the string
109 * returned by getLastErrorString to construct the detail string.
110 */
111JNIEXPORT void JNICALL
112JNU_ThrowByNameWithMessageAndLastError
113 (JNIEnv *env, const char *name, const char *message);
114
115/* Throw an IOException, using the last-error string for the detail
116 * string. If the last-error string is NULL, use the given default
117 * detail string.
118 */
119JNIEXPORT void JNICALL
120JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail);
121
122/* Convert between Java strings and i18n C strings */
123JNIEXPORT jstring
124NewStringPlatform(JNIEnv *env, const char *str);
125
126JNIEXPORT const char *
127GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
128
129JNIEXPORT jstring JNICALL
130JNU_NewStringPlatform(JNIEnv *env, const char *str);
131
132JNIEXPORT const char * JNICALL
133JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
134
135JNIEXPORT void JNICALL
136JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str);
137
138/* Class constants */
139JNIEXPORT jclass JNICALL
140JNU_ClassString(JNIEnv *env);
141
142JNIEXPORT jclass JNICALL
143JNU_ClassClass(JNIEnv *env);
144
145JNIEXPORT jclass JNICALL
146JNU_ClassObject(JNIEnv *env);
147
148JNIEXPORT jclass JNICALL
149JNU_ClassThrowable(JNIEnv *env);
150
151/* Copy count number of arguments from src to dst. Array bounds
152 * and ArrayStoreException are checked.
153 */
154JNIEXPORT jint JNICALL
155JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
156 jint count);
157
158/* Invoke a object-returning static method, based on class name,
159 * method name, and signature string.
160 *
161 * The caller should check for exceptions by setting hasException
162 * argument. If the caller is not interested in whether an exception
163 * has occurred, pass in NULL.
164 */
165JNIEXPORT jvalue JNICALL
166JNU_CallStaticMethodByName(JNIEnv *env,
167 jboolean *hasException,
168 const char *class_name,
169 const char *name,
170 const char *signature,
171 ...);
172
173/* Invoke an instance method by name.
174 */
175JNIEXPORT jvalue JNICALL
176JNU_CallMethodByName(JNIEnv *env,
177 jboolean *hasException,
178 jobject obj,
179 const char *name,
180 const char *signature,
181 ...);
182
183JNIEXPORT jvalue JNICALL
184JNU_CallMethodByNameV(JNIEnv *env,
185 jboolean *hasException,
186 jobject obj,
187 const char *name,
188 const char *signature,
189 va_list args);
190
191/* Construct a new object of class, specifying the class by name,
192 * and specififying which constructor to run and what arguments to
193 * pass to it.
194 *
195 * The method will return an initialized instance if successful.
196 * It will return NULL if an error has occurred (for example if
197 * it ran out of memory) and the appropriate Java exception will
198 * have been thrown.
199 */
200JNIEXPORT jobject JNICALL
201JNU_NewObjectByName(JNIEnv *env, const char *class_name,
202 const char *constructor_sig, ...);
203
204/* returns:
205 * 0: object is not an instance of the class named by classname.
206 * 1: object is an instance of the class named by classname.
207 * -1: the class named by classname cannot be found. An exception
208 * has been thrown.
209 */
210JNIEXPORT jint JNICALL
211JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char *classname);
212
213
214/* Get or set class and instance fields.
215 * Note that set functions take a variable number of arguments,
216 * but only one argument of the appropriate type can be passed.
217 * For example, to set an integer field i to 100:
218 *
219 * JNU_SetFieldByName(env, &exc, obj, "i", "I", 100);
220 *
221 * To set a float field f to 12.3:
222 *
223 * JNU_SetFieldByName(env, &exc, obj, "f", "F", 12.3);
224 *
225 * The caller should check for exceptions by setting hasException
226 * argument. If the caller is not interested in whether an exception
227 * has occurred, pass in NULL.
228 */
229JNIEXPORT jvalue JNICALL
230JNU_GetFieldByName(JNIEnv *env,
231 jboolean *hasException,
232 jobject obj,
233 const char *name,
234 const char *sig);
235JNIEXPORT void JNICALL
236JNU_SetFieldByName(JNIEnv *env,
237 jboolean *hasException,
238 jobject obj,
239 const char *name,
240 const char *sig,
241 ...);
242
243JNIEXPORT jvalue JNICALL
244JNU_GetStaticFieldByName(JNIEnv *env,
245 jboolean *hasException,
246 const char *classname,
247 const char *name,
248 const char *sig);
249JNIEXPORT void JNICALL
250JNU_SetStaticFieldByName(JNIEnv *env,
251 jboolean *hasException,
252 const char *classname,
253 const char *name,
254 const char *sig,
255 ...);
256
257
258/*
259 * Calls the .equals method.
260 */
261JNIEXPORT jboolean JNICALL
262JNU_Equals(JNIEnv *env, jobject object1, jobject object2);
263
264
265/************************************************************************
266 * Thread calls
267 *
268 * Convenience thread-related calls on the java.lang.Object class.
269 */
270
271JNIEXPORT void JNICALL
272JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout);
273
274JNIEXPORT void JNICALL
275JNU_Notify(JNIEnv *env, jobject object);
276
277JNIEXPORT void JNICALL
278JNU_NotifyAll(JNIEnv *env, jobject object);
279
280
281/************************************************************************
282 * Miscellaneous utilities used by the class libraries
283 */
284
285#define IS_NULL(obj) ((obj) == NULL)
286#define JNU_IsNull(env,obj) ((obj) == NULL)
287
288/************************************************************************
289 * Miscellaneous utilities used by the class libraries to return from
290 * a function if a value is NULL or an exception is pending.
291 */
292
293#define CHECK_NULL(x) \
294 do { \
295 if ((x) == NULL) { \
296 return; \
297 } \
298 } while (0) \
299
300#define CHECK_NULL_THROW_NPE(env, x, msg) \
301 do { \
302 if ((x) == NULL) { \
303 JNU_ThrowNullPointerException((env), (msg));\
304 return; \
305 } \
306 } while(0) \
307
308#define CHECK_NULL_THROW_NPE_RETURN(env, x, msg, z)\
309 do { \
310 if ((x) == NULL) { \
311 JNU_ThrowNullPointerException((env), (msg));\
312 return (z); \
313 } \
314 } while(0) \
315
316#define CHECK_NULL_RETURN(x, y) \
317 do { \
318 if ((x) == NULL) { \
319 return (y); \
320 } \
321 } while (0) \
322
323#ifdef __cplusplus
324#define JNU_CHECK_EXCEPTION(env) \
325 do { \
326 if ((env)->ExceptionCheck()) { \
327 return; \
328 } \
329 } while (0) \
330
331#define JNU_CHECK_EXCEPTION_RETURN(env, y) \
332 do { \
333 if ((env)->ExceptionCheck()) { \
334 return (y); \
335 } \
336 } while (0)
337#else
338#define JNU_CHECK_EXCEPTION(env) \
339 do { \
340 if ((*env)->ExceptionCheck(env)) { \
341 return; \
342 } \
343 } while (0) \
344
345#define JNU_CHECK_EXCEPTION_RETURN(env, y) \
346 do { \
347 if ((*env)->ExceptionCheck(env)) { \
348 return (y); \
349 } \
350 } while (0)
351#endif /* __cplusplus */
352/************************************************************************
353 * Debugging utilities
354 */
355
356JNIEXPORT void JNICALL
357JNU_PrintString(JNIEnv *env, char *hdr, jstring string);
358
359JNIEXPORT void JNICALL
360JNU_PrintClass(JNIEnv *env, char *hdr, jobject object);
361
362JNIEXPORT jstring JNICALL
363JNU_ToString(JNIEnv *env, jobject object);
364
365/*
366 * Package shorthand for use by native libraries
367 */
368#define JNU_JAVAPKG "java/lang/"
369#define JNU_JAVAIOPKG "java/io/"
370#define JNU_JAVANETPKG "java/net/"
371
372/*
373 * Check if the current thread is attached to the VM, and returns
374 * the JNIEnv of the specified version if the thread is attached.
375 *
376 * If the current thread is not attached, this function returns 0.
377 *
378 * If the current thread is attached, this function returns the
379 * JNI environment, or returns (void *)JNI_ERR if the specified
380 * version is not supported.
381 */
382JNIEXPORT void * JNICALL
383JNU_GetEnv(JavaVM *vm, jint version);
384
385/*
386 * Warning free access to pointers stored in Java long fields.
387 */
388#define JNU_GetLongFieldAsPtr(env,obj,id) \
389 (jlong_to_ptr((*(env))->GetLongField((env),(obj),(id))))
390#define JNU_SetLongFieldFromPtr(env,obj,id,val) \
391 (*(env))->SetLongField((env),(obj),(id),ptr_to_jlong(val))
392
393/*
394 * Internal use only.
395 */
396enum {
397 NO_ENCODING_YET = 0, /* "sun.jnu.encoding" not yet set */
398 NO_FAST_ENCODING, /* Platform encoding is not fast */
399 FAST_8859_1, /* ISO-8859-1 */
400 FAST_CP1252, /* MS-DOS Cp1252 */
401 FAST_646_US, /* US-ASCII : ISO646-US */
402 FAST_UTF_8
403};
404
405int getFastEncoding();
406
407JNIEXPORT void InitializeEncoding(JNIEnv *env, const char *name);
408
409void* getProcessHandle();
410
411void buildJniFunctionName(const char *sym, const char *cname,
412 char *jniEntryName);
413
414JNIEXPORT size_t JNICALL
415getLastErrorString(char *buf, size_t len);
416
417JNIEXPORT int JNICALL
418getErrorString(int err, char *buf, size_t len);
419
420#ifdef STATIC_BUILD
421/* Macros for handling declaration of static/dynamic
422 * JNI library Load/Unload functions
423 *
424 * Use DEF_JNI_On{Un}Load when you want a static and non-static entry points.
425 * Use DEF_STATIC_JNI_On{Un}Load when you only want a static one.
426 *
427 * LIBRARY_NAME must be set to the name of the library
428 */
429
430/* These three macros are needed to get proper concatenation of
431 * the LIBRARY_NAME
432 *
433 * NOTE: LIBRARY_NAME must be set for static builds.
434 */
435#define ADD_LIB_NAME3(name, lib) name ## lib
436#define ADD_LIB_NAME2(name, lib) ADD_LIB_NAME3(name, lib)
437#define ADD_LIB_NAME(entry) ADD_LIB_NAME2(entry, LIBRARY_NAME)
438
439#define DEF_JNI_OnLoad \
440ADD_LIB_NAME(JNI_OnLoad_)(JavaVM *vm, void *reserved) \
441{ \
442 jint JNICALL ADD_LIB_NAME(JNI_OnLoad_dynamic_)(JavaVM *vm, void *reserved); \
443 ADD_LIB_NAME(JNI_OnLoad_dynamic_)(vm, reserved); \
444 return JNI_VERSION_1_8; \
445} \
446jint JNICALL ADD_LIB_NAME(JNI_OnLoad_dynamic_)
447
448#define DEF_STATIC_JNI_OnLoad \
449JNIEXPORT jint JNICALL ADD_LIB_NAME(JNI_OnLoad_)(JavaVM *vm, void *reserved) { \
450 return JNI_VERSION_1_8; \
451}
452
453#define DEF_JNI_OnUnload \
454ADD_LIB_NAME(JNI_OnUnload_)(JavaVM *vm, void *reserved) \
455{ \
456 void JNICALL ADD_LIB_NAME(JNI_OnUnload_dynamic_)(JavaVM *vm, void *reserved); \
457 ADD_LIB_NAME(JNI_OnUnload_dynamic_)(vm, reserved); \
458} \
459void JNICALL ADD_LIB_NAME(JNI_OnUnload_dynamic_)
460
461#define DEF_STATIC_JNI_OnUnload \
462ADD_LIB_NAME(JNI_OnUnload_)
463
464#else
465
466#define DEF_JNI_OnLoad JNI_OnLoad
467#define DEF_STATIC_JNI_OnLoad
468#define DEF_JNI_OnUnload JNI_OnUnload
469#define DEF_STATIC_JNI_OnUnload
470#endif
471
472#ifdef STATIC_BUILD
473/* Macros for handling declaration of static/dynamic
474 * Agent library Load/Attach/Unload functions
475 *
476 * Use DEF_Agent_OnLoad, DEF_Agent_OnAttach or DEF_Agent_OnUnload
477 * when you want both static and non-static entry points.
478 * Use DEF_STATIC_Agent_OnLoad, DEF_STATIC_Agent_OnAttach or
479 * DEF_STATIC_Agent_OnUnload when you only want a static one.
480 *
481 * LIBRARY_NAME must be set to the name of the library for static builds.
482 */
483
484#define DEF_Agent_OnLoad \
485ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) \
486{ \
487 jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)(JavaVM *vm, char *options, void *reserved); \
488 return ADD_LIB_NAME(Agent_OnLoad_dynamic_)(vm, options, reserved); \
489} \
490jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)
491
492#define DEF_STATIC_Agent_OnLoad \
493JNIEXPORT jint JNICALL ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) { \
494 return JNI_FALSE; \
495}
496
497#define DEF_Agent_OnAttach \
498ADD_LIB_NAME(Agent_OnAttach_)(JavaVM *vm, char *options, void *reserved) \
499{ \
500 jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)(JavaVM *vm, char *options, void *reserved); \
501 return ADD_LIB_NAME(Agent_OnAttach_dynamic_)(vm, options, reserved); \
502} \
503jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)
504
505#define DEF_STATIC_Agent_OnAttach \
506JNIEXPORT jint JNICALL ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) { \
507 return JNI_FALSE; \
508}
509
510#define DEF_Agent_OnUnload \
511ADD_LIB_NAME(Agent_OnUnload_)(JavaVM *vm) \
512{ \
513 void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)(JavaVM *vm); \
514 ADD_LIB_NAME(Agent_OnUnload_dynamic_)(vm); \
515} \
516void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)
517
518#define DEF_STATIC_Agent_OnUnload \
519ADD_LIB_NAME(Agent_OnUnload_)
520
521#else
522#define DEF_Agent_OnLoad Agent_OnLoad
523#define DEF_Agent_OnAttach Agent_OnAttach
524#define DEF_Agent_OnUnload Agent_OnUnload
525#define DEF_STATIC_Agent_OnLoad
526#define DEF_STATIC_Agent_OnAttach
527#define DEF_STATIC_Agent_OnUnload
528#endif
529
530#ifdef __cplusplus
531} /* extern "C" */
532#endif /* __cplusplus */
533
534#endif /* JNI_UTIL_H */
535