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 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <jni.h>
27 #include <jvmti.h>
28 #include <aod.h>
29 #include <jvmti_aod.h>
30
31 extern "C" {
32
33 /*
34 * Expected agent work scenario:
35 * - receive ClassFileLoadHook event for class 'ClassToRedefine'
36 * - receive ClassLoad event for class 'ClassToRedefine' and redefine class from ClassLoad event handler
37 * - receive one more ClassFileLoadHook event for class 'ClassToRedefine'
38 * - receive ClassPrepare event for class 'ClassToRedefine' and finish work
39 */
40
41 #define REDEFINED_CLASS_NAME "Lnsk/jvmti/AttachOnDemand/attach002/ClassToRedefine;"
42 #define REDEFINED_CLASS_FILE_NAME "nsk/jvmti/AttachOnDemand/attach002/ClassToRedefine"
43
44 // class name in the ClassFileLoadHook callback
45 #define REDEFINED_CLASS_NAME_INTERNAL "nsk/jvmti/AttachOnDemand/attach002/ClassToRedefine"
46
47 static Options* options = NULL;
48 static const char* agentName;
49
50 static volatile jboolean agentGotCapabilities = JNI_FALSE;
51
52 static jvmtiEvent testEvents[] = {
53 JVMTI_EVENT_CLASS_LOAD,
54 JVMTI_EVENT_CLASS_PREPARE,
55 JVMTI_EVENT_CLASS_FILE_LOAD_HOOK};
56
57 static const int testEventsNumber = 3;
58
59 static volatile int classLoadReceived = 0;
60 static volatile int classFileLoadHookReceived = 0;
61
62 JNIEXPORT jboolean JNICALL
63 Java_nsk_jvmti_AttachOnDemand_attach002_attach002Target_agentGotCapabilities(JNIEnv * jni,
64 jclass klass, jobject obj) {
65 return agentGotCapabilities;
66 }
67
68 #define ATTACH002_TARGET_APP_CLASS_NAME "nsk/jvmti/AttachOnDemand/attach002/attach002Target"
69
70 int registerNativeMethods(JNIEnv* jni) {
71 jclass appClass;
72 JNINativeMethod nativeMethods[] = {
73 {(char*) "agentGotCapabilities", (char*) "()Z", (void*) Java_nsk_jvmti_AttachOnDemand_attach002_attach002Target_agentGotCapabilities}};
74 jint nativeMethodsNumber = 1;
75
76 appClass = jni->FindClass(ATTACH002_TARGET_APP_CLASS_NAME);
77 if (!NSK_JNI_VERIFY(jni, appClass != NULL)) {
78 return NSK_FALSE;
79 }
80
81 if (!NSK_JNI_VERIFY(jni,
82 (jni->RegisterNatives(appClass, nativeMethods, nativeMethodsNumber) == 0))) {
83 return NSK_FALSE;
84 }
85
86 return NSK_TRUE;
87 }
88
89 void JNICALL classLoadHandler(
90 jvmtiEnv *jvmti,
91 JNIEnv* jni,
92 jthread thread,
93 jclass klass) {
94 char className[MAX_STRING_LENGTH];
95
96 if (!nsk_jvmti_aod_getClassName(jvmti, klass, className)) {
97 nsk_jvmti_aod_disableEventsAndFinish(agentName, testEvents, testEventsNumber, 0, jvmti, jni);
98 return;
99 }
100
101 NSK_DISPLAY2("%s: ClassLoad event was received for class '%s'\n", agentName, className);
102
103 if (!strcmp(className, REDEFINED_CLASS_NAME)) {
104
105 classLoadReceived = 1;
106
184 {
185 jvmtiEventCallbacks eventCallbacks;
186 jvmtiCapabilities caps;
187 jvmtiEnv* jvmti = NULL;
188 JNIEnv* jni = NULL;
189
190 options = (Options*) nsk_aod_createOptions(optionsString);
191 if (!NSK_VERIFY(options != NULL))
192 return JNI_ERR;
193
194 agentName = nsk_aod_getOptionValue(options, NSK_AOD_AGENT_NAME_OPTION);
195
196 jni = (JNIEnv*) nsk_aod_createJNIEnv(vm);
197 if (jni == NULL)
198 return NSK_FALSE;
199
200 jvmti = nsk_jvmti_createJVMTIEnv(vm, reserved);
201 if (!NSK_VERIFY(jvmti != NULL))
202 return JNI_ERR;
203
204 if (!NSK_VERIFY(registerNativeMethods(jni))) {
205 return JNI_ERR;
206 }
207
208 memset(&caps, 0, sizeof(caps));
209 caps.can_generate_all_class_hook_events = 1;
210 caps.can_redefine_classes = 1;
211 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {
212 /*
213 * If VM is run with -Xshare:on agent can't get required capabilities (see 6718407)
214 */
215 NSK_DISPLAY1("%s: warning: agent failed to get required capabilities, agent finishing\n", agentName);
216
217 if (!NSK_VERIFY(nsk_aod_agentLoaded(jni, agentName)))
218 return JNI_ERR;
219
220 nsk_aod_agentFinished(jni, agentName, 1);
221 } else {
222 agentGotCapabilities = JNI_TRUE;
223
224 memset(&eventCallbacks,0, sizeof(eventCallbacks));
225 eventCallbacks.ClassLoad = classLoadHandler;
226 eventCallbacks.ClassPrepare = classPrepareHandler;
|
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 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <jni.h>
27 #include <jvmti.h>
28 #include <aod.h>
29 #include <jvmti_aod.h>
30 #include "ExceptionCheckingJniEnv.hpp"
31
32 extern "C" {
33
34 /*
35 * Expected agent work scenario:
36 * - receive ClassFileLoadHook event for class 'ClassToRedefine'
37 * - receive ClassLoad event for class 'ClassToRedefine' and redefine class from ClassLoad event handler
38 * - receive one more ClassFileLoadHook event for class 'ClassToRedefine'
39 * - receive ClassPrepare event for class 'ClassToRedefine' and finish work
40 */
41
42 #define REDEFINED_CLASS_NAME "Lnsk/jvmti/AttachOnDemand/attach002/ClassToRedefine;"
43 #define REDEFINED_CLASS_FILE_NAME "nsk/jvmti/AttachOnDemand/attach002/ClassToRedefine"
44
45 // class name in the ClassFileLoadHook callback
46 #define REDEFINED_CLASS_NAME_INTERNAL "nsk/jvmti/AttachOnDemand/attach002/ClassToRedefine"
47
48 static Options* options = NULL;
49 static const char* agentName;
50
51 static volatile jboolean agentGotCapabilities = JNI_FALSE;
52
53 static jvmtiEvent testEvents[] = {
54 JVMTI_EVENT_CLASS_LOAD,
55 JVMTI_EVENT_CLASS_PREPARE,
56 JVMTI_EVENT_CLASS_FILE_LOAD_HOOK};
57
58 static const int testEventsNumber = 3;
59
60 static volatile int classLoadReceived = 0;
61 static volatile int classFileLoadHookReceived = 0;
62
63 JNIEXPORT jboolean JNICALL
64 Java_nsk_jvmti_AttachOnDemand_attach002_attach002Target_agentGotCapabilities(JNIEnv * jni,
65 jclass klass, jobject obj) {
66 return agentGotCapabilities;
67 }
68
69 #define ATTACH002_TARGET_APP_CLASS_NAME "nsk/jvmti/AttachOnDemand/attach002/attach002Target"
70
71 void registerNativeMethods(JNIEnv* jni_env) {
72 ExceptionCheckingJniEnvPtr jni(jni_env);
73 jclass appClass;
74 JNINativeMethod nativeMethods[] = {
75 {(char*) "agentGotCapabilities", (char*) "()Z", (void*) Java_nsk_jvmti_AttachOnDemand_attach002_attach002Target_agentGotCapabilities}};
76 jint nativeMethodsNumber = 1;
77
78 appClass = jni->FindClass(ATTACH002_TARGET_APP_CLASS_NAME, TRACE_JNI_CALL);
79 jni->RegisterNatives(appClass, nativeMethods, nativeMethodsNumber, TRACE_JNI_CALL);
80 }
81
82 void JNICALL classLoadHandler(
83 jvmtiEnv *jvmti,
84 JNIEnv* jni,
85 jthread thread,
86 jclass klass) {
87 char className[MAX_STRING_LENGTH];
88
89 if (!nsk_jvmti_aod_getClassName(jvmti, klass, className)) {
90 nsk_jvmti_aod_disableEventsAndFinish(agentName, testEvents, testEventsNumber, 0, jvmti, jni);
91 return;
92 }
93
94 NSK_DISPLAY2("%s: ClassLoad event was received for class '%s'\n", agentName, className);
95
96 if (!strcmp(className, REDEFINED_CLASS_NAME)) {
97
98 classLoadReceived = 1;
99
177 {
178 jvmtiEventCallbacks eventCallbacks;
179 jvmtiCapabilities caps;
180 jvmtiEnv* jvmti = NULL;
181 JNIEnv* jni = NULL;
182
183 options = (Options*) nsk_aod_createOptions(optionsString);
184 if (!NSK_VERIFY(options != NULL))
185 return JNI_ERR;
186
187 agentName = nsk_aod_getOptionValue(options, NSK_AOD_AGENT_NAME_OPTION);
188
189 jni = (JNIEnv*) nsk_aod_createJNIEnv(vm);
190 if (jni == NULL)
191 return NSK_FALSE;
192
193 jvmti = nsk_jvmti_createJVMTIEnv(vm, reserved);
194 if (!NSK_VERIFY(jvmti != NULL))
195 return JNI_ERR;
196
197 registerNativeMethods(jni);
198
199 memset(&caps, 0, sizeof(caps));
200 caps.can_generate_all_class_hook_events = 1;
201 caps.can_redefine_classes = 1;
202 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {
203 /*
204 * If VM is run with -Xshare:on agent can't get required capabilities (see 6718407)
205 */
206 NSK_DISPLAY1("%s: warning: agent failed to get required capabilities, agent finishing\n", agentName);
207
208 if (!NSK_VERIFY(nsk_aod_agentLoaded(jni, agentName)))
209 return JNI_ERR;
210
211 nsk_aod_agentFinished(jni, agentName, 1);
212 } else {
213 agentGotCapabilities = JNI_TRUE;
214
215 memset(&eventCallbacks,0, sizeof(eventCallbacks));
216 eventCallbacks.ClassLoad = classLoadHandler;
217 eventCallbacks.ClassPrepare = classPrepareHandler;
|