I am doing a JBoss SEAM project and when I view a form I get this error.
java.lang.ClassCastException:
it.cogitoweb.csi.entity.csiorelav.CsiTipoLav cannot be cast to
it.cogitoweb.csi.entity.csiorelav.CsiTipoLav
Its alway the same JPA class which is related to the form which is shown on the screen, it doesn't make sense to me why is it the same class, it seems impossible.
This happens when two different ClassLoader objects load classes with the same name. The equality of two classes in Java depends on the fully qualified name and the class loader that loaded it.
So if two independent class loaders load classes from the same location, then objects of those types will not be able to be cast to each others type, even if their classes are called the same.
As Joachim explained earlier, java.lang.ClassCastException typically occurs when two classloaders load the classes with the same name. However, i have come across another situation when this could occur.
This could occur with some IDE's that automatically reloads classes that have been modified. In such cases there might be older versions of the class retained in memory causing ClassCastException.
Here are a few ways you could resolve this issue :
If you are writing a custom class loader, while loading a class make sure that the base/default class loader does not already have an instance of that class loaded.
Make the class being loaded a sub-class of the class that is already loaded by the default class loader.
Make the class being loaded implement an interface that is already loaded by the default class loader.
More info here - http://www.jspwiki.org/wiki/A2AClassCastException
This is because the class has been loaded by two different classloaders. You cannot cast between them.
You've likely got a duplicate copy of CsiTipoLav in your application, and the two different copies are being loaded at different times from different classloaders. JBoss has a plethora of different classloaders in a hierarchy, and it's easy to get things in a twist.
Make sure you only have one copy of the class.
The object you are trying to cast, is loaded by a different classloader than the one which has loaded the class you are trying to cast into.
In my case i had two different *.ear and wanted to load a class from the other.
So i had to isolate the classloader. I used this description:
http://www.thorgull.be/wiki/index.php?title=ClassLoader_isolation_in_JBOSS
It worked for me.
Related
I have class Foo which needs class Bar as an import. Class Bar is loaded with different class loader than Foo and while defining Foo, class loader can't find Bar and throws ClassNotFoundException. Is it even possible to tell class loader, if class is not available in current class loader try looking in another?
Not generally, no. One could write such a classloader, but you can't 'edit' an existing classloader to work like this.
ClassLoaders are asked by either code itself (SomeClass.class.getResource will end up there, as will, of course, invoking findResource or loadClass or whatnot on an actual ClassLoader instance), or by the JVM (when a given class needs another to execute, the class's classloader is asked for it. This usually results in that CL returning it from cache, but if it hasn't been loaded yet by that CL, that would result in it being loaded).
The CL is then free to implement this request in any way it sees fit. URLClassLoader, which is also the default classloader (initialized with the classpath) will first ask its parent loader (in the default JVM config, that'll be the system loader that knows where e.g. java.lang.String lives, from the jmod files of your JDK installation), and return that result if available. It will then load by scanning classpath, and it ends there. You can't ask an existing URLClassLoader to change its behaviour, but you can of course write your own classloader - it's just code, you can extend the findClass etc methods.
Maybe elaborate a bit on what you're trying to accomplish. Why are multiple classloaders involved and what are you trying to accomplish by having multiple? (Say: Load classes from database BLOB fields, or, separate modules out, or, allow dynamic reloading of web handlers - that kind of answer).
Are you using an existing CL-based framework like OSGi, perhaps?
Is it possible to load multiple versions of the same class into the JVM. I have a version of the class "XYZ" loaded in the main thread and I have multiple children threads doing some work. I want to load different versions of class "XYZ" in to children threads.
Is this doable? I was thinking of creating a new context class loader for each of the children threads and use this context class loader to load a different version of the class. For now I am using URLClassLoader for context class loaders but that does not seem to work. Do I have to create a custom class loader to the do the job?
Here is the code I have so far.
final Thread builderThread = new Thread("Child Thread " + buildToken) {
#Override
public void run() {
futureTask.run();
}
};
try {
URL url = new URL("file:///path to the jar file");
URLClassLoader classLoader = new URLClassLoader(new URL[]{url});
classLoader.loadClass("XYZ");
builderThread.setContextClassLoader(classLoader);
}
The reason why I want to have different versions of the class is because I want to have different values for the static fields in the class "XYZ".
Yes, it is possible, and you're on the right track with URLClassLoader. The scope of your classloaders will be determined by the scope you want the static fields to have. For example, if each task or thread should have its own copy of those fields, then each task or thread must have its own classloader.
There are a couple other issues to be aware of. First, the class you want to load multiple times must not be found on the system classpath. This is because classloaders exist in a hierarchy, and delegate to their parent before attempting to load a class themselves. If the system classloader finds the class, it will load it only once, and other classloaders will use the class loaded by the system classloader.
Second, the JVM will treat each loading of the class as a distinct class, despite the fact that they're all identical. This means that instances of the dynamically loaded class must be confined to the scope of their classloader. If each task has its own classloader, then instances cannot be passed between tasks. And obviously you cannot publish instances to the rest of the app, because the rest of the app uses the system classloader, which must not know about the class. (You can get around this somewhat if the dynamically loaded class has a superclass or superinterface that the system classloader does know about. Then you can publish the instance as that type.)
The reason why I want to have different versions of the class is because I want to have different values for the static fields in the class "XYZ".
This really seems like a hack to me. Do you really have no other way to inject different values into this class?
How about passing some sort of Context instance for each thread and convert your class to use the settings from the Context instead of from static fields. You could also use a ThreadLocal so each thread would get the static field information from there instead.
Loading different versions of the class is going to be extremely hard (if not impossible) to debug. The only time I've ever heard of folks using multiple class loaders is when you have security concerns (often in a web server environment) and there is a deliberate point to having separation between the web classes and the outer admin classes.
I'm implementing a feature that requires passing dynamically generated types (in binary representation, serialised with Kryo) between several instances of JVM (over the network). In order to properly resolve what types are loaded and what are not I use a custom system class loader (passed as java -Djava.system.class.loader parameter), which is used by other dynamically created class loaders as a parent. This custom system class loader knows of its children and in case it cannot find a class these derived class loaders can be asked if they have it (this is a reverse to the standard hierarchical structure of class loaders).
These dynamically generated types get transferred and loaded between different JVMs perfectly fine. The problem arises when I try to deserialise an instance of some type (a corresponding class is loaded from disc and is identical for all JMVs) that references one of the dynamically generated types -- ClassNotFoundException is raised by an instance of Kryo, which tries to readClass by name of the dynamically generated type.
Inside method readClass there a call to Class.forName, which in turn does not use the specified custom class loader (that knows of all dynamically generated types) and instead uses sun.misc.Launcher$AppClassLoader instance.
Is it possible to specify a custom system-wide class loader, so that all classes are loaded with it in order to avoid the described problem?
Update
Further analysis revealed that ClassLoader.getSystemClassLoader() actually returns the specified custom system class loader. Fortunately, the Kryo library supports setting of a custom class loader specifically for loading classes upon deserialisation. These two facts formed the basis of a solution to the described problem.
How would you load the custom class loader if all classes have to laoded using that class loader?
One way to get around this is to create a native instrumentation agent. This is loaded before any classes are loaded.
Another way around it is to compile your own version of AppClassLoader and prefix it to the boot class path or add it to the libs/endorsed directory.
I have an application that needs the ability to update parts of itself (one class at a time) without stopping and restarting. With the JavaCompiler API, it is straightforward to generate modified class source code, recompile, load, and instantiate a class. I can do this all in memory (no files read from disk or net).
The application will never instantiate more than one object of such a class. There will only be two or three references to that object. When the modified class is loaded and instantiated, all those references will be changed to the new object. I can also probably guarantee that no method in the affected class is running in another thread while loading the modified class.
My question is this: will my class loader have problems loading a modified class with the same name as a class it previously loaded?
If I do not explicitly implement a cache of loaded classes in the class loader, would that avoid problems? Or could delegation to a parent class loader still cause a problem?
I hope to use a single instance of my class loader, but if necessary, I could instantiate a new one each time I update a class.
Note: I looked at OSGI and it seems to be quite a bit more than I need.
There's a useful example on this at http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html
We do quite a bit of dynamic class reloading ourselves (using Groovy for compilations). Note if you've got class dependencies then you may need recompile these dependencies on reload. In dev stacks we keep a track of these dependencies and then recompile whenever dependencies become stale. In production stacks we opted for a non-reloading ClassLoader and create a new ClassLoader when ever anything changes. So you can do it either way.
BTW - you might find the GroovyScriptEngine at http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.groovy/groovy-all/1.8.5/groovy/util/GroovyScriptEngine.java#GroovyScriptEngine very interesting if you want to dig around how they do it.
Okay, it should work: when you load the new class, it will replace the class name in the appropriate tables, and the memory should be GC'd. That said, I'd give it a strenuous test with a real short program that compiles a nontrivial class and replaces it, say 10,000 times.
On different sites , Dynamic class loading is given as one of the reason of permgen problem.
As per my understanding , Dynamic class loading is loading the class as and when it is required.Alonwith that if Class A is loaded and it is referring another class B , it will also be loaded along with that. This is Dynamic class loading. Right? If yes, this is essential and inbuilt feature of JVM. What we can do about it?
Or my understanding is wrong here. when we say Dynamic class loading , are we reffering to custom class loaders here?
My last question related to above is, Class is loaded once by customer loader. So when we do hotdeployment on application server, how appserver loads the new version of class. Does it use different class loader here?
No, dynamic class loading refers to loading classes during runtime that are unknown at compile time, e.g., via Class.forName, or reflection (1, 2).