java.lang.LinkageError: ClassCastException
Je fais l'expérience d'un vraiment problème ennuyeux avec TestNG et RESTeasy.
J'ai une classe qui gère plusieurs tests à l'encontre d'une classe de l'API qui utilise le RESTeasy-cadre pour exposer lui-même.
Cependant si je laisse l'essai avec maven (mvn test), puis-je obtenir de l'exception suivante:
java.lang.LinkageError: ClassCastException: attempting to castjar:file:/C:/Users/rit/.m2/repository/org/jboss/resteasy/jaxrs-api/2.3.0.GA/jaxrs-api-2.3.0.GA.jar!/javax/ws/rs/ext/RuntimeDelegate.classtojar:file:/C:/Users/rit/.m2/repository/org/jboss/resteasy/jaxrs-api/2.3.0.GA/jaxrs-api-2.3.0.GA.jar!/javax/ws/rs/ext/RuntimeDelegate.class
at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:126)
at javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:96)
at javax.ws.rs.core.Response$ResponseBuilder.newInstance(Response.java:394)
at javax.ws.rs.core.Response.status(Response.java:116)
at javax.ws.rs.core.Response.status(Response.java:130)
at com.pd.api.TokenAPI_V1.validateAccessToken(TokenAPI_V1.java:141)
at com.test.pd.api.TokenAPI_V1Test.testIfValidAccessTokenReturnsCorrectHTTPHeadersWhenTokenIsNotFound(TokenAPI_V1Test.java:359)
Le test n'est rien de plus que d'appeler une méthode de l'API obejct qui retourne un objet Response (à partir de RESTeasy). Comme framework de test je ne l'utilisation de TestNG.
Méthode D'Essai
@Test
public void testIfValidAccessTokenReturnsCorrectHTTPHeadersWhenTokenIsNotFound() throws InvalidAccessTokenException {
Mockito.when(tokenService.validateAccessToken(TestConstants.ACCESS_TOKEN)).thenThrow(new InvalidAccessTokenException());
Response response = tokenAPI_v1.validateAccessToken(TestConstants.ACCESS_TOKEN, TestConstants.USER_AGENT);
assert "no-store".equals(response.getMetadata().getFirst("Cache-Control"));
assert "no-cache".equals(response.getMetadata().getFirst("Pragma"));
}
Description Du Problème
Il ressemble à la RESTeasy cadre charge le RuntimeDelegate dans un autre chargeur de classe. Si je prends un coup d'oeil au code source, puis il y a la méthode suivante à la RuntimeDelegate (qui couvre la ligne 126): RuntimeDelegate.java.
De sorte que le message principal qui est lié à l'erreur est la instanceof vérifier:
if (!(delegate instanceof RuntimeDelegate))
Si je vérifie le chargeur de classe de l'instance de délégué vs le chargeur de classe de la RuntimeDelegate, puis-je obtenir la sortie suivante:
delegate.getClass().getClassLoader() -> org.powermock.core.classloader.MockClassLoader@31e46a68
RuntimeDelegate.class.getClassLoader() -> sun.misc.Launcher$AppClassLoader@3c0fabe9
Je suis conscient de que bien sûr, cela ne fonctionne pas, mais je me demande pourquoi le RESTeasy truc est chargé dans le MockClassLoader et pas dans l'autre. Surtout que je n'ai pas se moquer de la TokenAPI qui est testé.
Faits Étranges
La chose étrange est que lorsque j'exécute les tests de IntelliJ (je choisis uniquement pour exécuter tous les tests de la classe qui contient la méthode qui produit le message d'erreur), alors qu'il traverse. On dirait qu'il est en quelque sorte lié au fait que mvn test s'exécute tous les tests du projet maven (ou du moins c'est ce que je suppose).
Salut rit, cela dépend si ces classes ont été chargées d'abord par le système de chargeur de classe avant ou pas. Votre code certainement référence à certains JAX-WS classes, qui peut faire référence à d'autres classe de JAX-WS. La JVM ne les reliant plus tard pour éviter la charge au moment du démarrage. Ainsi, lorsque ces classes sont utilisées pour la première fois, ils sont chargés par le PowerMock chargeur de classe, mais quand RESTeasy a commencé, il est chargé en utilisant le système de chargeur de classe, puis plus tard de type sont comparées (le instanceof) ils sont différents, parce qu'ils ont été chargés dans le chargeur de classes différentes. Votre solution est la bonne.
Si votre solution est la bonne, vous pouvez répondre à votre propre question.
mvn test peut être demandé à la "fourchette" des essais par la voie.
OriginalL'auteur rit | 2012-01-11
Vous devez vous connecter pour publier un commentaire.
Malheureusement, je ne peux pas vous dire pourquoi cela est arrivé, mais je peux vous dire comment obtenir autour de cette question.
Le problème, c'est que PowerMockito numérisés tha chemin de classe, et a également ajouté la RESTeasy classes (qui sont situés dans le package javax.ws.*'. L'image ci-dessus mentionné RuntimeDelegate a été chargé par la PowerMockito chargeur de classe et a causé le problème, que la classe a été comparé à celui d'un autre chargeur de classe.
Pour contourner ce problème, dites PowerMockito d'ignorer la javax.ws paquet lors de la numérisation pour les classes:
OriginalL'auteur rit
J'ai connu le même problème lors du déploiement de mon application JBoss v6.1 - en quelque sorte compris que le problème était dû à la même structure de paquet de RuntimeDelegate.class existant au sein de jesrey-core et jboss' jaxrs-api pot
Ci-dessous est mon pom.xml
Après ma guerre est déployé pour JBoss, juste enlevé resteasy.deployer dossier de jboss server\default\déployeurs dossier. Couru de ma candidature, et cela a fonctionné.
Je serais heureux si quelqu'un expliquer pourquoi cette erreur a résolu de cette façon? (Je pense que JBoss' a inutilement livré avec resteasy.déployeurs pots lorsque les développeurs pourraient inclure les pots sur leur propre dans leurs applications) - ne Pas cacher que j'ai essayé de déployer ma guerre sur Tomcat et cela a fonctionné sans problème.
OriginalL'auteur Kisanagaram