首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.lang.LinkageError: ClassCastException

java.lang.LinkageError: ClassCastException
EN

Stack Overflow用户
提问于 2012-01-11 17:30:40
回答 3查看 17.5K关注 0票数 13

对于TestNG和RESTeasy,我确实遇到了一个非常烦人的问题。

我确实有一个类,它对一个使用RESTeasy框架公开自身的API类运行几个测试。

但是,如果我允许使用maven (mvn测试)运行测试,则会得到以下异常:

代码语言:javascript
复制
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)

测试只会调用API的一个方法,该方法返回一个响应对象(来自RESTeasy)。作为测试框架,我确实使用了TestNG。

测试方法

代码语言:javascript
复制
@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"));
}

问题描述

看起来,RESTeasy框架将RuntimeDelegate加载到不同的类加载器中。如果我看一下源代码,那么在RuntimeDelegate (包括第126行)中有以下方法:RuntimeDelegate.java

因此,与错误相关的主要语句是instanceof check:

代码语言:javascript
复制
if (!(delegate instanceof RuntimeDelegate))

如果我检查委托实例的类加载程序与RuntimeDelegate的类加载器,则得到以下输出:

代码语言:javascript
复制
delegate.getClass().getClassLoader() -> org.powermock.core.classloader.MockClassLoader@31e46a68

RuntimeDelegate.class.getClassLoader() -> sun.misc.Launcher$AppClassLoader@3c0fabe9

当然,我知道这不起作用,但我想知道为什么RESTeasy内容加载在MockClassLoader中而不是在另一个中。特别是我不嘲笑TokenAPI,因为它是经过测试的。

奇异事实

奇怪的是,当我在IntelliJ之外运行测试时(我只选择从包含产生错误的方法的给定类中运行所有测试),然后它运行。看起来,这与mvn测试运行来自maven项目的所有测试(或者至少我猜是这样)有关。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-30 06:48:15

不幸的是,我不能告诉你为什么会这样,但我可以告诉你如何绕过这个问题。

问题是,PowerMockito扫描了tha类路径并添加了RESTeasy类(它们位于包'javax.ws.*‘中)。因此,上面提到的RuntimeDelegate是由PowerMockito类加载器加载的,并导致了随后的问题,即将该类与来自不同类加载器的类进行比较。

要解决这个问题,请告诉PowerMockito在扫描类时忽略javax.ws包:

代码语言:javascript
复制
@PowerMockIgnore({"javax.ws.*"})
票数 10
EN

Stack Overflow用户

发布于 2013-06-26 06:56:39

在将我的应用程序部署到JBoss v6.1时,我遇到了同样的问题--不知何故,我明白问题是由于jesrey-core和jboss的jaxrs-api jar中存在的相同的RuntimeDelegate.class包结构造成的。

下面是我的pom.xml

代码语言:javascript
复制
    <!-- For Restful Client -->
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.8</version>
        <exclusions>
            <exclusion>
                <groupId>com.sun.jersey</groupId>
                <artifactId>resteasy-jaxrs</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- For Jackson (JSON Utility) -->
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.8.5</version>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.9</version>
         <exclusions>
            <exclusion>
                <groupId>com.sun.jersey</groupId>
                <artifactId>jersey-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

在我的war部署到JBoss之后,只需将resteasy.deployer文件夹从jboss的服务器\默认\部署程序文件夹中删除。运行了我的申请,结果成功了。

如果有人能解释为什么这个错误是这样解决的,我会很高兴的。(我认为JBoss‘已经随resteasy.deployers war一起发布了,开发人员可以在他们的应用程序中单独使用这些war)--而不是为了掩饰我试图在Tomcat上部署war,它运行得很顺利。

票数 1
EN

Stack Overflow用户

发布于 2020-08-23 00:32:03

我通过在我的org.glassfish.jersey中更改pom.xml版本来解决这个问题。

下面是我的pom.xml

代码语言:javascript
复制
 <dependency>
      <groupId>javax.ws.rs</groupId>
      <artifactId>javax.ws.rs-api</artifactId>
      <version>2.1.1</version>
 </dependency>
 <dependency>
      <groupId>org.glassfish.jersey.core</groupId>
      <artifactId>jersey-client</artifactId>
      <version>2.31</version>
 </dependency>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8823844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档