Pregunta

Tengo 2 proyectos Java diferentes, uno tiene 2 clases: dynamicbeans.DynamicBean2 y dynamic.Validator.

En el otro proyecto, cargo ambas clases dinámicamente y las almaceno en un Object

class Form {
    Class beanClass;
    Class validatorClass;
    Validator validator;
}

Luego sigo adelante y creo un Validator objeto usando validatorClass.newInstance() y guárdelo en validator luego creo un objeto bean también usando beanClass.newInstance() y agregarlo a la sesión.

portletRequest.setAttribute("DynamicBean2", bean);

Durante el ciclo de vida del Form proyecto, llamo validator.validate() que carga el objeto bean creado previamente desde la sesión (estoy ejecutando Websphere Portal Server).Cuando intento devolver este objeto a un DynamicBean2 falla con una ClassCastException.

Cuando saco el objeto de la sesión usando

faces.getApplication().createValueBinding("#{DynamicBean2}").getValue(faces);

y verifique su clase usando .getClass() yo obtengo dynamicbeans.DynamicBean2.Esta es la clase a la que quiero transmitirlo; sin embargo, cuando lo intento, obtengo ClassCastException.

¿Alguna razón por la que recibo esto?

¿Fue útil?

Solución

No estoy siguiendo su descripción del flujo del programa, pero por lo general, cuando obtiene ClassCastExceptions, no puede explicar que ha cargado la clase con un cargador de clases y luego intente convertirla en la misma clase cargada por otro cargador de clases. Esto no funcionará: están representados por dos objetos de clase diferentes dentro de la JVM y el reparto fallará.

Hay un artículo sobre la carga de clases en WebSphere . No puedo decir cómo se aplica a su aplicación, pero hay varias soluciones posibles. Puedo pensar en al menos:

  1. Cambia el cargador de clases de contexto manualmente. Requiere que realmente pueda obtener una referencia a un cargador de clases apropiado, que puede no ser posible en su caso.

    Thread.currentThread().setContextClassLoader(...);
    
  2. Asegúrese de que la clase esté cargada por un cargador de clases más alto en la jerarquía.

  3. Serializar y deserializar el objeto. (¡Qué asco!)

Sin embargo, probablemente haya una forma más apropiada para su situación particular.

Otros consejos

Los objetos de clase se cargaron en diferentes cargadores de clases, por lo tanto, las instancias creadas a partir de cada una de las clases se consideran "incompatibles". Este es un problema común en un entorno donde se utilizan muchos cargadores de clases diferentes y se pasan objetos. Estos problemas pueden surgir fácilmente en Java EE y en entornos de portal.

Lanzar una instancia de una clase requiere que la Clase vinculada al objeto que se está fundiendo sea la misma que la cargada por el actual cargador de clases de contexto de hilo.

Obtuve el problema A2AClassCastException al intentar crear una Lista de objetos desde XML usando 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
}

Como se indicó anteriormente, la causa es que el digestor no usa el mismo ClassLoader que el resto del programa. Ejecuté esto en JBoss, y resultó que commons-digester.jar no estaba en el directorio lib de JBoss, sino en el directorio lib de una aplicación web. Copiar el jar en mywebapp / WEB-INF / lib también resolvió el problema. Otra solución fue llamar a digester.setClassLoader (MyTemplate.class.getClassLoader ()), pero parece una solución bastante fea en este contexto.

Tuve el mismo problema al usar varias instancias de JBoss en diferentes máquinas. Que mal que no me encontré con esta publicación anterior.
Hubo artefactos desplegados en diferentes máquinas, dos de ellos declararon cargadores de clases con un nombre idéntico. Cambié uno de los nombres del cargador de clases y todo funcionó bien = & Gt; Cuidado con Copy & Amp; Paste!

¿Por qué la clase ClassCastException lanzada no menciona los cargadores de clases involucrados? - Creo que sería una información muy útil.
¿Alguien sabe si habrá algo como esto disponible en el futuro? La necesidad de revisar los cargadores de clase de 20-30 artefactos no es tan agradable. ¿O hay algo que me perdí en el texto de excepción?

EDITAR : edité el archivo META-INF / jboss-app.xml y cambié el nombre del cargador, la idea es tener un nombre único. En el trabajo, utilizamos la identificación del artefacto (única) combinada con la versión insertada por maven ({$ versión}) durante la compilación.
El uso de campos dinámicos solo es opcional, pero ayuda si desea implementar diferentes versiones de la misma aplicación.

<jboss-app>
   <loader-repository> 
   com.example:archive=unique-archive-name-{$version}
   </loader-repository> 
</jboss-app>

Puede encontrar información aquí: https://community.jboss.org/wiki/ClassLoadingConfiguration

Tuve el mismo problema y finalmente encontré una solución en java.net:

Copie todo org.eclipse.persistence jar archivos de glassfish4/glassfish/modules a WEB-INF/lib.Entonces entra en tu glassfish-web.xml, y establecer class-delegate a false.

Trabajó para mi !

Tuve un problema similar con JAXB y JBoss AS 7.1. El problema y la solución se describen aquí: javax.xml.bind.JAXBException: Class *** ni ninguna de sus superclases es conocida en este contexto . La excepción que se dio fue org.foo.bar.ValueSet no se puede enviar a org.foo.bar.ValueSet

Tuve el mismo problema en un EJB wildfly, el EJB estaba devolviendo una lista de objetos y tiene una interfaz remota y local. Utilicé la interfaz local por error, lo que funcionaba bien hasta el momento en que intentas lanzar los objetos en la lista.

Interfaz local / remota:

public interface DocumentStoreService {

    @javax.ejb.Remote
    interface Remote extends DocumentStoreService {
    }

    @javax.ejb.Local
    interface Local extends DocumentStoreService {
    }

El bean EJB:

@Stateless
public class DocumentStoreServiceImpl implements DocumentStoreService.Local, DocumentStoreService.Remote {

El envoltorio de resorte correcto alrededor del 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>

Tenga en cuenta el $ Remote, puede cambiar esto a $ Local y encontrará la interfaz Local bien, y también ejecutará los métodos sin ningún problema (desde una aplicación separada en el mismo contenedor), pero los objetos del modelo no son si se utiliza la interfaz local por error.

Otra opción:

Me pasó en weblogic, pero supongo que también puede ocurrir en otros servidores, si lo hace (solo) " Publish " y por eso algunas de tus clases se vuelven a cargar. En su lugar, haga & Quot; Clean & Quot; para que todas las clases se vuelvan a cargar juntas.

Tuve el mismo problema con una búsqueda EJB de otro EJB. Resolví agregar @Remote (MyInterface.class) a la configuración de clase EJB

Tenía el mismo my.package.MyClass cannot be cast to my.package.MyClass en WildFly 10.1 y, según tengo entendido, hice lo contrario de lo que @Emil Lundberg describió en su respuesta.

He agregado el módulo (que contiene my.package.MyClass) a my.war/WEB-INF/jboss-deployment-structure.xml como dependencia

<dependencies>
    ...
    <module name="my.package"/>
</dependencies>

y eliminó el jar correspondiente de my.war/WEB-INF/lib, volvió a implementar WAR y luego el código funcionó como se esperaba.

Por lo tanto, nos aseguramos de que resuelva el problema. Ahora, debemos asegurarnos de que el problema no vuelva, por ejemplo, cuando la versión actualizada de WAR se ensamble y se implemente.

Para esto, en las fuentes de esos WAR , se requiere agregar <scope>provided</scope> para esos jar en pom.xml, de modo que cuando my.war sea reensamblado la próxima vez con el código de reparación / mejora inyectado, no agrupará este jar en <=>.

Estaba teniendo este problema después de agregar una dependencia a spring-boot-devtools en mi proyecto Springboot. Eliminé la dependencia y el problema desapareció. Mi mejor conjetura en este punto es que <=> trae un nuevo cargador de clases y eso causa el problema de problemas de conversión de clases entre diferentes cargadores de clases en ciertos casos donde el nuevo cargador de clases no está siendo utilizado por algunos hilos.

Referencia: Una excepción de mapa dozer relacionada con las herramientas de arranque de Spring

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top