Shevek (shevek) wrote,

I need help with a Java problem.

I have a ClassCastException because a class is loaded into two separate ClassLoaders, and I'm trying to cast to the wrong instance of the superclass. In order to debug this, I need to find the ClassLoaders which loaded copies of the class, and secondarily to find out why it didn't use the copy from JDK6. (We're talking STAX XMLInputFactory here.)

Anyway, how do I find these ClassLoaders? Specific answers only, please. I can get as far as JVisualVM, the heap dump shows me two instances of the Class, but won't show me the loaders. I can't work it out in OQL, and there's no documentation - heap.classes() takes no argument. For some reason, the only Class instances I can see in the heap are the primitives anyway: "select c from instanceof java.lang.Class c" shows me only 10, and if I inspect the 'name' field... I don't get the right set of ClassLoaders either, I think I may be looking at a side-effect of dumping the heap/permgen over JMX.

Does anyone else have specific experience with a debugger which can achieve what I need? The heap size is about 70Mb, so utterly tractable.

I've been bashing at this for two hours now and I'm at a dead end. Please help.

Thank you all.

Edit: I just sat back and thought about it, and I think what's going on is this:

- XMLInputFactory (why isn't this getting seen)
` SomeClassLoader
- MyClass (calls XMLInputFactory.newInstance() with a CCL set)
` XMLInputFactory (is this the JDK one?)
` OtherClassLoader (Also a delegate of the ContextClassLoader, and not parentFirst)
- Services declaration for XMLInputFactory
` XMLInputFactory from JSR173.

So, naturally, my call detects the XMLInputFactory, gets back something (ServiceLoader style) which cannot be cast to the XMLInputFactory in the static context. CCE ensues. So I need to find out why we didn't load the class from the JDK root loader, and/or how to modify the loader hierarchy so that I get something I can cast statically.

The platform is NetBeans, the CCL is the standard NB CCL (unified delegate to all modules), and the module supplying Zephyr (etc) is the JAXB plugin. Another user got a WstxInputFactory, source unknown.

I also note that STAX in 1.6 has newFactory(), in 1.5 it has only newInstance().

Second edit and TL;DR:

How do I grab the classloader for a named class using a debugger, on a 1.6 VM?

See also
  • Post a new comment


    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.