ClassCastException when casting to the same class

前端 未结 11 764
小蘑菇
小蘑菇 2020-11-22 07:09

I have 2 different Java projects, one has 2 classes: dynamicbeans.DynamicBean2 and dynamic.Validator.

On the other project, I load both of

相关标签:
11条回答
  • 2020-11-22 07:37

    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

    0 讨论(0)
  • 2020-11-22 07:44

    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

    0 讨论(0)
  • 2020-11-22 07:49

    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

    0 讨论(0)
  • 2020-11-22 07:49

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

    0 讨论(0)
  • 2020-11-22 07:55

    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:

    1. 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(...);
      
    2. Make sure the class is loaded by a class loader higher in the hierarchy.

    3. Serialize and deserialize the object. (Yuck!)

    There is probably a more appropriate way for your particular situation though.

    0 讨论(0)
  • 2020-11-22 07:57

    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.

    0 讨论(0)
提交回复
热议问题