Почему "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);     
    }   
}

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

Ответ 1

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

Например:

@Path ( "/{MyParam}" )

И где-то еще:

@Path ( "/{differentParam}" )

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

Ответ 2

Отправка очень поздно для тех, кто сталкивается с этой проблемой. У меня была точно такая же проблема - локально работал в 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 с именем "foo", корнем контекста которого является "bar/baz", будет опубликован в каталоге с именем "foo", а не "bar # baz", а tomcat/Jersey, похоже, не похож на это.

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

Ответ 3

Мне удалось вызвать ту же ошибку, и это было связано с двумя ситуациями 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)

Ответ 4

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

и использует MediaType.MULTIPART_FORM_DATA.

Чтобы устранить проблему, мне пришлось добавить следующее в конфигурацию Jersey 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>

Ответ 5

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

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

Решение состоит в том, чтобы использовать List < > вместо:   public void parseData (@FormParam ( "data" ) Список данных)

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

Ответ 6

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

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

Ответ 7

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

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

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

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

Ответ 8

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

@GET
@Path("test-get")
@Consumes( MediaType.APPLICATION_FORM_URLENCODED )
 public String testGet(@FormParam("name1") String name1) {

Ответ 9

По-видимому, основными причинами отказа являются то, что в пути к услугам есть дублируемая ссылка, это несколько путей ( "/" ), а также наличие ресурсов без определенного пути или таких классов ресурсов, которые не считаются меньшими с некоторыми (@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();
  }
}

Ответ 10

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

Ответ 11

Я решил эту проблему, добавив этот код в файл 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>

Ответ 12

В моем случае это было просто отсутствующим @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) {

Ответ 13

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

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

Ответ 14

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

    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.26.0-GA</version>
    </dependency>

Ответ 15

Добавить

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
    </resource>
  </resources>
</build>