Question

This looks like an old problem that is resolved, but unfortunately I couldn't find a good reference. I have a Java application using Javaassist. It was working fine until I upgraded it to a webstart application. Now Javaassist gives me a classNotFoundException. The class is definitely in class path though.

I found this related post https://community.jboss.org/message/302408 which is kind of old and I couldn't decode it. Can someone gime me a hand here?

thanks

Here is the code snippet:

 ctClasses = new HashMap<String, CtClass>();
    classPool = ClassPool.getDefault();

    try {
        ctEntity = classPool.get("org.myclass");
    } catch (NotFoundException e) {
        logger.error("Could not find entity class, this should not happen");
        throw new RuntimeException("Could not find Entity class",e);
    }

There is nothing in stacktrace.

 java.lang.RuntimeException: Could not find Entity class
    at ca.cbc.panacea.metadata.JavassistClassGeneratorImpl.<init>(JavassistClassGeneratorImpl.java:32)
    at ca.cbc.panacea.metadata.ClassGeneratorFactory.getDefaultClassGenerator(ClassGeneratorFactory.java:12)
    at ca.cbc.panacea.metadata.ClassCreator.<init>(ClassCreator.java:30)
    at ca.cbc.panacea.Panacea.digestMappingFile(Panacea.java:75)
    at ca.cbc.panacea.console.PanaceaConsole.validateMappingFile(PanaceaConsole.java:46)
    at ca.cbc.panacea.console.PanaceaConsoleUI.actionPerformed(PanaceaConsoleUI.java:132)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    at java.awt.Component.processMouseEvent(Component.java:6373)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
    at java.awt.Component.processEvent(Component.java:6138)
    at java.awt.Container.processEvent(Container.java:2085)
    at java.awt.Component.dispatchEventImpl(Component.java:4735)
    at java.awt.Container.dispatchEventImpl(Container.java:2143)
    at java.awt.Component.dispatchEvent(Component.java:4565)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4621)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4282)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4212)
    at java.awt.Container.dispatchEventImpl(Container.java:2129)
    at java.awt.Window.dispatchEventImpl(Window.java:2478)
    at java.awt.Component.dispatchEvent(Component.java:4565)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:679)
    at java.awt.EventQueue.access$000(EventQueue.java:85)
    at java.awt.EventQueue$1.run(EventQueue.java:638)
    at java.awt.EventQueue$1.run(EventQueue.java:636)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
    at java.awt.EventQueue$2.run(EventQueue.java:652)
    at java.awt.EventQueue$2.run(EventQueue.java:650)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:649)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
     Caused by: javassist.NotFoundException: ca.cbc.panacea.metadata.Entity
    at javassist.ClassPool.get(ClassPool.java:436)
    at ca.cbc.panacea.metadata.JavassistClassGeneratorImpl.<init>       (JavassistClassGeneratorImpl.java:29)

The problem is actually the ClassLoader. JNLP uses a different classloader than java command line. The question is how to reconcile JNLP class loader with Javassist.

Was it helpful?

Solution

The key is setting up the ClassPool to see the class loader of your application's classes. This can be done by adding a classpath to the ClassPool:

ctClasses = new HashMap<String, CtClass>();
classPool = ClassPool.getDefault();

//Add the classloader of your application's classes so Javassist can find them
ClassLoader loader = org.MyClass.class.getClassLoader();
pool.appendClassPath(new LoaderClassPath(loader));

try {
    ctEntity = classPool.get("org.MyClass");
} catch (NotFoundException e) {
    logger.error("Could not find entity class, this should not happen");
    throw new RuntimeException("Could not find Entity class",e);
}

You need to do customize the classpath of the class pool for any application that does not load its classes from the system classloader, such as web-start applications, Eclipse plugins and applications that run under a Java EE container.

More details under the class search path section of the Javassist tutorial.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top