• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How find all loaded classes/classloaders in JVM?

 
Dan Bizman
Ranch Hand
Posts: 387
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I need to find all the classes loaded into a JVM. Does anyone know how to do this? Is it possible? I know a number of methods seach for all ".class" files in the resources but not every class has to be from a .class file.

Also, doing that only gets the resources that were loaded from classloaders in our tree or with SystemClassLoader as an ancestor. What about parentless ClassLoaders? I know that the JVM still knows about those classloaders but is there any way to find them programmatically? If not, why not?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There wasn't any good way to do this until JDK 5 came out. See the java.lang.instrument package summary for an overview. The Instrumentation interface has a method getAllLoadedClasses() that should be just what you want.
[ March 25, 2008: Message edited by: Jim Yingst ]
 
Dan Bizman
Ranch Hand
Posts: 387
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
There wasn't any good way to do this until JDK 5 came out. See the java.lang.instrument package summary for an overview. The Instrumentation interface has a method getAllLoadedClasses() that should be just what you want.

[ March 25, 2008: Message edited by: Jim Yingst ]


Thanks for the info, but as far as I can see, there's no implementing class of Instrumentation and I don't see a static method for finding an implementation of it. Do you know where in the JRE it exists?

Thanks!
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You need to follow the instructions in the package summary I linked to. You create an "agent", which is a java program that will use the Instrumentation to do something. When you create the agent correctly with a premain() method, the JVM will create an Instrumentation instance for you, and pass it in as one of the parameters. You can then do whatever you want with it. One simple option is to put it in a static variable so you can reference it later:

Compile this and put it in a jar file (e.g. "agent.jar") with a manifest as described in the package summary, and then you can run your main program with

You can then access the Instrumentation instance later from your main program using JavaAgent.getInstrumentation().

The mechanism used here may seem needlessly convoluted. It's designed so that these "agents" can really be separate programs - things like IDEs and debuggers, for example. If you just want to access an Instrumentation instance from within your program, it's a bit harder than necessary, but still possible.
 
Dan Bizman
Ranch Hand
Posts: 387
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

The mechanism used here may seem needlessly convoluted. It's designed so that these "agents" can really be separate programs - things like IDEs and debuggers, for example. If you just want to access an Instrumentation instance from within your program, it's a bit harder than necessary, but still possible.


Thank you VERY much for the very throrough (and patient) response! That is what I want to do (access it from within a program). And that's the part that was a mystery to me.

One question: do ALL implementations of JRE 1.5 guarantee that the VM arg "-javaagent:agent.jar" will work exactly the same way? Is this a JRE guarantee or only for Sun's version?

Thanks again!
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Dan]: One question: do ALL implementations of JRE 1.5 guarantee that the VM arg "-javaagent:agent.jar" will work exactly the same way? Is this a JRE guarantee or only for Sun's version?

I don't really know. From the way the package summary is phrased, it seems that any JVM that has a command line interface at all is required to support the -javaagent: option at least. Some of the other options related to starting an agent after VM startup are described as optional, so other JVMs may not support this. In practice I suppose it's possible that a vendor might release a JDK and just say "that feature doesn't work". So you'll have to try it and see, to know for sure.

For what it's worth though, I tested that program on my Mac, with a JDK from Apple, not Sun. So that's at least one other vendor that supports the spec as written.
 
Steve Calkins
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried this suggestion, creating the JavaAgent.class and putting it in agent.jar
The pertinent parts of the manifest are:

Manifest-Version: 1.0
...
Specification-Version: 1.0.0
...
Premain-Class: de.cmsol.agent.JavaAgent

I use Eclipse and the VM argument list was set to:
-javaagent:agent.jar
...

Still the VM doesn't start. I get the exception:

java.net.SocketException: socket closed
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:384)
at java.net.ServerSocket.implAccept(ServerSocket.java:453)
at java.net.ServerSocket.accept(ServerSocket.java:421)
at org.eclipse.jdi.internal.connect.SocketTransportService.accept(SocketTransportService.java:95)
at org.eclipse.jdi.internal.connect.SocketTransportImpl.accept(SocketTransportImpl.java:56)
at org.eclipse.jdi.internal.connect.SocketListeningConnectorImpl.accept(SocketListeningConnectorImpl.java:135)
at org.eclipse.jdt.internal.launching.StandardVMDebugger$ConnectRunnable.run(StandardVMDebugger.java:107)
at java.lang.Thread.run(Thread.java:619)

What am I doiing wrong?
 
Campbell Ritchie
Sheriff
Pie
Posts: 49804
69
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch
 
Paul Clapham
Sheriff
Posts: 21322
32
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve Calkins wrote:I use Eclipse and the VM argument list was set to:
-javaagent:agent.jar


I'm taking a wild guess here: does that parameter mean that agent.jar is in the current working directory, or in the classpath? Or does it matter in your case? Bear in mind that I haven't read any documentation so I don't know whether it tells you that.
 
Steve Calkins
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe I wasn't thorough enough in my explanation. The agent.jar file was created from a separate project in Eclipse. This way I can use the Instrumentation interface for other purposes. In the project that uses agent.jar in Eclipse I extended the classpath by adding the jar file to the classpath entries. Thus I can debug the thing. But it doesn't work. Has anyone else tried this from Eclipse and had a similar problem? maybe it is an Eclipse thing...
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic