How to get an object instance of a class

How to get an object instance of a Java class? This class is not necessarily a singleton, nor does it necessarily provide static methods, nor is it necessarily managed by Spring. How can we obtain all object instances of this class when its source code cannot even be modified? Here is an implementation method based on JVMTI.

Instructions for use

First quote maven dependencies

<dependency>
   <groupId>io.github.liubsyy</groupId>
  <artifactId>FindInstancesOfClass</artifactId>
   <version>1.0.1</version>
</dependency>

Then directly call the function  InstancesOfClass.getInstances(Class<?> targetClass)  to get all object instances of a class

public class InstancesOfClass {
    /**
     * native方法 : 返回所有的实例对象
     * @param targetClass 需要查询实例的Class
     * @return
     */
    public static native Object[] getInstances(Class<?> targetClass);
}

Implementation principle

There is no interface for obtaining instances based on classes in Java. You need to use the JVMTI interfaces IterateOverInstancesOfClass and GetObjectsWithTags.

First write a class containing native methods

public class InstancesOfClass {
    /**
     * native方法 : 返回所有的实例对象
     * @param targetClass 需要查询实例的Class
     * @return
     */
    public static native Object[] getInstances(Class<?> targetClass);
}

Then use javah to generate the .h file, and then use C++ to write the implementation part.

#include <jni.h>
#include <jvmti.h>
#include "com_liubs_findinstances_jvmti_InstancesOfClass.h"


static jvmtiIterationControl JNICALL objectInstanceCallback(jlong class_tag, jlong size, jlong* tag_ptr, void* user_data) {
    *tag_ptr = 1;
    return JVMTI_ITERATION_CONTINUE;
}

JNIEXPORT jobjectArray JNICALL Java_com_liubs_findinstances_jvmti_InstancesOfClass_getInstances(JNIEnv* env, jclass clazz, jclass targetClazz) {
    JavaVM* vm;
    env->GetJavaVM(&vm);

    jvmtiEnv* jvmti;
    vm->GetEnv((void**)&jvmti, JVMTI_VERSION_1_0);

    jvmtiCapabilities capabilities = {0};
    capabilities.can_tag_objects = 1;
    jvmti->AddCapabilities(&capabilities);

    jvmti->IterateOverInstancesOfClass(targetClazz, JVMTI_HEAP_OBJECT_EITHER,
                                       objectInstanceCallback, NULL);

    jlong tag = 1;
    jint count;
    jobject* instances;
    jvmti->GetObjectsWithTags(1, &tag, &count, &instances, NULL);

    printf("Found %d objects with tag\n", count);

    // 转换jobject* 为 jobjectArray 并返回
    jobjectArray result = env->NewObjectArray(count, targetClazz, NULL);
    for (int i = 0; i < count; i++) {
        env->SetObjectArrayElement(result, i, instances[i]);
    }

    jvmti->Deallocate((unsigned char*)instances);
    return result;
}

 

Then use gcc/g++ to compile the cpp source code to generate the corresponding dynamic link library files under linux/mac/windows. so, .dylib and .dll, load the corresponding local link library through System.load(), and finally call InstancesOfClass.getInstances(Class <?> targetClass)  method.

For detailed source code, please see  https://github.com/Liubsyy/FindInstancesOfClass , which contains test cases.

 

 

 

 

Lei Jun announced the complete system architecture of Xiaomi's ThePaper OS, saying that the bottom layer has been completely restructured. Yuque announced the cause of the failure and repair process on October 23. Microsoft CEO Nadella: Abandoning Windows Phone and mobile business was a wrong decision. Both Java 11 and Java 17 usage rates exceeded Java 8 Hugging Face was restricted from accessing. Yuque network outage lasted for about 10 hours and has now returned to normal. The National Data Administration officially unveiled Oracle. Launched Java development extension for Visual Studio Code. Musk: Donate 1 billion if Wikipedia is renamed "Weiji Encyclopedia" USDMySQL 8.2.0 GA
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/3276866/blog/10123262