Question

J'ai 2 projets Java différents, dont 2 classes: dynamicbeans.DynamicBean2 et dynamic.Validator.

Sur l'autre projet, je charge ces deux classes de manière dynamique et les stocke sur un Object

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

Ensuite, créez un objet Validator à l'aide de validatorClass.newInstance() et stockez-le sur validator, puis créez un objet bean à l'aide de beanClass.newInstance() et ajoutez-le à la session.

portletRequest.setAttribute("DynamicBean2", bean);

Pendant le cycle de vie du projet Form, j'appelle validator.validate(), ce qui charge l'objet bean créé précédemment à partir de la session (j'utilise Websphere Portal Server). Lorsque j'essaie de reconvertir cet objet en DynamicBean2, il échoue avec un ClassCastException.

Lorsque je retire l'objet de la session en utilisant

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

et vérifiez sa classe en utilisant .getClass() je reçois <=>. C’est la classe sur laquelle je veux le lancer, mais lorsque j’essaie, j’obtiens la ClassCastException.

Une raison pour laquelle je reçois ceci?

Était-ce utile?

La solution

Je ne suis pas tout à fait à la suite de votre description du flux du programme, mais généralement, lorsque vous obtenez ClassCastExceptions, vous ne pouvez pas expliquer que vous avez chargé la classe avec un chargeur de classe, puis essayez de le lancer dans la même classe que celle chargée par un autre chargeur de classe. Cela ne fonctionnera pas. Ils sont représentés par deux objets de classe différents dans la machine virtuelle et l'échec de la distribution.

Il existe un article sur le chargement de classes dans WebSphere Je ne peux pas dire comment cela s’applique à votre demande, mais il existe un certain nombre de solutions possibles. Je peux au moins penser à:

  1. Modifiez le chargeur de classe de contexte manuellement. Nécessite que vous puissiez réellement obtenir une référence à un chargeur de classes approprié, ce qui peut ne pas être possible dans votre cas.

    Thread.currentThread().setContextClassLoader(...);
    
  2. Assurez-vous que la classe est chargée par un chargeur de classes plus haut dans la hiérarchie.

  3. Sérialiser et désérialiser l'objet. (Beurk!)

Cependant, il existe probablement un moyen plus approprié pour votre situation particulière.

Autres conseils

Les objets de classe ont été chargés dans différents chargeurs de classes. Par conséquent, les instances créées dans chacune des classes sont considérées comme "incompatibles". Il s'agit d'un problème courant dans un environnement où de nombreux chargeurs de classes sont utilisés et où des objets sont en train d'être échangés. Ces problèmes peuvent facilement survenir dans Java EE et les environnements de portail.

Le casting d'une instance d'une classe nécessite que la classe liée à l'objet en cours de conversion soit identique à celle chargée par le chargeur de classe de contexte de thread actuel.

J'ai eu le problème A2AClassCastException lors de la création d'une liste d'objets à partir de XML à l'aide d'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
}

Comme indiqué ci-dessus, la cause en est que le digesteur n'utilise pas le même ClassLoader que le reste du programme. J'ai exécuté cela dans JBoss, et il s'est avéré que commons-digester.jar n'était pas dans le répertoire lib de JBoss, mais plutôt dans le répertoire lib d'une application Web. Copier le pot dans mywebapp / WEB-INF / lib a également résolu le problème. Une autre solution consistait à digérer digester.setClassLoader (MyTemplate.class.getClassLoader ()), mais cela semble être une très mauvaise solution dans ce contexte.

J'ai eu le même problème lors de l'utilisation de plusieurs instances de JBoss sur différentes machines. Dommage que je ne sois pas tombé sur ce message plus tôt.
Des artefacts ont été déployés sur différentes machines, deux d'entre eux ont été déclarés comme étant des chargeurs de classe avec un nom identique. J'ai changé l'un des noms de chargeur de classe et tout a bien fonctionné = & Gt; Attention à la copie & Et au collage!

