Java - ClassCastException to the very same Class/Package [duplicate] - java

I have 2 different Java projects, one has 2 classes: dynamicbeans.DynamicBean2 and dynamic.Validator.
On the other project, I load both of these classes dynamically and store them on an Object
class Form {
Class beanClass;
Class validatorClass;
Validator validator;
}
I then go ahead and create a Validator object using validatorClass.newInstance() and store it on validator then I create a bean object as well using beanClass.newInstance() and add it to the session.
portletRequest.setAttribute("DynamicBean2", bean);
During the lifecycle of the Form project, I call validator.validate() which loads the previously created bean object from the session (I'm running Websphere Portal Server). When I try to cast this object back into a DynamicBean2 it fails with a ClassCastException.
When I pull the object back out of the session using
faces.getApplication().createValueBinding("#{DynamicBean2}").getValue(faces);
and check the class of it using .getClass() I get dynamicbeans.DynamicBean2. This is the class I want to cast it to however when I try I get the ClassCastException.
Any reason why I'm getting this?

I am not quite following your description of the program flow, but usually when you get ClassCastExceptions you cannot explain you have loaded the class with one classloader then try to cast it to the same class loaded by another classloader. This will not work - they are represented by two different Class objects inside the JVM and the cast will fail.
There is an article about classloading in WebSphere. I cannot say how it applies to your application, but there are a number of possible solutions. I can think of at least:
Change the context class loader manually. Requires that you can actually get a reference to an appropriate class loader, which may not be possible in your case.
Thread.currentThread().setContextClassLoader(...);
Make sure the class is loaded by a class loader higher in the hierarchy.
Serialize and deserialize the object. (Yuck!)
There is probably a more appropriate way for your particular situation though.

I was getting this problem after adding a dependency to spring-boot-devtools in my Springboot project. I removed the dependency and the problem went away. My best guess at this point is that spring-boot-devtools brings in a new classloader and that causes the issue of class casting problems between different classloaders in certain cases where the new classloader is not being used by some threads.
Reference: A dozer map exception related to Spring boot devtools

The class objects were loaded in different classloaders, therefore the instances created from in each of classes are seen as 'incompatible'. This is a common issue in a an environment where there are many different classloaders being used and objects are being passed around. These issues can easily arise in Java EE and portal environments.
Casting an instance of a class requires that the Class linked to the object being casted is the same as the one loaded by the current thread context classloader.

I got the A2AClassCastException problem when trying to create a List of objects from XML using Apache Commons Digester.
List<MyTemplate> templates = new ArrayList<MyTemplate>();
Digester digester = new Digester();
digester.addObjectCreate("/path/to/template", MyTemplate.class);
digester.addSetNext("/path/to/template", "add");
// Set more rules...
digester.parse(f); // f is a pre-defined File
for(MyTemplate t : templates) { // ClassCastException: Cannot cast mypackage.MyTemplate to mypackage.MyTemplate
// Do stuff
}
As stated above, the cause is that the digester doesn't use the same ClassLoader as the rest of the program. I ran this in JBoss, and it turned out that commons-digester.jar was not in JBoss's lib directory, but rather in a webapp's lib directory. Copying the jar into mywebapp/WEB-INF/lib also solved the problem. Another solution was to casll digester.setClassLoader(MyTemplate.class.getClassLoader()), but that feels like quite an ugly solution in this context.

Had the same my.package.MyClass cannot be cast to my.package.MyClass on WildFly 10.1 and, as I understand, I did the opposite to what #Emil Lundberg described in his answer.
I have added the module (which contains my.package.MyClass) to my.war/WEB-INF/jboss-deployment-structure.xml as a dependency
<dependencies>
...
<module name="my.package"/>
</dependencies>
and removed the corresponding jar from my.war/WEB-INF/lib, re-deployed the WAR and then the code worked as expected.
Thus, we made sure it solves the issue. Now, we need to make sure the issue won't come back, for example, when the updated version of WAR will be assembled and deployed.
For this, in the sources of those WAR, it is required to add <scope>provided</scope> for those jar in pom.xml, so that when my.war is re-assembled next time with the fix/enhancement code injected, it will not bundle this jar into my.war/WEB-INF/lib.

I had the same issue while using several JBoss instances on different machines. To bad I didn't stumble across this post earlier.
There were artifacts deployed on different machines, two of them declared class loaders with identical name.I changed one of the classloader names and everything worked fine => Beware of Copy&Paste!
Why doesn't the ClassCastException thrown mention the involved class loaders? - I think that would be very useful information.
Does anyone know if there will be anything like this available in the future? Needing to check the class loaders of 20-30 Artifacts is not that pleasant. Or is there something I missed in the exception text?
EDIT: I edited the META-INF/jboss-app.xml file and changed the name of the loader, the idea is to have a unique name. At work we use the artifact id(unique) combined with the version inserted by maven({$version}) during the build. Using dynamic fields is only optional but helps if you want to deploy different versions of the same application.
<jboss-app>
<loader-repository>
com.example:archive=unique-archive-name-{$version}
</loader-repository>
</jboss-app>
You can find some info here: https://community.jboss.org/wiki/ClassLoadingConfiguration

I had the same issue, and I finally found a workaround on java.net :
Copy all org.eclipse.persistence jar files from glassfish4/glassfish/modules to WEB-INF/lib. Then go in your glassfish-web.xml, and set class-delegate to false.
Worked for me !

I had a similar issue with JAXB and JBoss AS 7.1. The issue and solution are described here: javax.xml.bind.JAXBException: Class *** nor any of its super class is known to this context. The exception that was given was org.foo.bar.ValueSet cannot be cast to org.foo.bar.ValueSet

I had the same issue on a wildfly EJB, The EJB was returning a list of Objects and has an remote and a local interface. I used the Local interface by mistake what was working just fine up until the point you try to cast the objects in the list.
Local/Remote interface:
public interface DocumentStoreService {
#javax.ejb.Remote
interface Remote extends DocumentStoreService {
}
#javax.ejb.Local
interface Local extends DocumentStoreService {
}
The EJB bean:
#Stateless
public class DocumentStoreServiceImpl implements DocumentStoreService.Local, DocumentStoreService.Remote {
The correct spring wrapper around the EJB:
<bean id="documentStoreService" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="java:global/dpc/dpc-ejb/DocumentStoreServiceImpl!santam.apps.dpc.service.DocumentStoreService$Remote"/>
<property name="businessInterface" value="santam.apps.dpc.service.DocumentStoreService$Remote"/>
<property name="resourceRef" value="true" />
</bean>
Note the $Remote, You can change this to $Local and it will find the Local interface just fine, and also execute the methods without any issue (from a separate application on the same container), but the model objects are not marshaled and are from a different class loader if you use the local interface by mistake.

Another option:
Happened to me in weblogic, but I guess it can happen in other servers as well - if you do (just) "Publish" and therefor some of your classes are re-loaded. Instead do "Clean" so all the classes will re-loaded together.

I had same problem with an EJB lookup from another EJB.
I solved adding #Remote(MyInterface.class) to EJB class configuration

Related

Classloader problem with JAXB internal implementation interface com.sun.xml.bind.namespacePrefixMapper

I need help for the following problem: I use Websphere Liberty 19.0.0.9 with Oracle and IBM Java 1.8 an run an older application (EAR) containing an EJB, which serializes XML with JAXB. The application needs to control XML namespace definitions and prefixes and does this by providing an implementation of com.sun.xml.bind.namespacePrefixMapper to javax.xml.bind.Marshaller.setProperty with property "com.sun.xml.bind.namespacePrefixMapper".
At runtime the error java.lang.NoClassDefFoundError: com/sun/xml/bind/marshaller/NamespacePrefixMapper occurs when loading the implementation class.
The server.xml contains feature javaee-8.0, and the liberties’ JAXB implementation wlp-19.0.0.9\lib\com.ibm.ws.jaxb.tools.2.2.10_1.0.32.jar contains the class com.sun..xml.bind.marshaller.NamespacePrefixMapper.
I tried to solve it by putting the jaxb-impl-2.2.4.jar to the EAR/lib (which is the wrong way because JAXB is provided by JEE) but then an error occurred in the com.sun.xml.bind.v2.runtime.MarshallerImpl.setProperty(MarshallerImpl.java:511) because the check if(!(value instanceof NamespacePrefixMapper)) failed, because the Classloader (AppClassLoader) of the implementation provided another class object for class NamespacePrefixMapper than the MarshallerImpls’ classloader (org.eclipse.osgi.internal.loader.EquinoxClassLoader). But this showed that the liberty can access the the NamespacePrefixMapper.
I made several attempts to use the same classloader for the implementation and the MarschallerImpl when loading them, and I tried to solve it by classloder settings in the server.xml. No success.
I know that it is not recommended to use such JAXB implementation specific classes, but the application was developed this way and cannot be changed easily.
Any help is appreciated which tells me how to convince liberty to either provide the NamespacePrefixMapper class to the application classloader, or to use the application classloaders NamespacePrefixMapper also in the MarschallerImpl.
Thank you.
//The implementation class looks for example like this:
public class MyNamespacePrefixMapperImpl extends com.sun.xml.bind.marshaller.NamespacePrefixMapper {...}
JAXBContext c = JAXBContext.newInstance(some mapped class);
Marshaller m = c.createMarshaller();
com.sun.xml.bind.marshaller.NamespacePrefixMapper mapper = new MyNamespacePrefixMapperImpl();// Here the NoClassDefFoundError occurs.
m.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper); // Here the instanceof check fails if jaxb-impl.jar is in EAR/lib.
this is a precarious situation without an easy solution. Liberty attempts to "hide" internal packages to avoid scenarios where users want a slightly different version of the implementation than what the framework provides - the most glaring example of this problem was in traditional WAS where users wanted to use a different version of Jakarta Commons Logging than what was shipped with WAS - this required users to provide their own, either in an isolated shared library, or use other parent-last classloading hacks to make it work. Liberty avoids those issues by isolating the internal implementations from the user applications.
So that works great when a user wants to use a different version of a third party library than what Liberty provides, but as you have discovered, that doesn't work so great when your legacy application depends on those hidden/isolated third party libraries.
The most ideal solution would be to refactor the application code so as to not depend on internal JAXB classes - somebody with more JAXB expertise may be able to help with this... But it sounds like that may not be feasible, so another alternative would be to create a user feature. A user feature is essentially an extension to Liberty's runtime - so it has access to packages that user applications do not. It also allows you to add packages as APIs for the user applications - so you could use a user feature to add the com.sun.xml.bind.marshaller as a public API - then your user application could extend it freely. You could also include your MyNamespacePrefixMapperImpl class in your user feature and register it there so that it would automatically apply to all applications in your server.
You can find more information on user features here:
https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_feat_example.html
Hope this helps, Andy

Why can i not cast a class to the same type of class | java.lang.ClassCastException [duplicate]

I have 2 different Java projects, one has 2 classes: dynamicbeans.DynamicBean2 and dynamic.Validator.
On the other project, I load both of these classes dynamically and store them on an Object
class Form {
Class beanClass;
Class validatorClass;
Validator validator;
}
I then go ahead and create a Validator object using validatorClass.newInstance() and store it on validator then I create a bean object as well using beanClass.newInstance() and add it to the session.
portletRequest.setAttribute("DynamicBean2", bean);
During the lifecycle of the Form project, I call validator.validate() which loads the previously created bean object from the session (I'm running Websphere Portal Server). When I try to cast this object back into a DynamicBean2 it fails with a ClassCastException.
When I pull the object back out of the session using
faces.getApplication().createValueBinding("#{DynamicBean2}").getValue(faces);
and check the class of it using .getClass() I get dynamicbeans.DynamicBean2. This is the class I want to cast it to however when I try I get the ClassCastException.
Any reason why I'm getting this?
I am not quite following your description of the program flow, but usually when you get ClassCastExceptions you cannot explain you have loaded the class with one classloader then try to cast it to the same class loaded by another classloader. This will not work - they are represented by two different Class objects inside the JVM and the cast will fail.
There is an article about classloading in WebSphere. I cannot say how it applies to your application, but there are a number of possible solutions. I can think of at least:
Change the context class loader manually. Requires that you can actually get a reference to an appropriate class loader, which may not be possible in your case.
Thread.currentThread().setContextClassLoader(...);
Make sure the class is loaded by a class loader higher in the hierarchy.
Serialize and deserialize the object. (Yuck!)
There is probably a more appropriate way for your particular situation though.
I was getting this problem after adding a dependency to spring-boot-devtools in my Springboot project. I removed the dependency and the problem went away. My best guess at this point is that spring-boot-devtools brings in a new classloader and that causes the issue of class casting problems between different classloaders in certain cases where the new classloader is not being used by some threads.
Reference: A dozer map exception related to Spring boot devtools
The class objects were loaded in different classloaders, therefore the instances created from in each of classes are seen as 'incompatible'. This is a common issue in a an environment where there are many different classloaders being used and objects are being passed around. These issues can easily arise in Java EE and portal environments.
Casting an instance of a class requires that the Class linked to the object being casted is the same as the one loaded by the current thread context classloader.
I got the A2AClassCastException problem when trying to create a List of objects from XML using Apache Commons Digester.
List<MyTemplate> templates = new ArrayList<MyTemplate>();
Digester digester = new Digester();
digester.addObjectCreate("/path/to/template", MyTemplate.class);
digester.addSetNext("/path/to/template", "add");
// Set more rules...
digester.parse(f); // f is a pre-defined File
for(MyTemplate t : templates) { // ClassCastException: Cannot cast mypackage.MyTemplate to mypackage.MyTemplate
// Do stuff
}
As stated above, the cause is that the digester doesn't use the same ClassLoader as the rest of the program. I ran this in JBoss, and it turned out that commons-digester.jar was not in JBoss's lib directory, but rather in a webapp's lib directory. Copying the jar into mywebapp/WEB-INF/lib also solved the problem. Another solution was to casll digester.setClassLoader(MyTemplate.class.getClassLoader()), but that feels like quite an ugly solution in this context.
Had the same my.package.MyClass cannot be cast to my.package.MyClass on WildFly 10.1 and, as I understand, I did the opposite to what #Emil Lundberg described in his answer.
I have added the module (which contains my.package.MyClass) to my.war/WEB-INF/jboss-deployment-structure.xml as a dependency
<dependencies>
...
<module name="my.package"/>
</dependencies>
and removed the corresponding jar from my.war/WEB-INF/lib, re-deployed the WAR and then the code worked as expected.
Thus, we made sure it solves the issue. Now, we need to make sure the issue won't come back, for example, when the updated version of WAR will be assembled and deployed.
For this, in the sources of those WAR, it is required to add <scope>provided</scope> for those jar in pom.xml, so that when my.war is re-assembled next time with the fix/enhancement code injected, it will not bundle this jar into my.war/WEB-INF/lib.
I had the same issue while using several JBoss instances on different machines. To bad I didn't stumble across this post earlier.
There were artifacts deployed on different machines, two of them declared class loaders with identical name.I changed one of the classloader names and everything worked fine => Beware of Copy&Paste!
Why doesn't the ClassCastException thrown mention the involved class loaders? - I think that would be very useful information.
Does anyone know if there will be anything like this available in the future? Needing to check the class loaders of 20-30 Artifacts is not that pleasant. Or is there something I missed in the exception text?
EDIT: I edited the META-INF/jboss-app.xml file and changed the name of the loader, the idea is to have a unique name. At work we use the artifact id(unique) combined with the version inserted by maven({$version}) during the build. Using dynamic fields is only optional but helps if you want to deploy different versions of the same application.
<jboss-app>
<loader-repository>
com.example:archive=unique-archive-name-{$version}
</loader-repository>
</jboss-app>
You can find some info here: https://community.jboss.org/wiki/ClassLoadingConfiguration
I had the same issue, and I finally found a workaround on java.net :
Copy all org.eclipse.persistence jar files from glassfish4/glassfish/modules to WEB-INF/lib. Then go in your glassfish-web.xml, and set class-delegate to false.
Worked for me !
I had a similar issue with JAXB and JBoss AS 7.1. The issue and solution are described here: javax.xml.bind.JAXBException: Class *** nor any of its super class is known to this context. The exception that was given was org.foo.bar.ValueSet cannot be cast to org.foo.bar.ValueSet
I had the same issue on a wildfly EJB, The EJB was returning a list of Objects and has an remote and a local interface. I used the Local interface by mistake what was working just fine up until the point you try to cast the objects in the list.
Local/Remote interface:
public interface DocumentStoreService {
#javax.ejb.Remote
interface Remote extends DocumentStoreService {
}
#javax.ejb.Local
interface Local extends DocumentStoreService {
}
The EJB bean:
#Stateless
public class DocumentStoreServiceImpl implements DocumentStoreService.Local, DocumentStoreService.Remote {
The correct spring wrapper around the EJB:
<bean id="documentStoreService" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="java:global/dpc/dpc-ejb/DocumentStoreServiceImpl!santam.apps.dpc.service.DocumentStoreService$Remote"/>
<property name="businessInterface" value="santam.apps.dpc.service.DocumentStoreService$Remote"/>
<property name="resourceRef" value="true" />
</bean>
Note the $Remote, You can change this to $Local and it will find the Local interface just fine, and also execute the methods without any issue (from a separate application on the same container), but the model objects are not marshaled and are from a different class loader if you use the local interface by mistake.
Another option:
Happened to me in weblogic, but I guess it can happen in other servers as well - if you do (just) "Publish" and therefor some of your classes are re-loaded. Instead do "Clean" so all the classes will re-loaded together.
I had same problem with an EJB lookup from another EJB.
I solved adding #Remote(MyInterface.class) to EJB class configuration

Why can't I cast my object to itself? [duplicate]

I have 2 different Java projects, one has 2 classes: dynamicbeans.DynamicBean2 and dynamic.Validator.
On the other project, I load both of these classes dynamically and store them on an Object
class Form {
Class beanClass;
Class validatorClass;
Validator validator;
}
I then go ahead and create a Validator object using validatorClass.newInstance() and store it on validator then I create a bean object as well using beanClass.newInstance() and add it to the session.
portletRequest.setAttribute("DynamicBean2", bean);
During the lifecycle of the Form project, I call validator.validate() which loads the previously created bean object from the session (I'm running Websphere Portal Server). When I try to cast this object back into a DynamicBean2 it fails with a ClassCastException.
When I pull the object back out of the session using
faces.getApplication().createValueBinding("#{DynamicBean2}").getValue(faces);
and check the class of it using .getClass() I get dynamicbeans.DynamicBean2. This is the class I want to cast it to however when I try I get the ClassCastException.
Any reason why I'm getting this?
I am not quite following your description of the program flow, but usually when you get ClassCastExceptions you cannot explain you have loaded the class with one classloader then try to cast it to the same class loaded by another classloader. This will not work - they are represented by two different Class objects inside the JVM and the cast will fail.
There is an article about classloading in WebSphere. I cannot say how it applies to your application, but there are a number of possible solutions. I can think of at least:
Change the context class loader manually. Requires that you can actually get a reference to an appropriate class loader, which may not be possible in your case.
Thread.currentThread().setContextClassLoader(...);
Make sure the class is loaded by a class loader higher in the hierarchy.
Serialize and deserialize the object. (Yuck!)
There is probably a more appropriate way for your particular situation though.
I was getting this problem after adding a dependency to spring-boot-devtools in my Springboot project. I removed the dependency and the problem went away. My best guess at this point is that spring-boot-devtools brings in a new classloader and that causes the issue of class casting problems between different classloaders in certain cases where the new classloader is not being used by some threads.
Reference: A dozer map exception related to Spring boot devtools
The class objects were loaded in different classloaders, therefore the instances created from in each of classes are seen as 'incompatible'. This is a common issue in a an environment where there are many different classloaders being used and objects are being passed around. These issues can easily arise in Java EE and portal environments.
Casting an instance of a class requires that the Class linked to the object being casted is the same as the one loaded by the current thread context classloader.
I got the A2AClassCastException problem when trying to create a List of objects from XML using Apache Commons Digester.
List<MyTemplate> templates = new ArrayList<MyTemplate>();
Digester digester = new Digester();
digester.addObjectCreate("/path/to/template", MyTemplate.class);
digester.addSetNext("/path/to/template", "add");
// Set more rules...
digester.parse(f); // f is a pre-defined File
for(MyTemplate t : templates) { // ClassCastException: Cannot cast mypackage.MyTemplate to mypackage.MyTemplate
// Do stuff
}
As stated above, the cause is that the digester doesn't use the same ClassLoader as the rest of the program. I ran this in JBoss, and it turned out that commons-digester.jar was not in JBoss's lib directory, but rather in a webapp's lib directory. Copying the jar into mywebapp/WEB-INF/lib also solved the problem. Another solution was to casll digester.setClassLoader(MyTemplate.class.getClassLoader()), but that feels like quite an ugly solution in this context.
Had the same my.package.MyClass cannot be cast to my.package.MyClass on WildFly 10.1 and, as I understand, I did the opposite to what #Emil Lundberg described in his answer.
I have added the module (which contains my.package.MyClass) to my.war/WEB-INF/jboss-deployment-structure.xml as a dependency
<dependencies>
...
<module name="my.package"/>
</dependencies>
and removed the corresponding jar from my.war/WEB-INF/lib, re-deployed the WAR and then the code worked as expected.
Thus, we made sure it solves the issue. Now, we need to make sure the issue won't come back, for example, when the updated version of WAR will be assembled and deployed.
For this, in the sources of those WAR, it is required to add <scope>provided</scope> for those jar in pom.xml, so that when my.war is re-assembled next time with the fix/enhancement code injected, it will not bundle this jar into my.war/WEB-INF/lib.
I had the same issue while using several JBoss instances on different machines. To bad I didn't stumble across this post earlier.
There were artifacts deployed on different machines, two of them declared class loaders with identical name.I changed one of the classloader names and everything worked fine => Beware of Copy&Paste!
Why doesn't the ClassCastException thrown mention the involved class loaders? - I think that would be very useful information.
Does anyone know if there will be anything like this available in the future? Needing to check the class loaders of 20-30 Artifacts is not that pleasant. Or is there something I missed in the exception text?
EDIT: I edited the META-INF/jboss-app.xml file and changed the name of the loader, the idea is to have a unique name. At work we use the artifact id(unique) combined with the version inserted by maven({$version}) during the build. Using dynamic fields is only optional but helps if you want to deploy different versions of the same application.
<jboss-app>
<loader-repository>
com.example:archive=unique-archive-name-{$version}
</loader-repository>
</jboss-app>
You can find some info here: https://community.jboss.org/wiki/ClassLoadingConfiguration
I had the same issue, and I finally found a workaround on java.net :
Copy all org.eclipse.persistence jar files from glassfish4/glassfish/modules to WEB-INF/lib. Then go in your glassfish-web.xml, and set class-delegate to false.
Worked for me !
I had a similar issue with JAXB and JBoss AS 7.1. The issue and solution are described here: javax.xml.bind.JAXBException: Class *** nor any of its super class is known to this context. The exception that was given was org.foo.bar.ValueSet cannot be cast to org.foo.bar.ValueSet
I had the same issue on a wildfly EJB, The EJB was returning a list of Objects and has an remote and a local interface. I used the Local interface by mistake what was working just fine up until the point you try to cast the objects in the list.
Local/Remote interface:
public interface DocumentStoreService {
#javax.ejb.Remote
interface Remote extends DocumentStoreService {
}
#javax.ejb.Local
interface Local extends DocumentStoreService {
}
The EJB bean:
#Stateless
public class DocumentStoreServiceImpl implements DocumentStoreService.Local, DocumentStoreService.Remote {
The correct spring wrapper around the EJB:
<bean id="documentStoreService" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="java:global/dpc/dpc-ejb/DocumentStoreServiceImpl!santam.apps.dpc.service.DocumentStoreService$Remote"/>
<property name="businessInterface" value="santam.apps.dpc.service.DocumentStoreService$Remote"/>
<property name="resourceRef" value="true" />
</bean>
Note the $Remote, You can change this to $Local and it will find the Local interface just fine, and also execute the methods without any issue (from a separate application on the same container), but the model objects are not marshaled and are from a different class loader if you use the local interface by mistake.
Another option:
Happened to me in weblogic, but I guess it can happen in other servers as well - if you do (just) "Publish" and therefor some of your classes are re-loaded. Instead do "Clean" so all the classes will re-loaded together.
I had same problem with an EJB lookup from another EJB.
I solved adding #Remote(MyInterface.class) to EJB class configuration

SerializationPolicy error when performing RPC from within GWT application

I'm getting the following exception:
com.google.gwt.user.client.rpc.SerializationException: Type 'java.lang.Long' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized
using GWT 2.1 and the built in Jetty server. According to the docs, this type is definitely serializable... How can I include it in the SerializationPolicy?
Here's the link that should resolve problem:
http://developerlife.com/tutorials/?p=131
A user defined class is serializable if:
the class is assignable to IsSerializable or java.io.Serializable, either because it implements one of these interfaces, or because it is derived from a superclass that implements one of these interfaces.
all the class’s non-final, non-transient instance fields are serializable
the class has a public default (zero argument) constructor
Needed include a superfluous method in the RPC service that "whitelists" a number of objects. This arises because of the use of generics, GWT is unable to necessarily determine which object I may be serializing to include within some generic.
I included all of the types that may need to be (un)serialized as members of an object (SerializableWhitelist). I added a method to the RPC servlet object like:
public SerializableWhitelist junk(SerializableWhitelist l) { return null; }
It's worth noting that you need to include the whitelist datatypes as both an argument and as the return type, as GWT apparently maintains two separate serialization policies.
Try deleting the *.gwt.rpc files in your war/app directory, clean and rebuild.
One thing to note: you should avoid long or Long if possible because they are
emulated on GWT (because there is no native Javascript long) and very
slow. Use int instead where ever you can.
FYI I've raised this as a GWT bug: http://code.google.com/p/google-web-toolkit/issues/detail?id=5811
We'll see what they say.
FWIW, I was having this problem but my 'Object' type was hidden behind generified classes. The error message itself was wrong.
So if one of your rpc methods involves a class:
class Xxx<T> implements IsSerializable {...
It needs to change to:
class Xxx<T extends IsSerializable> implements IsSerializable {...
The problem can also be because the code on your local machine on which you are running hosted mode is not the same as the one on the external server you are connecting to via RPC. So in my case i was missing a git pull on my local machine to match what was deployed on the external server. The changes were minimal, just a new property in one of the classes that were included in the gwt.rpc, but this was already sufficient that the gwt.rpc md5 filenames were different and thus the above mentioned error occurred.
Inspired by http://groups.google.com/group/google-web-toolkit/browse_thread/thread/7dd5123d359ddfa8
Using eclipse and maven and gwt 2.1.1
Compile and deploy gwt war.
Try using OOPHM launched from Eclipse. This would fail for me.
This will generate in server logs:
ERROR: The serialization policy file 'blah.gwt.rpc' was not found; did you forget to include it in this deployment?
WARNING: Failed to get the SerializationPolicy '94DEC228B2828D3A5897FEE3D6845A40' for module 'http://blah:8080/BlahUI/BlahUI/'; a legacy, 1.3.3 compatible, serialization policy will be used. You may experience SerializationExceptions as a result.
And then
Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: Type '[LpathToClass;' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer.For security purposes, this type will not be serialized.: instance = [LpathToClass;#9d524af
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:614)
Now that extra gwt.rpc files have been generated (either by eclipse/maven plugin who knows?)
Recompile (even a clean compile will work because the gwt.rpc files are not in the target folder, my OOPHM gwt.rpc files are at same folder as entrypoint html) and redeploy. This new war file will contain the generated gwt.rpc files.
Relaunch OOPHM from Eclipse. Works for me.
Another FWIW: I believe I cleared up a similar problem in an enum class by changing
the access modifier of the single, one argument constructor from default (no modifier)
to 'private'. In any event, doing that didn't break it because it's working that way now.
I faced this error and got stuck for 1 day completely. Then I came to across following quick solution:
Make sure your DTOs or Entities classes following the serializable interface rules.
Its the the only thing you need to do because rest of the issues will be with your build creation.
So if you are using maven then make sure do clean build and clear all browser cache.
I resolved my issues with this. I hope it will help. Thanks!
Make sure that the class is in shared folder.
This is what I was Missing.

Can i deny access to a jvm class by configuring java.policy file?

I wanted to add to my jdk6\jre\lib\security\java.policy file an interdiction to create some classes that are blacklisted by appengine. For example I want my local jvm to throw an exception when the application tries to instantiate javax.naming.NamingException.
It is possible?
I will try to explain my specific problem here. Google offers an service (GAE-google app engine) that has some limitations on what classes can be used. For example doesn't instantiate JNDI classes that are in javax.naming package. They also offer an testing server that can be used to tests this application on my machine, but this server allows such classes and can exacute the code. You find out that you used a blacklisted class only after you upload your application to google. I was thinking if such class blacklist enforcement couldn't be done on the development jvm. Else i'm thinking that this would be easy they might already provide such a policy file.
You could write a small loader application that creates a new, custom classloader. Your application classes could then be loaded using this classloader.
In the custom classloader, you can then throw ClassNotFoundException when your application tries to access a class that you want to blacklist.
You will need to overload the load() method. This method will be responsible for throwing the exception on your blacklisted classes ordelegating to the parent Classloader if the class is allowed. A sample implementation:
public Class loadClass(String name) throws ClassNotFoundException {
if(name.equals("javax.lang.ClassIDontLike")){
throw new ClassNotFoundException("I'm sorry, Dave. I'm afraid I can't do that.");
}
return super.loadClass(name, false);
}
(Of course, a real implementation can be way more sophisticated than this)
Because the classes of your application are loaded through this Classloader, and you are only delegating the loadClass() invokations to the parent classloader when you want to, you can blacklist any classes that you need.
I am pretty sure that this is the method that Google uses to blacklist classes in their server. They load every app in a specific Classloader. This is also similar to the way that Tomcat isolates the different Web Applications.
Wouldn't you rather get compilation errors than runtime errors while testing your program? You could configure your IDE or compiler to warn you when an undesired class is instantiated. I know AspectJ has some nice features for this: You can define compilation warnings/errors on join points and get feedback in e.g. Eclipse. To use this in Eclipse, you simply install the AspectJ plugin and write a suitable aspect. To get the errors while compiling from a command line or script, you would actually have to use the AspectJ compiler, but I doubt that you would need that.
The Java documentation lists all possible policy permissions here:
http://java.sun.com/javase/6/docs/technotes/guides/security/permissions.html
Class creation / loading is not mentioned, so I believe you cannot enforce this using a policy.
At any rate, why do you want to throw an exception when an exception class is loaded? Maybe you could explain your problem, then someone might be able to propose a solution.
Edit:
One way to prevent loading of certain classes would be to remove them from the JRE installation. Most system classes are contained in rt.jar in your JDK/JRE installation. You should be able to modify it with any ZIP-tool.
Just create a special installation of your JRE, and modify its rt.jar. That is an ugly hack, but should be OK for testing purposes...

Categories