I have profiled my Java application and know that it contains a memory leak in native code but not in the application's own Java source code. I'm trying to identify the dependency or dependencies that might be at fault.
Back in earlier versions of the JDK, you could find native libraries in a Java app with something like this:
public class ClassScope {
private static final java.lang.reflect.Field LIBRARIES;
static {
LIBRARIES = ClassLoader.class.getDeclaredField("loadedLibraryNames");
LIBRARIES.setAccessible(true);
}
public static String[] getLoadedLibraries(final ClassLoader loader) {
final Vector<String> libraries = (Vector<String>) LIBRARIES.get(loader);
return libraries.toArray(new String[] {});
}
}
final String[] libraries = ClassScope.getLoadedClasses(ClassLoader.getSystemClassLoader());
However, if you try this on JDKs after 9, you get warned that this access will be revoked from Java 12 om:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by <class> (file:<file>) to method|constructor
WARNING: Please consider reporting this to the maintainers of <file>
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
And in JDK 17 the field has been removed completely:
No field loadedLibraryNames in class Ljava/lang/ClassLoader;
So, in a JDK 17 app, what options are there to identify native libraries used via JNI?