1 /* 2 * Copyright (c) 2007, 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. 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 Periodically hotswap class(es) with a changed version in 25 asynchronous manner from specified number of JVMTI agents. The VM 26 works in default mode. 27 */ 28 #include <jni.h> 29 #include <jvmti.h> 30 #include "agent_common.h" 31 #include <string.h> 32 #include "jni_tools.h" 33 #include "jvmti_tools.h" 34 #include "JVMTITools.h" 35 36 extern "C" { 37 38 #define FILE_NAME "nsk/jvmti/scenarios/hotswap/HS103/hs103t002/MyThread" 39 #define SEARCH_NAME "nsk/jvmti/scenarios/hotswap/HS103/hs103t002/MyThread" 40 #define MAIN_CLASS "nsk/jvmti/scenarios/hotswap/HS103/hs103t002/hs103t002" 41 42 static jvmtiEnv * jvmti; 43 static jthread testAgentThread; 44 45 JNIEXPORT void JNICALL doRedefineInNativeThread(jvmtiEnv * jvmti, 46 JNIEnv * jni, void * arg) { 47 jclass cla; 48 int i = 0; 49 int redefineNumber = 0; 50 char fileName[512]; 51 52 jclass testClass; 53 54 jmethodID setRedefinitionDone; 55 jmethodID setRedefinitionFailed; 56 57 testClass = jni->FindClass(MAIN_CLASS); 58 59 if (!NSK_JNI_VERIFY(jni, ( 60 setRedefinitionFailed = NSK_CPP_STUB4(GetStaticMethodID, jni, 61 testClass, "setRedefinitionFailed", "()V")) != NULL)) 62 { 63 NSK_CPP_STUB2(FatalError, jni, 64 "TEST FAILED: while getting setRedefinitionFailed()\n"); 65 } 66 67 if (!NSK_JNI_VERIFY(jni, ( 68 setRedefinitionDone = NSK_CPP_STUB4(GetStaticMethodID, jni, 69 testClass, "setRedefinitionDone", "()V")) != NULL)) 70 { 71 NSK_CPP_STUB2(FatalError, jni, 72 "TEST FAILED: while getting setRedefinitionDone()\n"); 73 } 74 75 nsk_printf("doRedefineInNativeThread\n"); 76 cla = jni->FindClass(SEARCH_NAME); 77 nsk_jvmti_getFileName(redefineNumber, FILE_NAME, fileName, sizeof(fileName)/sizeof(char)); 78 for(i = 0; i < 30; i++) { 79 nsk_printf(" Inside the redefine method..\n"); 80 if ( nsk_jvmti_redefineClass(jvmti, cla,fileName) == NSK_TRUE) { 81 nsk_printf("\nMyClass :: Successfully redefined..\n"); 82 } else { 83 nsk_printf("\nMyClass :: Failed to redefine ..\n"); 84 85 if (!NSK_JNI_VERIFY_VOID(jni, NSK_CPP_STUB3(CallStaticVoidMethod, jni, 86 testClass, setRedefinitionFailed))) 87 { 88 NSK_CPP_STUB2(FatalError, jni, 89 "TEST FAILED: while calling setRedefinitionFailed()\n"); 90 } 91 } 92 } 93 94 if (!NSK_JNI_VERIFY_VOID(jni, NSK_CPP_STUB3(CallStaticVoidMethod, jni, 95 testClass, setRedefinitionDone))) 96 { 97 NSK_CPP_STUB2(FatalError, jni, 98 "TEST FAILED: while calling setRedefinitionDone()\n"); 99 } 100 101 nsk_printf(" All 30 redefinitions are done..\n"); 102 } 103 104 105 #ifdef STATIC_BUILD 106 JNIEXPORT jint JNICALL Agent_OnLoad_hs103t002(JavaVM *jvm, char *options, void *reserved) { 107 return Agent_Initialize(jvm, options, reserved); 108 } 109 JNIEXPORT jint JNICALL Agent_OnAttach_hs103t002(JavaVM *jvm, char *options, void *reserved) { 110 return Agent_Initialize(jvm, options, reserved); 111 } 112 JNIEXPORT jint JNI_OnLoad_hs103t002(JavaVM *jvm, char *options, void *reserved) { 113 return JNI_VERSION_1_8; 114 } 115 #endif 116 117 jint Agent_Initialize(JavaVM *vm, char *options, void *reserved) { 118 jint rc; 119 120 nsk_printf("Agent:: VM.. Started..\n"); 121 122 rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION_1_1); 123 if (rc != JNI_OK ) { 124 nsk_printf("Agent:: Could not load JVMTI interface \n"); 125 return JNI_ERR; 126 } else { 127 jvmtiCapabilities caps; 128 if (nsk_jvmti_parseOptions(options) == NSK_FALSE ) { 129 nsk_printf("# error agent Failed to parse options \n"); 130 return JNI_ERR; 131 } 132 memset(&caps, 0, sizeof(caps)); 133 caps.can_redefine_classes = 1; 134 jvmti->AddCapabilities(&caps); 135 } 136 return JNI_OK; 137 } 138 139 JNIEXPORT jboolean JNICALL 140 Java_nsk_jvmti_scenarios_hotswap_HS103_hs103t002_hs103t002_startAgentThread(JNIEnv * jni, jclass cls) { 141 jvmtiError err ; 142 jthread thread; 143 jclass clas; 144 jmethodID method; 145 const char * threadName = "Agent Thread"; 146 jobject name; 147 148 nsk_printf("hs103t002_startAgentThread\n"); 149 150 name = jni->NewStringUTF(threadName); 151 clas = jni->FindClass("java/lang/Thread"); 152 153 if (!NSK_JNI_VERIFY(jni, (method = NSK_CPP_STUB4(GetMethodID, 154 jni, clas, "<init>","(Ljava/lang/String;)V")) != NULL)) { 155 NSK_CPP_STUB2(FatalError, jni, 156 "failed to get ID for the java method\n"); 157 } 158 159 thread = (jthread) jni->NewObject(clas,method,name); 160 testAgentThread = jni->NewGlobalRef(thread); 161 err = JVMTI_ERROR_NONE; 162 err = jvmti->RunAgentThread(testAgentThread, &doRedefineInNativeThread, NULL, 163 JVMTI_THREAD_NORM_PRIORITY); 164 if (err == JVMTI_ERROR_INVALID_PRIORITY) { 165 nsk_printf(" JVMTI_ERROR_INVALID_PRIORITY ..\n"); 166 return JNI_ERR; 167 } else if ( err == JVMTI_ERROR_INVALID_THREAD) { 168 nsk_printf(" JVMTI_ERROR_INVALID_THREAD ..\n"); 169 return JNI_ERR; 170 } else if (err == JVMTI_ERROR_NULL_POINTER) { 171 nsk_printf(" JVMTI_ERROR_NULL_POINTER ..\n"); 172 return JNI_ERR; 173 } else { 174 nsk_printf(" Agent Thread Created.. \n"); 175 } 176 return JNI_OK; 177 } 178 179 }