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, который возвращает объект 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 .

Итак, основным утверждением, связанным с ошибкой, является проверка instanceof:

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 test запускает все тесты из проекта maven (или, по крайней мере, я так думаю).

11
задан Brice 13 January 2012 в 14:49
поделиться