mirror of
https://github.com/darlinghq/darling-openjdk.git
synced 2024-11-26 22:00:25 +00:00
8233091: Backout JDK-8212117: Class.forName loads a class but not linked if class is not initialized
Reviewed-by: alanb, dholmes, mchung
This commit is contained in:
parent
691e75e223
commit
3561b4ed50
@ -148,7 +148,6 @@ JVM_IsSupportedJNIVersion
|
||||
JVM_IsThreadAlive
|
||||
JVM_IsVMGeneratedMethodIx
|
||||
JVM_LatestUserDefinedLoader
|
||||
JVM_LinkClass
|
||||
JVM_LoadLibrary
|
||||
JVM_MaxMemory
|
||||
JVM_MaxObjectInspectionAge
|
||||
|
@ -346,11 +346,6 @@ JVM_GetCallerClass(JNIEnv *env);
|
||||
JNIEXPORT jclass JNICALL
|
||||
JVM_FindPrimitiveClass(JNIEnv *env, const char *utf);
|
||||
|
||||
/*
|
||||
* Link the 'arg' class
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_LinkClass(JNIEnv *env, jclass classClass, jclass arg);
|
||||
|
||||
/*
|
||||
* Find a class from a boot class loader. Returns NULL if class not found.
|
||||
|
@ -419,7 +419,7 @@ JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
|
||||
}
|
||||
|
||||
TempNewSymbol sym = SymbolTable::new_symbol(name);
|
||||
result = find_class_from_class_loader(env, sym, true, true, loader,
|
||||
result = find_class_from_class_loader(env, sym, true, loader,
|
||||
protection_domain, true, thread);
|
||||
|
||||
if (log_is_enabled(Debug, class, resolve) && result != NULL) {
|
||||
@ -3208,7 +3208,7 @@ static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {
|
||||
Handle protection_domain; // null protection domain
|
||||
|
||||
TempNewSymbol sym = SymbolTable::new_symbol(name);
|
||||
jclass result = find_class_from_class_loader(env, sym, true, true, loader, protection_domain, true, CHECK_NULL);
|
||||
jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
|
||||
|
||||
if (log_is_enabled(Debug, class, resolve) && result != NULL) {
|
||||
trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
|
||||
|
@ -742,17 +742,6 @@ JVM_END
|
||||
// Misc. class handling ///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
JVM_ENTRY(void, JVM_LinkClass(JNIEnv* env, jclass classClass, jclass arg))
|
||||
JVMWrapper("JVM_LinkClass");
|
||||
|
||||
oop r = JNIHandles::resolve(arg);
|
||||
Klass* klass = java_lang_Class::as_Klass(r);
|
||||
|
||||
if (!ClassForNameDeferLinking && klass->is_instance_klass()) {
|
||||
InstanceKlass::cast(klass)->link_class(CHECK);
|
||||
}
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env))
|
||||
JVMWrapper("JVM_GetCallerClass");
|
||||
|
||||
@ -863,10 +852,9 @@ JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name,
|
||||
|
||||
Handle h_loader(THREAD, loader_oop);
|
||||
Handle h_prot(THREAD, protection_domain);
|
||||
|
||||
jboolean link = !ClassForNameDeferLinking;
|
||||
jclass result = find_class_from_class_loader(env, h_name, init, link, h_loader,
|
||||
jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
|
||||
h_prot, false, THREAD);
|
||||
|
||||
if (log_is_enabled(Debug, class, resolve) && result != NULL) {
|
||||
trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
|
||||
}
|
||||
@ -903,7 +891,7 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
|
||||
}
|
||||
Handle h_loader(THREAD, class_loader);
|
||||
Handle h_prot (THREAD, protection_domain);
|
||||
jclass result = find_class_from_class_loader(env, h_name, init, false, h_loader,
|
||||
jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
|
||||
h_prot, true, thread);
|
||||
|
||||
if (log_is_enabled(Debug, class, resolve) && result != NULL) {
|
||||
@ -3410,12 +3398,9 @@ JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) {
|
||||
|
||||
// Shared JNI/JVM entry points //////////////////////////////////////////////////////////////
|
||||
|
||||
jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, jboolean link,
|
||||
jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init,
|
||||
Handle loader, Handle protection_domain,
|
||||
jboolean throwError, TRAPS) {
|
||||
// Initialization also implies linking - check for coherent args
|
||||
assert((init && link) || !init, "incorrect use of init/link arguments");
|
||||
|
||||
// Security Note:
|
||||
// The Java level wrapper will perform the necessary security check allowing
|
||||
// us to pass the NULL as the initiating class loader. The VM is responsible for
|
||||
@ -3424,11 +3409,9 @@ jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, jb
|
||||
// if there is no security manager in 3-arg Class.forName().
|
||||
Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL);
|
||||
|
||||
// Check if we should initialize the class (which implies linking), or just link it
|
||||
// Check if we should initialize the class
|
||||
if (init && klass->is_instance_klass()) {
|
||||
klass->initialize(CHECK_NULL);
|
||||
} else if (link && klass->is_instance_klass()) {
|
||||
InstanceKlass::cast(klass)->link_class(CHECK_NULL);
|
||||
}
|
||||
return (jclass) JNIHandles::make_local(env, klass->java_mirror());
|
||||
}
|
||||
|
@ -31,8 +31,7 @@
|
||||
// Useful entry points shared by JNI and JVM interface.
|
||||
// We do not allow real JNI or JVM entry point to call each other.
|
||||
|
||||
jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, jboolean link,
|
||||
Handle loader, Handle protection_domain, jboolean throwError, TRAPS);
|
||||
jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS);
|
||||
|
||||
void trace_class_resolution(Klass* to_class);
|
||||
|
||||
|
@ -2223,9 +2223,6 @@ const size_t minimumSymbolTableSize = 1024;
|
||||
"Maximum total size of NIO direct-buffer allocations") \
|
||||
range(0, max_jlong) \
|
||||
\
|
||||
product(bool, ClassForNameDeferLinking, false, \
|
||||
"Revert to not linking in Class.forName()") \
|
||||
\
|
||||
/* Flags used for temporary code during development */ \
|
||||
\
|
||||
diagnostic(bool, UseNewCode, false, \
|
||||
|
@ -392,10 +392,6 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @see java.lang.Class#forName(String)
|
||||
* @see java.lang.ClassLoader
|
||||
*
|
||||
* @jls 12.2 Loading of Classes and Interfaces
|
||||
* @jls 12.3 Linking of Classes and Interfaces
|
||||
* @jls 12.4 Initialization of Classes and Interfaces
|
||||
* @since 1.2
|
||||
*/
|
||||
@CallerSensitive
|
||||
@ -442,10 +438,6 @@ public final class Class<T> implements java.io.Serializable,
|
||||
* <p> This method does not check whether the requested class is
|
||||
* accessible to its caller. </p>
|
||||
*
|
||||
* <p> Note that this method throws errors related to loading and linking as
|
||||
* specified in Sections 12.2 and 12.3 of <em>The Java Language
|
||||
* Specification</em>.
|
||||
*
|
||||
* @apiNote
|
||||
* This method returns {@code null} on failure rather than
|
||||
* throwing a {@link ClassNotFoundException}, as is done by
|
||||
@ -473,8 +465,6 @@ public final class Class<T> implements java.io.Serializable,
|
||||
* in a module.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @jls 12.2 Loading of Classes and Interfaces
|
||||
* @jls 12.3 Linking of Classes and Interfaces
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
@ -498,21 +488,13 @@ public final class Class<T> implements java.io.Serializable,
|
||||
cl = module.getClassLoader();
|
||||
}
|
||||
|
||||
Class<?> ret;
|
||||
if (cl != null) {
|
||||
ret = cl.loadClass(module, name);
|
||||
return cl.loadClass(module, name);
|
||||
} else {
|
||||
ret = BootLoader.loadClass(module, name);
|
||||
return BootLoader.loadClass(module, name);
|
||||
}
|
||||
if (ret != null) {
|
||||
// The loaded class should also be linked
|
||||
linkClass(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static native void linkClass(Class<?> c);
|
||||
|
||||
/**
|
||||
* Creates a new instance of the class represented by this {@code Class}
|
||||
* object. The class is instantiated as if by a {@code new}
|
||||
|
@ -1933,17 +1933,12 @@ assertEquals("[x, y, z]", pb.command().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a class by name from the lookup context defined by this {@code Lookup} object.
|
||||
* This method attempts to locate, load, and link the class, and then determines whether
|
||||
* the class is accessible to this {@code Lookup} object. The static
|
||||
* Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
|
||||
* initializer of the class is not run.
|
||||
* <p>
|
||||
* The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
|
||||
* loader, and the {@linkplain #lookupModes() lookup modes}.
|
||||
* <p>
|
||||
* Note that this method throws errors related to loading and linking as
|
||||
* specified in Sections 12.2 and 12.3 of <em>The Java Language
|
||||
* Specification</em>.
|
||||
* loader, and the {@linkplain #lookupModes() lookup modes}. In particular, the method first attempts to
|
||||
* load the requested class, and then determines whether the class is accessible to this lookup object.
|
||||
*
|
||||
* @param targetName the fully qualified name of the class to be looked up.
|
||||
* @return the requested class.
|
||||
@ -1955,9 +1950,6 @@ assertEquals("[x, y, z]", pb.command().toString());
|
||||
* modes.
|
||||
* @throws SecurityException if a security manager is present and it
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
*
|
||||
* @jls 12.2 Loading of Classes and Interfaces
|
||||
* @jls 12.3 Linking of Classes and Interfaces
|
||||
* @since 9
|
||||
*/
|
||||
public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {
|
||||
|
@ -62,7 +62,6 @@ import java.nio.charset.Charset;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessControlException;
|
||||
import java.text.Normalizer;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
@ -725,9 +724,6 @@ public final class LauncherHelper {
|
||||
} catch (LinkageError le) {
|
||||
abort(null, "java.launcher.module.error3", mainClass, m.getName(),
|
||||
le.getClass().getName() + ": " + le.getLocalizedMessage());
|
||||
} catch (AccessControlException ace) {
|
||||
abort(ace, "java.launcher.module.error5", mainClass, m.getName(),
|
||||
ace.getClass().getName(), ace.getLocalizedMessage());
|
||||
}
|
||||
if (c == null) {
|
||||
abort(null, "java.launcher.module.error2", mainClass, mainModule);
|
||||
@ -784,9 +780,6 @@ public final class LauncherHelper {
|
||||
} catch (LinkageError le) {
|
||||
abort(le, "java.launcher.cls.error6", cn,
|
||||
le.getClass().getName() + ": " + le.getLocalizedMessage());
|
||||
} catch (AccessControlException ace) {
|
||||
abort(ace, "java.launcher.cls.error7", cn,
|
||||
ace.getClass().getName(), ace.getLocalizedMessage());
|
||||
}
|
||||
return mainClass;
|
||||
}
|
||||
|
@ -73,7 +73,6 @@ static JNINativeMethod methods[] = {
|
||||
{"getRawTypeAnnotations", "()" BA, (void *)&JVM_GetClassTypeAnnotations},
|
||||
{"getNestHost0", "()" CLS, (void *)&JVM_GetNestHost},
|
||||
{"getNestMembers0", "()[" CLS, (void *)&JVM_GetNestMembers},
|
||||
{"linkClass", "(" CLS ")V", (void *)&JVM_LinkClass},
|
||||
};
|
||||
|
||||
#undef OBJ
|
||||
|
@ -130,7 +130,7 @@ public class TestMetaSpaceLog {
|
||||
public static void loadClass(WhiteBox wb) {
|
||||
try {
|
||||
URLClassLoader ucl = new URLClassLoader(urls);
|
||||
ucl.loadClass("case00");
|
||||
Class.forName("case00", false, ucl);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8212117
|
||||
* @summary Verify JVMTI GetClassStatus returns CLASS_PREPARE after call to Class.forName()
|
||||
* @run main/othervm/native -agentlib:ClassStatus ClassStatus
|
||||
*/
|
||||
|
||||
|
||||
public class ClassStatus {
|
||||
static {
|
||||
try {
|
||||
System.out.println("ClassStatus static block");
|
||||
System.loadLibrary("ClassStatus");
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
System.err.println("Could not load ClassStatus library");
|
||||
System.err.println("java.library.path: "
|
||||
+ System.getProperty("java.library.path"));
|
||||
throw ule;
|
||||
}
|
||||
}
|
||||
|
||||
static native int check(Class klass);
|
||||
|
||||
public static void main(String[] args) throws ClassNotFoundException {
|
||||
ClassLoader loader = ClassStatus.class.getClassLoader();
|
||||
Module module = loader.getUnnamedModule();
|
||||
|
||||
// Load class, but don't initialize it
|
||||
Class foo2 = Class.forName(module, "Foo2");
|
||||
Class foo3 = Class.forName("Foo3", false, loader);
|
||||
|
||||
System.out.println("Loaded: " + foo2);
|
||||
System.out.println("Loaded: " + foo3);
|
||||
|
||||
int status2 = check(foo2);
|
||||
int status3 = check(foo3);
|
||||
|
||||
new Foo2().bar();
|
||||
new Foo3().bar();
|
||||
|
||||
if (status2 != 0) {
|
||||
System.out.println("The agent returned non-zero exit status for Foo2: " + status2);
|
||||
}
|
||||
if (status3 != 0) {
|
||||
System.out.println("The agent returned non-zero exit status for Foo3: " + status3);
|
||||
}
|
||||
if (status2 != 0 || status3 != 0) {
|
||||
throw new RuntimeException("Non-zero status returned from the agent");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Foo2 {
|
||||
static {
|
||||
System.out.println("Foo2 is initialized");
|
||||
}
|
||||
void bar() {
|
||||
System.out.println("Foo2.bar() is called");
|
||||
}
|
||||
}
|
||||
|
||||
class Foo3 {
|
||||
static {
|
||||
System.out.println("Foo3 is initialized");
|
||||
}
|
||||
void bar() {
|
||||
System.out.println("Foo3.bar() is called");
|
||||
}
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jvmti.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef JNI_ENV_ARG
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define JNI_ENV_ARG(x, y) y
|
||||
#define JNI_ENV_PTR(x) x
|
||||
#else
|
||||
#define JNI_ENV_ARG(x,y) x, y
|
||||
#define JNI_ENV_PTR(x) (*x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define PASSED 0
|
||||
#define FAILED 2
|
||||
|
||||
static jvmtiEnv* jvmti = NULL;
|
||||
|
||||
static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
|
||||
return Agent_Initialize(jvm, options, reserved);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
|
||||
return Agent_Initialize(jvm, options, reserved);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
JNI_OnLoad(JavaVM *jvm, void *reserved) {
|
||||
return JNI_VERSION_9;
|
||||
}
|
||||
|
||||
static void
|
||||
check_jvmti_error(jvmtiEnv *jvmti, char* fname, jvmtiError err) {
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
printf(" ## %s error: %d\n", fname, err);
|
||||
fflush(0);
|
||||
exit(err);
|
||||
}
|
||||
}
|
||||
|
||||
static char*
|
||||
get_class_signature(jvmtiEnv *jvmti, jclass klass) {
|
||||
char* sign = NULL;
|
||||
jvmtiError err = (*jvmti)->GetClassSignature(jvmti, klass, &sign, NULL);
|
||||
|
||||
check_jvmti_error(jvmti, "GetClassSignature", err);
|
||||
return sign;
|
||||
}
|
||||
|
||||
static jboolean
|
||||
is_class_status_prepared(jvmtiEnv *jvmti, jclass klass) {
|
||||
char* sign = get_class_signature(jvmti, klass);
|
||||
jint status = 0;
|
||||
jvmtiError err = (*jvmti)->GetClassStatus(jvmti, klass, &status);
|
||||
|
||||
check_jvmti_error(jvmti, "GetClassStatus", err);
|
||||
printf(" Class %s status: 0x%08x\n", sign, status);
|
||||
printf(" Class %s is prepared: %d\n", sign, (status & JVMTI_CLASS_STATUS_PREPARED) != 0);
|
||||
fflush(0);
|
||||
|
||||
return (status & JVMTI_CLASS_STATUS_PREPARED) != 0;
|
||||
}
|
||||
|
||||
static jboolean
|
||||
is_class_in_loaded_classes(JNIEnv *env, jclass klass) {
|
||||
char* sign = get_class_signature(jvmti, klass);
|
||||
jint class_count = 0;
|
||||
jclass* classes = NULL;
|
||||
jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &class_count, &classes);
|
||||
|
||||
check_jvmti_error(jvmti, "GetLoadedClasses", err);
|
||||
|
||||
for (int i = 0; i < class_count; i++) {
|
||||
jclass cls = classes[i];
|
||||
jboolean same = (*env)->IsSameObject(env, cls, klass);
|
||||
if (same) {
|
||||
printf("Found class %s in the list of loaded classes\n", sign);
|
||||
fflush(0);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
}
|
||||
printf("Error: Have not found class %s in the list of loaded classes\n", sign);
|
||||
fflush(0);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
static void JNICALL
|
||||
ClassPrepare(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jclass klass) {
|
||||
char* sign = get_class_signature(jvmti, klass);
|
||||
|
||||
sign = (sign == NULL) ? "NULL" : sign;
|
||||
|
||||
if (strcmp(sign, "LFoo2;") == 0 || strcmp(sign, "LFoo3;") == 0) {
|
||||
printf("ClassPrepare event for class: %s\n", sign);
|
||||
fflush(0);
|
||||
}
|
||||
}
|
||||
|
||||
static jint
|
||||
Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
|
||||
jvmtiError err;
|
||||
jint size;
|
||||
jint res;
|
||||
jvmtiEventCallbacks callbacks;
|
||||
|
||||
printf("Agent_Initialize started\n");
|
||||
fflush(0);
|
||||
res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), JVMTI_VERSION_9);
|
||||
if (res != JNI_OK || jvmti == NULL) {
|
||||
printf("## Agent_Initialize: Error in GetEnv: res: %d, jvmti env: %p\n", res, jvmti);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
size = (jint)sizeof(callbacks);
|
||||
memset(&callbacks, 0, size);
|
||||
callbacks.ClassPrepare = ClassPrepare;
|
||||
|
||||
err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size);
|
||||
check_jvmti_error(jvmti, "## Agent_Initialize: SetEventCallbacks", err);
|
||||
|
||||
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL);
|
||||
check_jvmti_error(jvmti, "## Agent_Initialize: SetEventNotificationMode CLASS_PREPARE", err);
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_ClassStatus_check(JNIEnv *env, jclass cls, jclass klass) {
|
||||
if (is_class_in_loaded_classes(env, klass) != JNI_TRUE ||
|
||||
is_class_status_prepared(jvmti, klass) != JNI_TRUE) {
|
||||
return FAILED;
|
||||
}
|
||||
return PASSED;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user