List All Loaded Classes in the Java JVM Using Nashorn JavaScript - Capture Club
kmcowan 17 August, 2018 0

List All Loaded Classes in the Java JVM Using Nashorn JavaScript

Java Virtual Machine

 

As I was working through an issue the other day, at one point I wanted to see what was loaded in the Java Virtual Machine (JVM).  To make matters a bit more tricky, I had to accomplish this using Nashorn JavaScript.  So after a bit of poking around, I found this in Java:


import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Vector; 

public class ListLoadedClasses {
   private static Field ClassLoader_classes_field = null;
    private static Iterator list(ClassLoader CL)
            throws NoSuchFieldException, SecurityException,
            IllegalArgumentException, IllegalAccessException {
        Class CL_class = CL.getClass();
        while (CL_class != java.lang.ClassLoader.class) {
            CL_class = CL_class.getSuperclass();
        }
       ClassLoader_classes_field = CL_class
                .getDeclaredField("classes");
        ClassLoader_classes_field.setAccessible(true);
        Vector classes = (Vector) ClassLoader_classes_field.get(CL);
        return classes.iterator();
    }

    public static void main(String args[]) throws Exception {
        ClassLoader myCL = Thread.currentThread().getContextClassLoader();
        while (myCL != null) {
            System.out.println("ClassLoader: " + myCL);
            for (Iterator iter = list(myCL); iter.hasNext();) {
                System.out.println("\t" + iter.next());
            }
            myCL = myCL.getParent();
        }
    }
}

So in the above snippet, you can see that we’re getting the ClassLoader objects from the head, and iterating over their respective loaded classes. All-in-all, pretty straight forward.

JavaScript, For the Win, again, again

But what if we didn’t have access to a Java environment? What if we were working in, say, a Nashorn JavaScript environment and wanted to do this same thing. We can accomplish that by porting the above code over to Nashorn, which looks like this:


var listLoadedClasses = function(doc){
    var e = java.lang.Exception;
    var Class = java.lang.Class;
    var Thread = java.lang.Thread;
    var ClassLoader = java.lang.ClassLoader;
    var System = java.lang.System;
    var Iterator = java.util.Iterator;
    
    try{
         var myCL = Thread.currentThread().getContextClassLoader();
         var str = "";
         while (myCL !== null) {
            str += " ClassLoader: " + myCL +" \n";
            for (var iter = list(myCL); iter.hasNext();) {
                str += " \t" + iter.next() + " \n";
            }
            myCL = myCL.getParent();
        }
        logger.info(str);
    }catch(e){
        
    }
    
    function list(CL){
        var ex = java.lang.Exception;
        var Vector = java.util.Vector;
        var ClassLoader_classes_field = java.lang.reflect.Field;
        try{
            var CL_class = CL.getClass();
        while (CL_class != java.lang.ClassLoader.class) {
            CL_class = CL_class.getSuperclass();
        }
        ClassLoader_classes_field = CL_class.getDeclaredField("classes");
        ClassLoader_classes_field.setAccessible(true);
        var classes =  ClassLoader_classes_field.get(CL);
        return classes.iterator();
        }catch(ex){
            
        }
    }
    
    return doc;
}

So it looks a bit different, but the end result is exactly the same.

 

Ultimately, there is really nothing you can’t do with Nashorn, and that is what makes it so cool.

Leave a Reply