Can i use JDI to monitor which the classes that are being loaded and information about which classloader is being used to load each of the classes?
Created Jul 28, 2001
Davanum Srinivas
import java.io.*;
import java.util.*;
import com.sun.jdi.*;
import com.sun.jdi.connect.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
public class ShowClassLoaders {
static final String[] excludes = {
"java.*",
"javax.*",
"sun.*",
"com.sun.*",
};
public static void main(String[] args) {
try {
VirtualMachine vm = null;
LaunchingConnector connector = null;
for(Iterator i =
Bootstrap.virtualMachineManager().allConnectors().iterator();
i.hasNext(); ) {
Connector c = (Connector)i.next();
if (c.name().equals("com.sun.jdi.CommandLineLaunch")) {
connector = (LaunchingConnector)c;
}
}
Map arguments = connector.defaultArguments();
Connector.Argument mainArgument =
(Connector.Argument)arguments.get("main"); StringBuffer
mainArgs = new StringBuffer(); int i;
for(i = 0; i < args.length - 1; i++) {
mainArgs.append(args[i] + " ");
} mainArgs.append(args[i]);
mainArgument.setValue(mainArgs.toString());
vm = connector.launch(arguments);
EventRequestManager erm = vm.eventRequestManager();
ClassPrepareRequest cpr = erm.createClassPrepareRequest();
for(i = 0; i < excludes.length; i++) {
cpr.addClassExclusionFilter(excludes[i]);
}
cpr.enable();
Thread eventsListener = new
DisplayClassLoaders(vm.eventQueue());
Process p = vm.process();
new MonitorOutput(p.getErrorStream());
new MonitorOutput(p.getInputStream());
vm.resume();
eventsListener.join();
} catch(Throwable oops) {
oops.printStackTrace();
}
}
private static class DisplayClassLoaders extends Thread {
EventQueue eventQueue;
public DisplayClassLoaders(EventQueue eventQueue) {
super();
this.eventQueue = eventQueue;
start();
}
public void run() {
try {
boolean stop = false;
do {
EventSet eventSet = eventQueue.remove();
for(EventIterator i = eventSet.eventIterator();
i.hasNext(); ) {
Event evt = i.nextEvent();
if(evt instanceof ClassPrepareEvent) {
ClassPrepareEvent cpe =
(ClassPrepareEvent)evt; ReferenceType refType
= cpe.referenceType();
System.out.println("Loading:" + refType.name()
+
", " +
refType.classLoader());
} else if(evt instanceof VMDisconnectEvent) {
stop = true;
}
}
eventSet.resume();
} while(!stop);
} catch(Throwable oops) {
oops.printStackTrace();
}
}
}
static private class MonitorOutput extends Thread {
InputStreamReader in;
OutputStreamWriter out = new OutputStreamWriter(System.out);
public void run() {
try {
int i;
char[] buf = new char[256];
while ((i = in.read(buf, 0, buf.length)) >= 0) {
out.write(buf, 0, i);
}
} catch(Throwable oops) {
oops.printStackTrace();
}
}
public MonitorOutput(InputStream in) {
super();
this.in = new InputStreamReader(in);
setDaemon(true);
start();
}
}
}
For example to monitor SwingSet2 demo that ships with JDK, set the CLASSPATH as shown below:
CLASSPATH=C:JDK13lib ools.jar;C:JDK13demojfcSwingSet2SwingSet2.jar;.;and then use the following command-line:
java ShowClassLoaders SwingSet2