Почему java.lang.IllegalStateException: конфигурация ресурса не может быть изменена в этом контексте. появляется развертывание приложения Джерси?

Я создал приложение, реализующее службы REST локально, используя:

Джерси Eclipse Indigo 2.4 Tomcat 7.0.47

При локальном запуске с использованием Eclipse службы работают нормально, но при развертывании моего файла WAR я получаю следующее исключение при попытке выполнить GET для одного из URL-адресов служб:

HTTP Status 500 - Servlet.init() for servlet com.app.rest.MyResourceConfig threw exception

type Exception report

message Servlet.init() for servlet com.app.rest.MyResourceConfig threw exception

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Servlet.init() for servlet com.app.rest.MyResourceConfig threw exception
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    java.lang.Thread.run(Thread.java:662)

root cause

java.lang.IllegalStateException: The resource configuration is not modifiable in this context.
    org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:270)
    org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:218)
    org.glassfish.jersey.server.ResourceConfig.register(ResourceConfig.java:448)
    org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:300)
    org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167)
    org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:349)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    java.lang.Thread.run(Thread.java:662)

Мне пока не удалось найти основную причину, и мое единственное подозрение заключается в том, что это может быть отсутствующая работающая зависимость или какая-то другая конфигурация в Eclipse, которая отличается от моей локальной среды сервера Tomcat и Tomcat на удаленном сервере.

Мой код в классе конфигурации ресурсов:

package com.app.rest;

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;

import com.app.rest.services.RunDetailsService;
import com.app.rest.services.RunHistoryService;
import com.app.rest.services.RunPollService;
import com.app.rest.services.RunTestService;


@ApplicationPath("api")
public class MyResourceConfig extends ResourceConfig {

    public MyResourceConfig() {
        register(RunHistoryService.class).
        register(RunTestService.class).
        register(RunDetailsService.class).
        register(RunPollService.class);     
    }   
}

Как вы думаете, что может быть возможной причиной?


person Ghasfarost    schedule 18.12.2013    source источник


Ответы (16)


Одна из возможных причин заключается в том, что у вас есть два или более применимых сопоставления для этого вызова URL.

Например:

@Путь("/{мойПарам}")

И еще где-то:

@Путь("/{различныйПарам}")

Теперь у Джерси нет возможности сказать, какой метод на самом деле должен вызываться, и выдает эту ошибку.

person TondaCZE    schedule 08.03.2014
comment
Ничего общего с путями в моем случае - person Martynas Jusevičius; 13.04.2021

В моем случае у меня был ресурс Джерси POST для загрузки файлов. Ресурс указал параметр: @FormDataParam("file") InputStream file

и использовал MediaType.MULTIPART_FORM_DATA.

Чтобы решить эту проблему, мне пришлось добавить следующее в конфигурацию REST Джерси в моем файле web.xml:

<init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
person Hervian    schedule 09.05.2016

Сообщение очень поздно для тех, кто наткнулся на эту проблему. У меня была точно такая же проблема - работал локально в eclipse, но когда я попытался развернуть за пределами Eclipse, он разбился и сгорел с той же трассировкой стека, что и в вопросе. Проблема возникла из-за двойного развертывания наших веб-приложений из-за неправильного именования файлов войны, которые мы развертывали.

Когда для autoDeploy установлено значение true, tomcat ожидает ОЧЕНЬ конкретного соглашения об именах файлов .war, которое связано с контекстным путем. Например, контекстный путь «/foo/bar» должен иметь соответствующий файл .war с именем «foo#bar.war». Кроме того, путь контекста, сопоставленный с «/» или «», ожидает файл войны с именем ROOT.war.

Полные правила именования можно найти здесь: http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Naming

Исправление имен файлов войны решило проблему.

