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 = jni->GetStaticMethodID(testClass, "setRedefinitionFailed", "()V")) != NULL)) 61 { 62 jni->FatalError("TEST FAILED: while getting setRedefinitionFailed()\n"); 63 } 64 65 if (!NSK_JNI_VERIFY(jni, ( 66 setRedefinitionDone = jni->GetStaticMethodID(testClass, "setRedefinitionDone", "()V")) != NULL)) 67 { 68 jni->FatalError("TEST FAILED: while getting setRedefinitionDone()\n"); 69 } 70 71 nsk_printf("doRedefineInNativeThread\n"); 72 cla = jni->FindClass(SEARCH_NAME); 73 nsk_jvmti_getFileName(redefineNumber, FILE_NAME, fileName, sizeof(fileName)/sizeof(char)); 74 for(i = 0; i < 30; i++) { 75 nsk_printf(" Inside the redefine method..\n"); 76 if ( nsk_jvmti_redefineClass(jvmti, cla,fileName) == NSK_TRUE) { 77 nsk_printf("\nMyClass :: Successfully redefined..\n"); 78 } else { 79 nsk_printf("\nMyClass :: Failed to redefine ..\n"); 80 81 if (!NSK_JNI_VERIFY_VOID(jni, jni->CallStaticVoidMethod(testClass, setRedefinitionFailed))) 82 { 83 jni->FatalError("TEST FAILED: while calling setRedefinitionFailed()\n"); 84 } 85 } 86 } 87 88 if (!NSK_JNI_VERIFY_VOID(jni, jni->CallStaticVoidMethod(testClass, setRedefinitionDone))) 89 { 90 jni->FatalError("TEST FAILED: while calling setRedefinitionDone()\n"); 91 } 92 93 nsk_printf(" All 30 redefinitions are done..\n"); 94 } 95 96 97 #ifdef STATIC_BUILD 98 JNIEXPORT jint JNICALL Agent_OnLoad_hs103t002(JavaVM *jvm, char *options, void *reserved) { 99 return Agent_Initialize(jvm, options, reserved); 100 } 101 JNIEXPORT jint JNICALL Agent_OnAttach_hs103t002(JavaVM *jvm, char *options, void *reserved) { 102 return Agent_Initialize(jvm, options, reserved); 103 } 104 JNIEXPORT jint JNI_OnLoad_hs103t002(JavaVM *jvm, char *options, void *reserved) { 105 return JNI_VERSION_1_8; 106 } 107 #endif 108 109 jint Agent_Initialize(JavaVM *vm, char *options, void *reserved) { 110 jint rc; 111 112 nsk_printf("Agent:: VM.. Started..\n"); 113 114 rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION_1_1); 115 if (rc != JNI_OK ) { 116 nsk_printf("Agent:: Could not load JVMTI interface \n"); 117 return JNI_ERR; 118 } else { 119 jvmtiCapabilities caps; 120 if (nsk_jvmti_parseOptions(options) == NSK_FALSE ) { 121 nsk_printf("# error agent Failed to parse options \n"); 122 return JNI_ERR; 123 } 124 memset(&caps, 0, sizeof(caps)); 125 caps.can_redefine_classes = 1; 126 jvmti->AddCapabilities(&caps); 127 } 128 return JNI_OK; 129 } 130 131 JNIEXPORT jboolean JNICALL 132 Java_nsk_jvmti_scenarios_hotswap_HS103_hs103t002_hs103t002_startAgentThread(JNIEnv * jni, jclass cls) { 133 jvmtiError err ; 134 jthread thread; 135 jclass clas; 136 jmethodID method; 137 const char * threadName = "Agent Thread"; 138 jobject name; 139 140 nsk_printf("hs103t002_startAgentThread\n"); 141 142 name = jni->NewStringUTF(threadName); 143 clas = jni->FindClass("java/lang/Thread"); 144 145 if (!NSK_JNI_VERIFY(jni, (method = jni->GetMethodID(clas, "<init>", "(Ljava/lang/String;)V")) != NULL)) { 146 jni->FatalError("failed to get ID for the java method\n"); 147 } 148 149 thread = (jthread) jni->NewObject(clas,method,name); 150 testAgentThread = jni->NewGlobalRef(thread); 151 err = JVMTI_ERROR_NONE; 152 err = jvmti->RunAgentThread(testAgentThread, &doRedefineInNativeThread, NULL, 153 JVMTI_THREAD_NORM_PRIORITY); 154 if (err == JVMTI_ERROR_INVALID_PRIORITY) { 155 nsk_printf(" JVMTI_ERROR_INVALID_PRIORITY ..\n"); 156 return JNI_ERR; 157 } else if ( err == JVMTI_ERROR_INVALID_THREAD) { 158 nsk_printf(" JVMTI_ERROR_INVALID_THREAD ..\n"); 159 return JNI_ERR; 160 } else if (err == JVMTI_ERROR_NULL_POINTER) { 161 nsk_printf(" JVMTI_ERROR_NULL_POINTER ..\n"); 162 return JNI_ERR; 163 } else { 164 nsk_printf(" Agent Thread Created.. \n"); 165 } 166 return JNI_OK; 167 } 168 169 }