Pourquoi l’exception ClassCastException levée ne mentionne-t-elle pas les chargeurs de classe impliqués? - Je pense que ce serait une information très utile.
Est-ce que quelqu'un sait s'il y aura quelque chose comme ça disponible dans le futur? Avoir besoin de vérifier les chargeurs de classe de 20-30 Artefacts n’est pas si agréable. Ou y a-t-il quelque chose qui m'a échappé dans le texte de l'exception?

MODIFIER : j'ai modifié le fichier META-INF / jboss-app.xml et modifié le nom du chargeur. L'idée est d'avoir un nom unique. Au travail, nous utilisons l'identifiant d'artefact (unique) combiné à la version insérée par maven ({$ version}) lors de la construction.
L'utilisation de champs dynamiques est uniquement facultative, mais vous aidera si vous souhaitez déployer différentes versions de la même application.

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

Vous trouverez quelques informations ici: https://community.jboss.org/wiki/ClassLoadingConfiguration" rel="nofollow"> https://community.jboss.org/wiki/ClassLoadingConfiguration"/ a>

J'ai eu le même problème et j'ai finalement trouvé une solution de contournement sur java.net:

Copiez tous les org.eclipse.persistence jar fichiers de glassfish4/glassfish/modules à WEB-INF/lib. Ensuite, allez dans votre glassfish-web.xml, et définissez class-delegate sur false.

Travaillé pour moi!

J'ai eu le même problème sur un EJB wildfly, l'EJB renvoyait une liste d'objets et possède une interface distante et locale. J'ai utilisé l'interface locale par erreur, ce qui fonctionnait parfaitement jusqu'au moment où vous essayez de convertir les objets de la liste.

Interface locale / distante:

public interface DocumentStoreService {

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

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

Le haricot EJB:

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

L'emballage à ressort correct autour de l'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>

Notez le $ Remote, vous pouvez le changer en $ Local et il trouvera l’interface locale très bien, et aussi exécuter les méthodes sans aucun problème (à partir d’une application séparée sur le même conteneur), mais les objets de modèle ne sont pas marshaled et proviennent d'un autre chargeur de classes si vous utilisez l'interface locale par erreur.

Une autre option:

m'est arrivé dans weblogic, mais je suppose que cela peut également se produire sur d'autres serveurs - si vous le faites (seulement) & "Publier &"; et par conséquent certaines de vos classes sont rechargées. Au lieu de cela, faites & Quot; Nettoyer & Quot; donc toutes les classes seront rechargées ensemble.

J'ai eu le même problème avec une recherche EJB auprès d'un autre EJB. J'ai résolu d'ajouter @Remote (MyInterface.class) à la configuration de classe EJB

J'ai eu la même chose my.package.MyClass cannot be cast to my.package.MyClass sur WildFly 10.1 et, si j'ai bien compris, j'ai fait l'inverse de ce que @ Emil Lundberg a décrit dans sa réponse.

J'ai ajouté le module (qui contient my.package.MyClass) à my.war/WEB-INF/jboss-deployment-structure.xml en tant que dépendance

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

et supprimé le fichier jar correspondant de my.war/WEB-INF/lib, redéployez le fichier WAR, puis le code fonctionne comme prévu.

Nous nous sommes donc assurés que le problème soit résolu. Maintenant, nous devons nous assurer que le problème ne reviendra pas, par exemple, lorsque la version mise à jour de WAR sera assemblée et déployée.

Pour cela, dans les sources de ces WAR , il est nécessaire d'ajouter <scope>provided</scope> pour ces fichiers jar dans pom.xml, de sorte que lorsque my.war est réassemblé la prochaine fois avec le code de correction / amélioration injecté, il ne regroupera pas ce fichier jar dans <=>.

Je rencontrais ce problème après avoir ajouté une dépendance à spring-boot-devtools dans mon projet Springboot. J'ai enlevé la dépendance et le problème est parti. Ma meilleure hypothèse à ce stade est que <=> introduit un nouveau chargeur de classes et que cela pose le problème de transtypage de classes entre différents chargeur de classes dans certains cas où le nouveau chargeur de classes n’est pas utilisé par certains threads.

Référence: Une exception de carte de bulldozer liée à l'outil de démarrage de printemps

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top