java.lang.LinkageError: ClassCastException



我确实在TestNG和RESTeasy方面遇到了一个非常烦人的问题。

我有一个类,它针对一个API类运行了几个测试,该类使用RESTeasy框架来公开自己。

然而,如果我让测试用maven(mvn-test)运行,那么我会得到以下异常:

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 obejct的一个方法,该方法返回一个Response对象(来自RESTeasy)。作为测试框架,我确实使用了TestNG。

测试方法

@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.

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

if (!(delegate instanceof RuntimeDelegate))

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

delegate.getClass().getClassLoader() -> org.powermock.core.classloader.MockClassLoader@31e46a68
RuntimeDelegate.class.getClassLoader() -> sun.misc.Launcher$AppClassLoader@3c0fabe9

我知道这当然不起作用,但我想知道为什么RESTeasy的东西加载在MockClassLoader中,而不加载在另一个中。尤其是当我不嘲笑经过测试的TokenAPI时。

奇怪的事实

奇怪的是,当我从IntelliJ中运行测试时(我只选择从包含产生错误的方法的给定类中运行所有测试),它就会运行到底。看起来这在某种程度上与mvn测试运行maven项目中的所有测试有关(或者至少我猜是这样)。

很遗憾,我不能告诉你为什么会发生这种情况,但我可以告诉你如何解决这个问题。

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

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

@PowerMockIgnore({"javax.ws.*"})

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

下面是我的pom.xml

    <!-- 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后,刚刚从JBoss的server\default\deployers文件夹中删除了resteasy.deployer文件夹。运行了我的应用程序,它成功了。

如果有人解释为什么这个错误会以这种方式解决,我会很高兴?(我认为JBoss不必要地附带了resteasy.deployers jar,而开发人员可以在他们的应用程序中自己包含这些jar)-不要隐瞒,我曾尝试在Tomcat上部署我的war,它运行得很顺利。

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

下面是我的pom.xml

 <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>

相关内容

  • 没有找到相关文章

最新更新