libAddModuleUsesAndProvidesTest.c revision 12290:8953c0318163
1/* 2 * Copyright (c) 2016, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24#include <stdio.h> 25#include <string.h> 26#include "jvmti.h" 27 28#ifdef __cplusplus 29extern "C" { 30#endif 31 32#ifndef JNI_ENV_ARG 33 34#ifdef __cplusplus 35#define JNI_ENV_ARG(x, y) y 36#define JNI_ENV_PTR(x) x 37#else 38#define JNI_ENV_ARG(x,y) x, y 39#define JNI_ENV_PTR(x) (*x) 40#endif 41 42#endif 43 44#define TranslateError(err) "JVMTI error" 45 46#define PASSED 0 47#define FAILED 2 48 49static const char *EXC_CNAME = "java/lang/Exception"; 50static const char* MOD_CNAME = "Ljava/lang/reflect/Module;"; 51 52static jvmtiEnv *jvmti = NULL; 53static jint result = PASSED; 54 55static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved); 56 57JNIEXPORT 58jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { 59 return Agent_Initialize(jvm, options, reserved); 60} 61 62JNIEXPORT 63jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { 64 return Agent_Initialize(jvm, options, reserved); 65} 66 67JNIEXPORT 68jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { 69 return JNI_VERSION_1_8; 70} 71 72static 73jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 74 jint res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), 75 JVMTI_VERSION_9); 76 if (res != JNI_OK || jvmti == NULL) { 77 printf(" Error: wrong result of a valid call to GetEnv!\n"); 78 return JNI_ERR; 79 } 80 81 return JNI_OK; 82} 83 84static 85jint throw_exc(JNIEnv *env, char *msg) { 86 jclass exc_class = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, EXC_CNAME)); 87 88 if (exc_class == NULL) { 89 printf("throw_exc: Error in FindClass(env, %s)\n", EXC_CNAME); 90 return -1; 91 } 92 return JNI_ENV_PTR(env)->ThrowNew(JNI_ENV_ARG(env, exc_class), msg); 93} 94 95static 96jclass jlrM(JNIEnv *env) { 97 jclass cls = NULL; 98 99 cls = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, MOD_CNAME)); 100 if (cls == NULL) { 101 printf(" Error in JNI FindClass: %s\n", MOD_CNAME); 102 } 103 return cls; 104} 105 106jmethodID 107get_method(JNIEnv *env, jclass clazz, const char * name, const char *sig) { 108 jmethodID method = NULL; 109 110 method = JNI_ENV_PTR(env)->GetMethodID(JNI_ENV_ARG(env, clazz), name, sig); 111 if (method == NULL) { 112 printf(" Error in JNI GetMethodID %s with signature %s", name, sig); 113 } 114 return method; 115} 116 117static 118jboolean can_use_service(JNIEnv *env, jobject module, jclass service) { 119 static jmethodID mCanUse = NULL; 120 jboolean res = JNI_FALSE; 121 122 if (mCanUse == NULL) { 123 const char* sign = "(Ljava/lang/Class;)Z"; 124 mCanUse = get_method(env, jlrM(env), "canUse", sign); 125 } 126 res = JNI_ENV_PTR(env)->CallBooleanMethod(JNI_ENV_ARG(env, module), 127 mCanUse, service); 128 return res; 129} 130 131JNIEXPORT jint JNICALL 132Java_MyPackage_AddModuleUsesAndProvidesTest_checkUses(JNIEnv *env, 133 jclass cls, 134 jobject baseModule, 135 jclass service) { 136 jvmtiError err = JVMTI_ERROR_NONE; 137 jboolean used = JNI_FALSE; 138 139 // Add a service to use to NULL module 140 printf("Check #UN1:\n"); 141 err = (*jvmti)->AddModuleUses(jvmti, NULL, service); 142 if (err != JVMTI_ERROR_NULL_POINTER) { 143 printf("#UN1: jvmtiError from AddModuleUses: %d\n", err); 144 throw_exc(env, "Check #UN1: failed to return JVMTI_ERROR_NULL_POINTER for module==NULL"); 145 return FAILED; 146 } 147 148 // Add NULL service to use to baseModule 149 printf("Check #UN2:\n"); 150 err = (*jvmti)->AddModuleUses(jvmti, baseModule, NULL); 151 if (err != JVMTI_ERROR_NULL_POINTER) { 152 printf("#UN2: jvmtiError from AddModuleUses: %d\n", err); 153 throw_exc(env, "Check #UN2: failed to return JVMTI_ERROR_NULL_POINTER for service==NULL"); 154 return FAILED; 155 } 156 157 // Add service to use to invalid module (cls) 158 printf("Check #UI1:\n"); 159 err = (*jvmti)->AddModuleUses(jvmti, (jobject)cls, service); 160 if (err != JVMTI_ERROR_INVALID_MODULE) { 161 printf("#UI1: jvmtiError from AddModuleUses: %d\n", err); 162 throw_exc(env, "Check #UI1: did not get expected JVMTI_ERROR_INVALID_MODULE for invalid module"); 163 return FAILED; 164 } 165 166 // Add invalid service (thisModule) to use to baseModule 167 printf("Check #UI2:\n"); 168 err = (*jvmti)->AddModuleUses(jvmti, baseModule, baseModule); 169 if (err != JVMTI_ERROR_INVALID_CLASS) { 170 printf("#UI2: jvmtiError from AddModuleUses: %d\n", err); 171 throw_exc(env, "Check #UI2: did not get expected JVMTI_ERROR_INVALID_CLASS for invalid service"); 172 return FAILED; 173 } 174 175 // Check if the service can not be used 176 printf("Check #UC1:\n"); 177 used = can_use_service(env, baseModule, service); 178 if (used != JNI_FALSE) { 179 throw_exc(env, "Check #UC1: unexpected use of service"); 180 return FAILED; 181 } 182 183 // Add uses of a correct service 184 printf("Check #UC2:\n"); 185 err = (*jvmti)->AddModuleUses(jvmti, baseModule, service); 186 if (err != JVMTI_ERROR_NONE) { 187 printf("#UC2: jvmtiError from AddModuleUses: %d\n", err); 188 throw_exc(env, "Check #UC2: got unexpected JVMTI error"); 189 return FAILED; 190 } 191 192 // Check if the service can not be used 193 printf("Check #UC3:\n"); 194 used = can_use_service(env, baseModule, service); 195 if (used == JNI_FALSE) { 196 throw_exc(env, "Check #UC3: service can not be used unexpectedly"); 197 return FAILED; 198 } 199 fflush(0); 200 return PASSED; 201} 202 203JNIEXPORT jint JNICALL 204Java_MyPackage_AddModuleUsesAndProvidesTest_checkProvides(JNIEnv *env, 205 jclass cls, 206 jobject baseModule, 207 jclass service, 208 jclass serviceImpl) { 209 jvmtiError err = JVMTI_ERROR_NONE; 210 jboolean provided = JNI_FALSE; 211 212 // Add provides to NULL module 213 printf("Check #PN1:\n"); 214 err = (*jvmti)->AddModuleProvides(jvmti, NULL, service, serviceImpl); 215 if (err != JVMTI_ERROR_NULL_POINTER) { 216 printf("#PN1: jvmtiError from AddModuleProvides: %d\n", err); 217 throw_exc(env, "Check #PN1: failed to return JVMTI_ERROR_NULL_POINTER for module==NULL"); 218 return FAILED; 219 } 220 221 // Add provides with NULL service 222 printf("Check #PN2:\n"); 223 err = (*jvmti)->AddModuleProvides(jvmti, baseModule, NULL, serviceImpl); 224 if (err != JVMTI_ERROR_NULL_POINTER) { 225 printf("#PN2: jvmtiError from AddModuleProvides: %d\n", err); 226 throw_exc(env, "Check #PN2: failed to return JVMTI_ERROR_NULL_POINTER for service==NULL"); 227 return FAILED; 228 } 229 230 // Add provides with NULL serviceImpl 231 printf("Check #PN3:\n"); 232 err = (*jvmti)->AddModuleProvides(jvmti, baseModule, service, NULL); 233 if (err != JVMTI_ERROR_NULL_POINTER) { 234 printf("#PN3: jvmtiError from AddModuleProvides: %d\n", err); 235 throw_exc(env, "Check #PN3: failed to return JVMTI_ERROR_NULL_POINTER for serviceImpl==NULL"); 236 return FAILED; 237 } 238 239 // Add provides to invalid module (cls) 240 printf("Check #PI1:\n"); 241 err = (*jvmti)->AddModuleProvides(jvmti, (jobject)cls, service, serviceImpl); 242 if (err != JVMTI_ERROR_INVALID_MODULE) { 243 printf("#PI1: jvmtiError from AddModuleProvides: %d\n", err); 244 throw_exc(env, "Check #PI1: did not get expected JVMTI_ERROR_INVALID_MODULE for invalid module"); 245 return FAILED; 246 } 247 248 // Add provides with invalid service (baseModule) 249 printf("Check #PI2:\n"); 250 err = (*jvmti)->AddModuleProvides(jvmti, baseModule, baseModule, serviceImpl); 251 if (err != JVMTI_ERROR_INVALID_CLASS) { 252 printf("#PI2: jvmtiError from AddModuleProvides: %d\n", err); 253 throw_exc(env, "Check #PI2: did not get expected JVMTI_ERROR_INVALID_CLASS for invalid service"); 254 return FAILED; 255 } 256 257 // Add provides with invalid serviceImpl (baseModule) 258 printf("Check #PI3:\n"); 259 err = (*jvmti)->AddModuleProvides(jvmti, baseModule, service, baseModule); 260 if (err != JVMTI_ERROR_INVALID_CLASS) { 261 printf("#PI3: jvmtiError from AddModuleProvides: %d\n", err); 262 throw_exc(env, "Check #PI3: did not get expected JVMTI_ERROR_INVALID_CLASS for invalid serviceImpl"); 263 return FAILED; 264 } 265 266 // Add provides to baseModule with correct service and serviceImpl 267 printf("Check #PC2:\n"); 268 err = (*jvmti)->AddModuleProvides(jvmti, baseModule, service, serviceImpl); 269 if (err != JVMTI_ERROR_NONE) { 270 printf("#PC2: jvmtiError from AddModuleExports: %d\n", err); 271 throw_exc(env, "Check #PC2: error in add provides to baseModule with correct service and serviceImpl"); 272 return FAILED; 273 } 274 fflush(0); 275 return PASSED; 276} 277 278#ifdef __cplusplus 279} 280#endif 281