Strange ClassCastException

In my plugin, I'm accessing a JMX service through RMI. Unfortunately I get a ClassCastException. The code is as follows:


The exception is:
java.lang.ClassCastException: javax.management.ObjectName

The classes seem the same but I guess they get loaded by different ClassLoaders. My plugin depends on the JMX jars and somehow the JARS are loaded by IDEA's classloader instead of the system classloader?

When I run the code as a separate application everything works fine. What should I do to avoid the exception?

5 comments

The plugin needs to work with earlier Java versions than 5 and that's why I have included the JMX libraries. I think the issue is related to the fact that Java 5 already includes the same classes.

I would need to be able to somehow give a priority to the included libraries instead the libraries provided by the JDK.

Any ideas?

0

I had exactly the same problem. My solution was to use my own class
loader, both for loading the plugin class and as the current thread's
context class loader.

Markus Halttunen wrote:

In my plugin, I'm accessing a JMX service through RMI. Unfortunately I get a ClassCastException. The code is as follows:

 import javax.management.ObjectName;
> ..
>             JMXServiceURL jmxServiceURL = new JMXServiceURL(url);
>             JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxServiceURL, null);
>             MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();
>             Set set = mbsc.queryNames(new ObjectName("Something:*"), null);
>             Iterator iterator = set.iterator();
>             while (iterator.hasNext()) {
>                 ObjectName name = (ObjectName)iterator.next();
> ]]>


The exception is:
java.lang.ClassCastException: javax.management.ObjectName

The classes seem the same but I guess they get loaded by different ClassLoaders. My plugin depends on the JMX jars and somehow the JARS are loaded by IDEA's classloader instead of the system classloader?

When I run the code as a separate application everything works fine. What should I do to avoid the exception?


--
Martin Fuhrer
Fuhrer Engineering AG
http://www.fuhrer.com

0

Thanks, Martin!

Do you mean that you have some kind of bootstrap class that gets started by IDEA and that class loads the actual plugin? Is the plugin you mentioned open source or would you happen to have a code example for that? :)

0

It's not really a bootstrap class. I've put everything related to JMX
into it's own class, and everytime I'm using JMX I create my own class
loader and load this JMX utility class through it. Then inside the
utility class I set its class loader (which happens to be my own
implementation) as the current thread's context class loader prior to
any JMX call.

Those are the (extremely simplified) participants of my plugin:

interface MyJmx {

void test(String url);
}

class MyJmxImpl implements MyJmx {

public void test(String url) {
Thread thread = Thread.currentThread();
ClassLoader loader = thread.getContextClassLoader();
try {
thread.setContextClassLoader(getClass().getClassLoader());
JMXServiceURL jUrl = new JMXServiceURL(url);
JMXConnector conn = JMXConnectorFactory.connect(jUrl, null);
MBeanServerConnection srv = conn.getMBeanServerConnection();
Set set = srv.queryNames(new ObjectName("Something:*"), null);
for (ObjectName name : (Set) set) { System.out.println(name); } } finally { thread.setContextClassLoader(loader); } } class MyClassLoader extends URLClassLoader { private static final Set EXCLUDES = new HashSet(Arrays.asList( MyJmx.class.getName(), MyOwnClass1.class.getName(), MyOwnClass2.class.getName() )); MyClassLoader() throws MalformedURLException { super(new URL[], null); List paths = ...; // get all dirs and jars for (String path : paths) { addURL(new File(path).toURI().toURL()); } } @Override protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException { if (EXCLUDES.contains(name)) { return getClass().getClassLoader().loadClass(name); } else { return super.loadClass(name, resolve); } } } class MyPluginClass { public void doSomethingWithJmx(String url) { try { ClassLoader loader = new MyClassLoader(); String name = "my.package.MyJmxClass"; Class type = (Class]]>) loader.loadClass(name);
MyJmx jmx = type.newInstance();
jmx.test();
} catch (Exception e) {
log(e);
}
}
}

Markus Halttunen wrote:

Thanks, Martin!

Do you mean that you have some kind of bootstrap class that gets started by IDEA and that class loads the actual plugin? Is the plugin you mentioned open source or would you happen to have a code example for that? :)


--
Martin Fuhrer
Fuhrer Engineering AG
http://www.fuhrer.com

0

Thank you for the great example code, Martin!

- Markus

PS. My apologies to everyone for posting the initial question on the wrong forum. :)

0

Please sign in to leave a comment.