I'm currently having problems with a little project I'm working on. In this project I'm trying to dynamically create Classes from a configuration String and load it into the JVM.
When I do this in a "normal" environment (Unit Tests) everything works fine. But when I try to create the Classes in an OSGI environment (Apache Karaf) I receive a ClassFormatError with the Message "Illegal class name "Ljava/lang/String;" in class ...".
After a short research I found out that this problem occurs for classes in java/lang when they are not loaded by the system class loader but I'm everything else than an expert when it comes to class loading in java and especially OSGi.
I think the way I'm getting access to the defineClass
method could be of interest for this problem so here it is:
PROTECTION_DOMAIN = (ProtectionDomain) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return RestEndpoint.class.getProtectionDomain();
}
});
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
Class loader = Class.forName("java.lang.ClassLoader");
DEFINE_CLASS = loader.getDeclaredMethod("defineClass",
new Class[]{ String.class,
byte[].class,
Integer.TYPE,
Integer.TYPE,
ProtectionDomain.class });
DEFINE_CLASS.setAccessible(true);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return null;
}
});
The last (hopefully useful) piece of information is the ClassLoader I am invoking the defineClass method on when running my project in an OSGi bundle: It is an instance of org.apache.felix.framework.BundleWiringImpl.
It would be great if someone could help me out here!
Greetings, Pascal
EDIT: I need to define classes at runtime because I want to avoid boilerplate code in my project and make the program more consistent.
To be more precise my project will be a RESTful WebService. Since I'm using multiple technologies to store data and snychronize processes (mongoDB, MySQL, activeMQ, ...), I want to use Apache camel to deal with all the different technologies. The problem is that there is no possibility I know of to nicely integrate Camel with the Java approach on REST (The whole mapping of methods and classes to HTTP requests is done with Annotations). So the only possibility for me was to write methods which would place parameters of the request in the exchange headers of Camel and fire them to the route. To avoid this I wanted to automate this process by defining those classes at runtime from the route definitions.
Write your own class loader whose parent is the bundle's class loader instead of trying to hack into the existing class loader.