Еще хочу отметить, что, в конце концов, eclipse тоже захлебнулся для меня этой проблемой. Иногда очистка проекта и попытка повторного запуска решит проблему, но не каждый раз, и я не уверен, почему это решает ее. Я все еще пытаюсь найти полное решение. Решить проблему для eclipse немного сложнее, потому что (насколько мне известно) я не могу указать имя каталога, в котором eclipse публикует проект. Например, проект в eclipse с именем «foo», корнем контекста которого является «bar/baz», будет опубликован в каталоге с именем «foo», а не «bar#baz», и tomcat/Jersey, похоже, это не нравится.

Я надеюсь, что это поможет кому-то сэкономить 12+ часов, которые потребовались мне и моей команде, чтобы отладить эту проблему в ночь перед демонстрацией :)

person Jeff    schedule 03.10.2014

Мне удалось вызвать ту же ошибку, и это было связано с двумя ситуациями: 1) определение путей в ресурсах ws НЕ ДОЛЖНО начинаться с «/xyz», просто должно быть «xyz» до ResourceConfig @ApplicationPath («/»)

2) также возникает из-за зависимости какого-либо API (jar) в проекте .war или tomcat/lib

3) Это также происходит, когда есть неоднозначность в пути к ресурсу (дублирует одно и то же имя), представленном в следующем журнале: «ПРЕДУПРЕЖДЕНИЕ: модель ресурса имеет неоднозначный (суб-) метод ресурса для HTTP-метода GET и входные mime-типы, как определено с помощью аннотаций @Consumes и @Produces в методах Java public javax.ws.rs.core.Response"

Netbeans 8.1, Apache Tomcat 8.0.12, JAX-RS 2.0 (футболка 2.12)

person lzgrillo    schedule 21.10.2014
comment
2) было причиной ошибки в моем приложении... я просто скопировал обновленные файлы на сервер и пропустил удаление старых библиотек, которые больше не используются. - person karlis; 04.08.2016
comment
Я рекомендую для обнаружения этих аномалий в используемых библиотеках использовать Maven + Netbeans 8.x, у него есть инструмент open POM -> Graph, который позволяет просматривать карту зависимостей с конфликтами (красный) - person lzgrillo; 17.08.2016
comment
Моя проблема заключалась в обновлении сервера. На моей рабочей станции разработчика все было в порядке, потому что я удалил старые библиотеки при добавлении новой версии.... но по прошествии нескольких дней при обновлении сервера вы можете пропустить, что старые все еще там. - person karlis; 19.08.2016

Вышеупомянутое исключение может быть следствием исключения, когда Джерси не может внедрить какой-либо тип пользователя, например. @QueryParam/@PathParam. Например. вы не зарегистрировали свой ParamConverterProvider. Посмотрите выше в журналах первую трассировку исключения.

Я решил свой случай с:

@Component public static class JerseyConfig extends ResourceConfig { public JerseyConfig() { this.register(LocalDateParamProvider.class); } }

(Я использую Spring.) Когда я вставил вышеуказанный вызов register(), исключение исчезло.

person Eugene Gr. Philippov    schedule 21.12.2015

Не уверен, что это все еще проблема для вас, но недавно я столкнулся с той же проблемой. Однако после дальнейшего изучения моего кода я обнаружил, что эта ошибка возникает из-за следующей сигнатуры метода: public void parseData(@FormParam("data") Данные коллекции)

Как только я отследил ошибку до этой строки, я немного погуглил и обнаружил, что использование @FormParam с Collection‹> не работает.

Решение состоит в том, чтобы вместо этого использовать List‹>: public void parseData(@FormParam("data") List data)

Надеюсь, это будет полезно всем, кто найдет этот пост в будущем, поскольку сообщение об ошибке действительно не очень полезно!

person Ed Mackenzie    schedule 09.07.2014

Я столкнулся с тем же сообщением об ошибке. я писал об этом в мой блог (испанский).

