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 33 extern "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. */ 48 JNIEXPORT void JNICALL 49 JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg); 50 51 /* Throw common exceptions */ 52 JNIEXPORT void JNICALL 53 JNU_ThrowNullPointerException(JNIEnv *env, const char *msg); 54 55 JNIEXPORT void JNICALL 56 JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv *env, const char *msg); 57 58 JNIEXPORT void JNICALL 59 JNU_ThrowOutOfMemoryError(JNIEnv *env, const char *msg); 60 61 JNIEXPORT void JNICALL 62 JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg); 63 64 JNIEXPORT void JNICALL 65 JNU_ThrowInternalError(JNIEnv *env, const char *msg); 66 67 JNIEXPORT void JNICALL 68 JNU_ThrowIOException(JNIEnv *env, const char *msg); 69 70 JNIEXPORT void JNICALL 71 JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg); 72 73 /* Throw an exception by name, using the string returned by 74 * getLastErrorString for the detail string. If the last-error 75 * string is NULL, use the given default detail string. 76 */ 77 JNIEXPORT void JNICALL 78 JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name, 79 const char *defaultDetail); 80 81 /* Throw an exception by name, using a given message and the string 82 * returned by getLastErrorString to construct the detail string. 83 */ 84 JNIEXPORT void JNICALL 85 JNU_ThrowByNameWithMessageAndLastError 86 (JNIEnv *env, const char *name, const char *message); 87 88 /* Throw an IOException, using the last-error string for the detail 89 * string. If the last-error string is NULL, use the given default 90 * detail string. 91 */ 92 JNIEXPORT void JNICALL 93 JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail); 94 95 /* Convert between Java strings and i18n C strings */ 96 JNIEXPORT jstring 97 NewStringPlatform(JNIEnv *env, const char *str); 98 99 JNIEXPORT const char * 100 GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy); 101 102 JNIEXPORT jstring JNICALL 103 JNU_NewStringPlatform(JNIEnv *env, const char *str); 104 105 JNIEXPORT const char * JNICALL 106 JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy); 107 108 JNIEXPORT void JNICALL 109 JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str); 110 111 /* Class constants */ 112 JNIEXPORT jclass JNICALL 113 JNU_ClassString(JNIEnv *env); 114 115 /* Copy count number of arguments from src to dst. Array bounds 116 * and ArrayStoreException are checked. 117 */ 118 JNIEXPORT jint JNICALL 119 JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src, 120 jint count); 121 122 /* Invoke a object-returning static method, based on class name, 123 * method name, and signature string. 124 * 125 * The caller should check for exceptions by setting hasException 126 * argument. If the caller is not interested in whether an exception 127 * has occurred, pass in NULL. 128 */ 129 JNIEXPORT jvalue JNICALL 130 JNU_CallStaticMethodByName(JNIEnv *env, 131 jboolean *hasException, 132 const char *class_name, 133 const char *name, 134 const char *signature, 135 ...); 136 137 /* Invoke an instance method by name. 138 */ 139 JNIEXPORT jvalue JNICALL 140 JNU_CallMethodByName(JNIEnv *env, 141 jboolean *hasException, 142 jobject obj, 143 const char *name, 144 const char *signature, 145 ...); 146 147 JNIEXPORT jvalue JNICALL 148 JNU_CallMethodByNameV(JNIEnv *env, 149 jboolean *hasException, 150 jobject obj, 151 const char *name, 152 const char *signature, 153 va_list args); 154 155 /* Construct a new object of class, specifying the class by name, 156 * and specififying which constructor to run and what arguments to 157 * pass to it. 158 * 159 * The method will return an initialized instance if successful. 160 * It will return NULL if an error has occurred (for example if 161 * it ran out of memory) and the appropriate Java exception will 162 * have been thrown. 163 */ 164 JNIEXPORT jobject JNICALL 165 JNU_NewObjectByName(JNIEnv *env, const char *class_name, 166 const char *constructor_sig, ...); 167 168 /* returns: 169 * 0: object is not an instance of the class named by classname. 170 * 1: object is an instance of the class named by classname. 171 * -1: the class named by classname cannot be found. An exception 172 * has been thrown. 173 */ 174 JNIEXPORT jint JNICALL 175 JNU_IsInstanceOfByName(JNIEnv *env, jobject object, const char *classname); 176 177 178 /* Get or set class and instance fields. 179 * Note that set functions take a variable number of arguments, 180 * but only one argument of the appropriate type can be passed. 181 * For example, to set an integer field i to 100: 182 * 183 * JNU_SetFieldByName(env, &exc, obj, "i", "I", 100); 184 * 185 * To set a float field f to 12.3: 186 * 187 * JNU_SetFieldByName(env, &exc, obj, "f", "F", 12.3); 188 * 189 * The caller should check for exceptions by setting hasException 190 * argument. If the caller is not interested in whether an exception 191 * has occurred, pass in NULL. 192 */ 193 JNIEXPORT jvalue JNICALL 194 JNU_GetFieldByName(JNIEnv *env, 195 jboolean *hasException, 196 jobject obj, 197 const char *name, 198 const char *sig); 199 JNIEXPORT void JNICALL 200 JNU_SetFieldByName(JNIEnv *env, 201 jboolean *hasException, 202 jobject obj, 203 const char *name, 204 const char *sig, 205 ...); 206 207 JNIEXPORT jvalue JNICALL 208 JNU_GetStaticFieldByName(JNIEnv *env, 209 jboolean *hasException, 210 const char *classname, 211 const char *name, 212 const char *sig); 213 214 215 /************************************************************************ 216 * Miscellaneous utilities used by the class libraries 217 */ 218 219 #define IS_NULL(obj) ((obj) == NULL) 220 #define JNU_IsNull(env,obj) ((obj) == NULL) 221 222 /************************************************************************ 223 * Miscellaneous utilities used by the class libraries to return from 224 * a function if a value is NULL or an exception is pending. 225 */ 226 227 #define CHECK_NULL(x) \ 228 do { \ 229 if ((x) == NULL) { \ 230 return; \ 231 } \ 232 } while (0) \ 233 234 #define CHECK_NULL_THROW_NPE(env, x, msg) \ 235 do { \ 236 if ((x) == NULL) { \ 237 JNU_ThrowNullPointerException((env), (msg));\ 238 return; \ 239 } \ 240 } while(0) \ 241 242 #define CHECK_NULL_THROW_NPE_RETURN(env, x, msg, z)\ 243 do { \ 244 if ((x) == NULL) { \ 245 JNU_ThrowNullPointerException((env), (msg));\ 246 return (z); \ 247 } \ 248 } while(0) \ 249 250 #define CHECK_NULL_RETURN(x, y) \ 251 do { \ 252 if ((x) == NULL) { \ 253 return (y); \ 254 } \ 255 } while (0) \ 256 257 #ifdef __cplusplus 258 #define JNU_CHECK_EXCEPTION(env) \ 259 do { \ 260 if ((env)->ExceptionCheck()) { \ 261 return; \ 262 } \ 263 } while (0) \ 264 265 #define JNU_CHECK_EXCEPTION_RETURN(env, y) \ 266 do { \ 267 if ((env)->ExceptionCheck()) { \ 268 return (y); \ 269 } \ 270 } while (0) 271 #else 272 #define JNU_CHECK_EXCEPTION(env) \ 273 do { \ 274 if ((*env)->ExceptionCheck(env)) { \ 275 return; \ 276 } \ 277 } while (0) \ 278 279 #define JNU_CHECK_EXCEPTION_RETURN(env, y) \ 280 do { \ 281 if ((*env)->ExceptionCheck(env)) { \ 282 return (y); \ 283 } \ 284 } while (0) 285 #endif /* __cplusplus */ 286 287 /************************************************************************ 288 * Debugging utilities 289 */ 290 291 JNIEXPORT jstring JNICALL 292 JNU_ToString(JNIEnv *env, jobject object); 293 294 295 /* 296 * Package shorthand for use by native libraries 297 */ 298 #define JNU_JAVAPKG "java/lang/" 299 #define JNU_JAVAIOPKG "java/io/" 300 #define JNU_JAVANETPKG "java/net/" 301 302 /* 303 * Check if the current thread is attached to the VM, and returns 304 * the JNIEnv of the specified version if the thread is attached. 305 * 306 * If the current thread is not attached, this function returns 0. 307 * 308 * If the current thread is attached, this function returns the 309 * JNI environment, or returns (void *)JNI_ERR if the specified 310 * version is not supported. 311 */ 312 JNIEXPORT void * JNICALL 313 JNU_GetEnv(JavaVM *vm, jint version); 314 315 /* 316 * Warning free access to pointers stored in Java long fields. 317 */ 318 #define JNU_GetLongFieldAsPtr(env,obj,id) \ 319 (jlong_to_ptr((*(env))->GetLongField((env),(obj),(id)))) 320 #define JNU_SetLongFieldFromPtr(env,obj,id,val) \ 321 (*(env))->SetLongField((env),(obj),(id),ptr_to_jlong(val)) 322 323 /* 324 * Internal use only. 325 */ 326 enum { 327 NO_ENCODING_YET = 0, /* "sun.jnu.encoding" not yet set */ 328 NO_FAST_ENCODING, /* Platform encoding is not fast */ 329 FAST_8859_1, /* ISO-8859-1 */ 330 FAST_CP1252, /* MS-DOS Cp1252 */ 331 FAST_646_US, /* US-ASCII : ISO646-US */ 332 FAST_UTF_8 333 }; 334 335 JNIEXPORT void InitializeEncoding(JNIEnv *env, const char *name); 336 337 void* getProcessHandle(); 338 339 void buildJniFunctionName(const char *sym, const char *cname, 340 char *jniEntryName); 341 342 JNIEXPORT size_t JNICALL 343 getLastErrorString(char *buf, size_t len); 344 345 JNIEXPORT int JNICALL 346 getErrorString(int err, char *buf, size_t len); 347 348 #ifdef STATIC_BUILD 349 /* Macros for handling declaration of static/dynamic 350 * JNI library Load/Unload functions 351 * 352 * Use DEF_JNI_On{Un}Load when you want a static and non-static entry points. 353 * Use DEF_STATIC_JNI_On{Un}Load when you only want a static one. 354 * 355 * LIBRARY_NAME must be set to the name of the library 356 */ 357 358 /* These three macros are needed to get proper concatenation of 359 * the LIBRARY_NAME 360 * 361 * NOTE: LIBRARY_NAME must be set for static builds. 362 */ 363 #define ADD_LIB_NAME3(name, lib) name ## lib 364 #define ADD_LIB_NAME2(name, lib) ADD_LIB_NAME3(name, lib) 365 #define ADD_LIB_NAME(entry) ADD_LIB_NAME2(entry, LIBRARY_NAME) 366 367 #define DEF_JNI_OnLoad \ 368 ADD_LIB_NAME(JNI_OnLoad_)(JavaVM *vm, void *reserved) \ 369 { \ 370 jint JNICALL ADD_LIB_NAME(JNI_OnLoad_dynamic_)(JavaVM *vm, void *reserved); \ 371 ADD_LIB_NAME(JNI_OnLoad_dynamic_)(vm, reserved); \ 372 return JNI_VERSION_1_8; \ 373 } \ 374 jint JNICALL ADD_LIB_NAME(JNI_OnLoad_dynamic_) 375 376 #define DEF_STATIC_JNI_OnLoad \ 377 JNIEXPORT jint JNICALL ADD_LIB_NAME(JNI_OnLoad_)(JavaVM *vm, void *reserved) { \ 378 return JNI_VERSION_1_8; \ 379 } 380 381 #define DEF_JNI_OnUnload \ 382 ADD_LIB_NAME(JNI_OnUnload_)(JavaVM *vm, void *reserved) \ 383 { \ 384 void JNICALL ADD_LIB_NAME(JNI_OnUnload_dynamic_)(JavaVM *vm, void *reserved); \ 385 ADD_LIB_NAME(JNI_OnUnload_dynamic_)(vm, reserved); \ 386 } \ 387 void JNICALL ADD_LIB_NAME(JNI_OnUnload_dynamic_) 388 389 #define DEF_STATIC_JNI_OnUnload \ 390 ADD_LIB_NAME(JNI_OnUnload_) 391 392 #else 393 394 #define DEF_JNI_OnLoad JNI_OnLoad 395 #define DEF_STATIC_JNI_OnLoad 396 #define DEF_JNI_OnUnload JNI_OnUnload 397 #define DEF_STATIC_JNI_OnUnload 398 #endif 399 400 #ifdef STATIC_BUILD 401 /* Macros for handling declaration of static/dynamic 402 * Agent library Load/Attach/Unload functions 403 * 404 * Use DEF_Agent_OnLoad, DEF_Agent_OnAttach or DEF_Agent_OnUnload 405 * when you want both static and non-static entry points. 406 * Use DEF_STATIC_Agent_OnLoad, DEF_STATIC_Agent_OnAttach or 407 * DEF_STATIC_Agent_OnUnload when you only want a static one. 408 * 409 * LIBRARY_NAME must be set to the name of the library for static builds. 410 */ 411 412 #define DEF_Agent_OnLoad \ 413 ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) \ 414 { \ 415 jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)(JavaVM *vm, char *options, void *reserved); \ 416 return ADD_LIB_NAME(Agent_OnLoad_dynamic_)(vm, options, reserved); \ 417 } \ 418 jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_) 419 420 #define DEF_STATIC_Agent_OnLoad \ 421 JNIEXPORT jint JNICALL ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) { \ 422 return JNI_FALSE; \ 423 } 424 425 #define DEF_Agent_OnAttach \ 426 ADD_LIB_NAME(Agent_OnAttach_)(JavaVM *vm, char *options, void *reserved) \ 427 { \ 428 jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)(JavaVM *vm, char *options, void *reserved); \ 429 return ADD_LIB_NAME(Agent_OnAttach_dynamic_)(vm, options, reserved); \ 430 } \ 431 jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_) 432 433 #define DEF_STATIC_Agent_OnAttach \ 434 JNIEXPORT jint JNICALL ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) { \ 435 return JNI_FALSE; \ 436 } 437 438 #define DEF_Agent_OnUnload \ 439 ADD_LIB_NAME(Agent_OnUnload_)(JavaVM *vm) \ 440 { \ 441 void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)(JavaVM *vm); \ 442 ADD_LIB_NAME(Agent_OnUnload_dynamic_)(vm); \ 443 } \ 444 void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_) 445 446 #define DEF_STATIC_Agent_OnUnload \ 447 ADD_LIB_NAME(Agent_OnUnload_) 448 449 #else 450 #define DEF_Agent_OnLoad Agent_OnLoad 451 #define DEF_Agent_OnAttach Agent_OnAttach 452 #define DEF_Agent_OnUnload Agent_OnUnload 453 #define DEF_STATIC_Agent_OnLoad 454 #define DEF_STATIC_Agent_OnAttach 455 #define DEF_STATIC_Agent_OnUnload 456 #endif 457 458 #ifdef __cplusplus 459 } /* extern "C" */ 460 #endif /* __cplusplus */ 461 462 #endif /* JNI_UTIL_H */