Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassPool.get() throwing NotFoundException on class that clearly exists?

I am using the Javassist library to load a class at runtime.

public class FilterClassGenerator<T, DT> {
   private volatile static Long classNameIncrementor = 1L;

   private Class<T> listFilterClass;
   private Class<DT> dataObjectClass;

   public FilterClassGenerator(Class<T> listFilterClass, Class<DT> dataObjectClass) {
       this.listFilterClass = listFilterClass;
       this.dataObjectClass = dataObjectClass;
   }

   public T createFilterClass(ApiFilter filter) {
       try {
           ClassPool pool = ClassPool.getDefault();
           CtClass comparison = pool.makeClass("com.frammo.filterClasses." + generateNewClassName());
           comparison.setSuperclass(pool.get(listFilterClass.getName()));
           // More code

I am getting the following error at: comparison.setSuperclass(pool.get(listFilterClass.getName()));

javassist.NotFoundException: com.frammo.stocks.api.simulation.IiiAccountComparisonFilter

But clearly this class exists!

package com.frammo.stocks.api.simulation;

// Imports

public abstract class IiiAccountComparisonFilter extends ListComparisonFilter<IiiAccount> {

}

Any ideas why it cannot find the class?

like image 617
Armada Avatar asked May 14 '14 11:05

Armada


People also ask

What is classnotfoundexception in Java and how to fix it?

Whenever we try to load a class, if the class loader is not able to find the class at the specified path a ClassNotFoundException is generated. This may occur while executing java program, loading a class explicitly using forName () method of the class named Class or the loadClass () method of the ClassLoader class.

What is a classpool object?

ClassPool objects hold all the CtClass es that have been created so that the consistency among modified classes can be guaranteed. Thus if a large number of CtClass es are processed, the ClassPool will consume a huge amount of memory. To avoid this, a ClassPool object should be recreated, for example, every hundred classes processed.

How does get () work in a classpool?

If a ClassPool has a parent pool, get () first asks the parent pool to find a class file. Only if the parent could not find the class file, get () searches the ClassPath s of the child ClassPool. This search order is reversed if ClassPath.childFirstLookup is true. If true, the contents of a jar file are cached after the jar file is opened.

What is ifnotfrozen in a class file?

classfile - class file. ifNotFrozen - throws a RuntimeException if this parameter is true and there is a frozen class with the same name. Creates a new class (or interface) from the given class file. If there already exists a class with the same name, this method returns the existing class; a new class is never created from the given class file.


2 Answers

This generally happens when Class pool does not find the class in all available search paths. To fix this problem you need to add the class path of your class files to class pool's search path as given below:

    ClassPool.getDefault().insertClassPath(new ClassClassPath(YourCurrentClassName.class));
like image 156
aman rastogi Avatar answered Oct 14 '22 14:10

aman rastogi


I assume this happens because of your use of ClassPool.getDefault(). From the method's documentation:

The default class pool searches the system search path, which usually includes the platform library, extension libraries, and the search path specified by the -classpath option or the CLASSPATH environment variable.

I assume that your class com.frammo.stocks.api.simulation.IiiAccountComparisonFilter is not on the system class path.

You can verify this easily by calling:

Class.forName(
  "com.frammo.stocks.api.simulation.IiiAccountComparisonFilter",
  true,
  ClassLoader.getSystemClassLoader());

This will most likey throw an exception as well. Is your application running as a web application? Such applications load using a different class loader.

You need to make this class source known to the ClassPool. Check the ClassPool's API for how to do this.

like image 35
Rafael Winterhalter Avatar answered Oct 14 '22 15:10

Rafael Winterhalter