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?
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.
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.
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.
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.
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));
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With