X

This blog introduces how to diagnose Agile PLM related issues.

  • December 4, 2014

ClasspathLocator based on JMX to detect class location

Jie Chen
Senior Principal Technical Support Engineer

Sometimes I get ClassNotFoundException error from Agile PLM and really do not know which jar file containing this Class is lost. Same happens if I get below error.

  • java.lang.NoClassDefFoundError
  • java.lang.ClassNotFoundException
  • java.lang.NoSuchMethodException
  • java.lang.NoSuchMethodError

Another issue is if duplicated class are referenced by JVM, it is hard to to figure out which one is acting.

Below is a simple tool written in Java with JMX to detect related class location in a working environment. Let me say its name ClasspathLocator


JMX Service

ClasspathLocator JMX MBean interface

package com.agile.support.jmx;
public interface ClasspathLocatorMBean {

public String findLocation(String klass);
}


class to implement the ClasspathLocator JMX MBean interface

package com.agile.support.jmx;
import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
import java.security.CodeSource;
import java.security.ProtectionDomain;
public class ClasspathLocator implements ClasspathLocatorMBean {

@Override

public String findLocation(String klass) {

klass = klass.trim();

try {

Class clazz = Class.forName(klass);

if (clazz == null) {

return “Invalid class: ” + klass;

}

ProtectionDomain protectionDomain = clazz.getProtectionDomain();

CodeSource codeSource = protectionDomain.getCodeSource();

File jarFile;

if (codeSource != null && codeSource.getLocation() != null) {

jarFile = new File(codeSource.getLocation().toURI());

} else {

String path = clazz.getResource(clazz.getSimpleName() + “.class”).getPath();

String jarFilePath = path.substring(path.indexOf(“:”) + 1, path.indexOf(“!”));

jarFilePath = URLDecoder.decode(jarFilePath, “UTF-8”);

jarFile = new File(jarFilePath);

}

return klass + “ -> ” + jarFile.getAbsolutePath();

} catch (Throwable e) {

e.printStackTrace();

return klass + “ Not found”;

}

}
}

One Class file could exist as packed in a jar file or a physical *.class in a folder. So I use if-else to handle these two cases like above.


ClasspathLocator JMX service

package com.agile.support.jmx;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class AgileSupportJMXAgent {

private final MBeanServer mbs;

public AgileSupportJMXAgent(){

mbs = ManagementFactory.getPlatformMBeanServer();

}

public void register() throws Exception {

ObjectName objectName = new ObjectName(“AgileSupport:type=ClasspathLocator”);

if (mbs.isRegistered(objectName)){

mbs.unregisterMBean(objectName);

}

ClasspathLocator cpLoc = new ClasspathLocator();

mbs.registerMBean(cpLoc, objectName);


}
}

In above code, I create a MBean folder named AgileSupport and the MBean name is ClasspathLocator.

Trigger Class (Client)

It is a client class to start ClasspathLocator JMX service. You can implement it simply by calling new AgileSupportJMXAgent().register() . However in Agile PLM, we can dynamically invoke it within Custom PX.

In this case, I create CustomAction JmxPX.class and add it to Tools menu.

package com.agile.support.jmx;
import com.agile.api.IAgileSession;
import com.agile.api.IDataObject;
import com.agile.api.INode;
import com.agile.px.ActionResult;
import com.agile.px.ICustomAction;
public class JmxPX implements ICustomAction {

@Override

public ActionResult doAction(IAgileSession sess, INode node, IDataObject obj) {

try {

new AgileSupportJMXAgent().register();

} catch (Exception e) {

e.printStackTrace();

return new ActionResult(ActionResult.EXCEPTION, e);

}

return new ActionResult(ActionResult.STRING, “AgileSupportJMXAgent started.”);

}
}


Use Case

When I do troubleshooting, I simply click ClassLocatorJMXService px in Tools menu, which I set up in JavaClient. Be sure to see the message AgileSupportJMXAgent started..

Next, I use JConsole to connect to Agile PLM JMX service, will see my customized ClasspathLocator MBean is listed correctly and the function findLocation() is available.

For test purpose, I input oracle.jdbc.driver.OracleDriver and click button findLocation, it will pop up a window containing my expected result of jar location.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.