Domanda

Ho riscontrato eccezioni occasionali nell'applicazione XPages:

java.lang.ClassCastException: someClass incompatible with someClass.

Entrambe le classi menzionate sono le stesse, è usata come session bean.Non sono stato in grado di cercare su Google nulla che coprisse il mio problema.La spiegazione usuale per questo era il cambiamento negli elementi di design, non il mio caso.

L'applicazione XPage diventa inutilizzabile (pagine che utilizzano il bean di sessione someClass) da quel momento, fino al riavvio dell'attività http o al nuovo salvataggio di faces-config.xml.

In alcuni casi questo è correlato ad altre eccezioni:

com.ibm.jscript.InterpretException: Script interpreter error, line=x, col=y: 
Java method 'method(signature containg someClass)'
on java class 'someOtherClass' not found

Cosa c'è dietro questo comportamento?

È stato utile?

Soluzione

Philippe Riand lo ha spiegato tramite e-mail:

Questo cast di classe si verifica perché la stessa classe è stata caricata due volte da 2 diversi caricatori di classi. Quindi, dal punto di vista di Java, sono diversi e il cast fallisce.

Ora, ogni applicazione XPages ha il proprio classloader. Ma questo programma di caricamento classi viene scartato ogni volta che viene apportata una modifica di progettazione all'applicazione, ad esempio tramite Domino Designer. Ciò è necessario poiché una modifica a un XPages genera una nuova classe Java che dovrebbe quindi essere caricata al posto della precedente. Quando ciò accade, il classloader viene scartato e ne viene creato uno nuovo. Quindi tutte le classi relative all'applicazione vengono ricaricate, poiché sono necessarie, anche se non sono cambiate. Questo è un comportamento comune implementato dai server J2EE. Detto questo, se il codice memorizza nella cache un oggetto in un ambito che non viene scartato quando si verifica una modifica di progettazione, è probabile che ciò accada. Ad esempio, applicationScope e sessionScope non vengono attualmente eliminati quando si verifica una modifica di progettazione, il che potrebbe portare a questo problema. Questa è stata una scelta progettuale poiché scartare gli ambiti a volte fornisce una brutta esperienza per gli sviluppatori, ma con questo inconveniente.

Infine, il salvataggio di faces-config.xml funziona come una soluzione alternativa. Quando questo file viene salvato, l'intero modulo viene scartato dalla memoria, inclusi gli ambiti. Questo spiega perché funziona. Apportare una modifica alla classe Java personalizzata dovrebbe ricaricare il modulo e rimuovere il problema.

Quindi sembra che mettere i bean (anche indirettamente) in sessionScope o applicationScope sia la causa.

Altri suggerimenti

Se lo stesso file di classe viene caricato in diversi programmi di caricamento classi, le due classi Java risultanti non sono la stessa classe;non ti sarebbe permesso passare istanze di uno a funzioni che aspettano l'altro.In genere, se riscontri questo tipo di problema, è perché hai più programmi di caricamento classi figlio che possono accedere a un file jar non visibile al loro comune programma di caricamento classi principale.Potrebbe essere necessario spostare il jar contenente "someclass" in una directory di libreria comune invece che (ad esempio) una directory di webapp specifica.

Sto solo mettendo la mia esperienza qui.

Stavo eseguendo la mia app in un ambiente CAT con più JVM quando ho riscontrato questo problema.Poiché la stessa build veniva eseguita correttamente per me in ambiente ITG, ho riavviato entrambe le JVM su CAT e l'errore è stato risolto.Non sono esattamente sicuro di cosa lo causasse.

Pulendo il progetto anche questo funziona!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top