Читая приведенные выше ответы и суммируя свой собственный опыт, я могу сказать, что если вы видите это исключение, оно на самом деле является проблемой инициализации. Посмотрите на изменения синтаксиса или код, который выполняется во время инициализации. Проверьте журналы контейнера (например, catalina.out на Tomcat).

person sargue    schedule 12.03.2015

Другая возможная причина получения этого исключения — попытка передать параметр формы с помощью @FormParam с HTTP Get (@GET). Он должен пожаловаться, поскольку вы не можете передавать данные в теле формы с помощью HTTP Get. Пример кода, который вызовет это исключение...

@GET
@Path("test-get")
@Consumes( MediaType.APPLICATION_FORM_URLENCODED )
 public String testGet(@FormParam("name1") String name1) {
person Alan S.    schedule 29.02.2016
comment
У меня работает, но все же нужно знать, как получить из параметров в методе GET - person Manee.O.H; 11.12.2016

По-видимому, основные причины сбоя заключаются в том, что в пути службы есть дублирующая ссылка, это множественный путь ("/"), а также наличие ресурсов без определенного пути или такие классы ресурсов не учитываются Меньше с некоторыми определенными (@ GET, @POST, @UPDATE, @DELETE, ...).

Чтобы решить эту проблему, для каждого ресурса должен быть указан путь (не дублированный) и как минимум в каждом ресурсе должен быть один или несколько опубликованных методов, отсутствие этих методов в разных версиях джерси могло вызвать это исключение.

Пример:

package com.contpaq.tech.service.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/")
public class RootSrv {

  @GET
  @Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
  public Response getVersion() {
    return Response.ok().entity("NodeServer Versión 0.6.69").build();
  }
}
person lzgrillo    schedule 01.02.2017
comment
Это было проблемой и для меня, у меня было два ресурса с одинаковым путем. - person rpajaziti; 10.07.2019

Я получил такое же сообщение об ошибке. Для меня проблема заключалась в том, что я использовал @RequestMapping (аннотацию Spring) вместо @QueryParam (аннотацию JAX-RS) в аргументе метода из-за копирования и вставки . Сообщение об ошибке было не таким информативным, но это было проблемой для меня.

person Zolcsi    schedule 23.08.2016

Я решил эту проблему, добавив этот код в файл web.xml

  <servlet>
    <servlet-name>jersey-serlvet</servlet-name>
    <servlet-class>
        com.sun.jersey.spi.container.servlet.ServletContainer
    </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>jersey-serlvet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
person salah atwa    schedule 03.10.2016

В моем случае это был просто отсутствующий @PathParam("id") для объявления «int id». Неправильный код:

@POST
@Path("{id}/messages")
public Response returnMessages(int id, Message[] msgs) {

Исправленный код:

@POST
@Path("{id}/messages")
public Response returnMessages(@PathParam("id") int id, Message[] msgs) {
person Jaap D    schedule 11.04.2017

Попробуйте отменить развертывание ROOT.war в локальном хосте: 8080/manager и повторно разверните WAR с этим именем (ROOT.war), а затем повторите попытку.

Это сработало для меня.

person Ráfagan    schedule 19.01.2018

Проблема в моем случае заключается в том, что затененная банка не включает пакет javassist, который Джерси использует для манипулирования байт-кодом. При затенении jar обязательно включите org.javassist:*.

    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.26.0-GA</version>
    </dependency>
person Yao Li    schedule 09.10.2019

Вы можете получить java.lang.IllegalStateException, если закроете соединение с базой данных (особенно если это основное соединение, инициализированное через web.xml как listener-class, который является сервлетом), а затем, когда будет отправлен следующий запрос, поскольку подключение к базе данных недоступно, это исключение может быть сгенерировано.

В моем случае я обнаружил в середине выполнения mongoClient.close()

person D.Blaz    schedule 30.12.2020

Добавлять

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
    </resource>
  </resources>
</build>
person javapeople M    schedule 12.04.2017