2

I would like to know if it is possible with JNI apis to list ALL the current available instances(as jobject) in the current JVM.

Example of what I mean:

jvm->AttachCurrentThreadAsDaemon((void**)&env,0);
jobject* instances;
int count = env->GetInstances(&instances);

My task would be to search through them for objects which implement a certain interface(env->IsInstanceOf()), I have to do this dynamically and globally without class names

Sam
  • 2,950
  • 1
  • 18
  • 26
  • 6
    See ["Is there a simple way of obtaining all object instances of a specific class in Java"](http://stackoverflow.com/questions/1947122/). – Andy Thomas Apr 06 '16 at 17:55
  • Though this question has a similar title, I wouldn't call it duplicate, since the referenced question is 1) outdated, 2) not about JNI, 3) does not have a precise answer. – apangin Apr 07 '16 at 04:50

1 Answers1

7

JVMTI will help.

  1. Call IterateOverInstancesOfClass to tag all required objects;
  2. Call GetObjectsWithTags to copy all tagged objects to jobject* array.

Here is an example. Note that targetClass can be also an interface.

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

JNIEXPORT void JNICALL
Java_Test_iterateInstances(JNIEnv* env, jclass ignored, jclass targetClass) {
    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(targetClass, JVMTI_HEAP_OBJECT_EITHER,
                                       HeapObjectCallback, NULL);

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

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

    jvmti->Deallocate((unsigned char*)instances);
}
apangin
  • 92,924
  • 10
  • 193
  • 247