web-dev-qa-db-ja.com

「Java.lang.IllegalStateException:リソース構成はこのコンテキストでは変更できません。」 Jerseyアプリをデプロイしているように見えますか?

RESTサービスをローカルで実装するアプリを作成しました:

Eclipseインディゴジャージー2.4 Tomcat 7.0.47

Eclipseを使用してローカルで実行する場合、サービスは正常に機能しますが、WARファイルをデプロイするときに、サービスURLの1つに対してGETを実行しようとすると、次の例外が発生します。

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)

私はまだ根本的な原因を見つけることができませんでしたが、私の唯一の疑いは、実行中の依存関係が欠落しているか、自分のローカルTomcatサーバー環境やリモートサーバーのTomcatとは異なるEclipseの他の構成にある可能性があることです。

リソース構成クラスの私のコードは次のとおりです。

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);     
    }   
}

考えられる原因は何だと思いますか?

15
Ghasfarost

考えられる原因の1つは、そのURL呼び出しに2つ以上の適用可能なマッピングがあることです。

例えば:

@Path( "/ {myParam}")

そして他のどこか:

@Path( "/ {differentParam}")

現在、ジャージーには、どのメソッドが実際に呼び出されることになっているのかを伝える方法がなく、このエラーが発生します。

20
TondaCZE

この問題に遭遇した人のために非常に遅く投稿する。私はまったく同じ問題を抱えていました-Eclipseでローカルに動作しましたが、Eclipseの外部にデプロイしようとすると、問題の同じスタックトレースでクラッシュして書き込みました。この問題は、デプロイしていたwarファイルの名前が不適切であるために、Webアプリケーションが二重にデプロイされたことが原因でした。

AutoDeployがtrueに設定されている場合、Tomcatは、コンテキストパスに関連する.warファイルの非常に固有の命名規則を想定しています。たとえば、コンテキストパス「/ foo/bar」には、「foo#bar.war」という名前の対応する.warファイルが必要です。さらに、「/」または「」にマップされたコンテキストパスでは、ROOT.warというwarファイルが必要です。

完全な命名規則はここにあります: http://Tomcat.Apache.org/Tomcat-7.0-doc/config/context.html#Naming

Warファイルの名前を修正することで問題は解決しました。

また、結局のところ、Eclipseがこの問題を解決することにも注意したい。時々、プロジェクトをクリーンアップして再実行しようとすると問題が解決することがありますが、毎回ではありません。なぜそれが修正されるのかわかりません。私はまだ完全な解決策を見つけようとしています。 (私の知る限り)Eclipseがプロジェクトを公開するディレクトリの名前を指定できないため、Eclipseの問題を解決するのは少し難しいです。たとえば、「foo」という名前のEclipseのプロジェクトで、コンテキストルートが「bar/baz」であるプロジェクトは、「bar#baz」ではなく「foo」という名前のディレクトリに公開され、Tomcat/Jerseyはそれを好まないようです。

これが私と私のチームがデモの前夜にこの問題をデバッグするのにかかった12時間以上を他の人に節約してくれることを願っています:)

5
Jeff

私の場合、ジャージーPOSTファイルアップロード用のリソースがありました。このリソースはパラメーターを指定しました:@FormDataParam("file") InputStream file

mediaType.MULTIPART_FORM_DATAを使用しました。

この問題を修正するために、web.xmlファイルのJersey REST構成に以下を追加する必要がありました。

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

私は同じエラーの原因を管理しましたが、これは2つの状況が原因でした。1)リソース内のパスの定義は、「/ xyz」から始まり、「xyz」だけでResourceConfig @ApplicationPath(「/」)にしてはなりません。

2).warプロジェクトまたはTomcat/libのAPI(jar)の依存関係によっても発生します

3)リソースパスにあいまいさがある場合(同じ名前が重複する)が次のログに表示される場合にも発生します:「警告:リソースモデルに、定義されているHTTPメソッドGETと入力MIMEタイプのあいまいな(サブ)リソースメソッドがありますJava method public javax.ws.rs.core.Response "の@Consumesおよび@Produces注釈

Netbeans 8.1、Apache Tomcat 8.0.12、JAX-RS 2.0(jersey 2.12)

5
lzgrillo

同じエラーメッセージが発生しました。 私はそれについて投稿しました私のブログ (スペイン語)。

上記の答えを読んで私の経験を足し合わせると、この例外がスローされた場合は、実際には初期化の問題であると言えます。初期化中に実行される構文の変更またはコードを確認します。コンテナーログを確認します(Tomcatのcatalina.outなど)。

2
sargue

上記の例外は、Jerseyが一部のユーザータイプを挿入できない場合の結果の例外である可能性があります。 _@QueryParam_/_@PathParam_。例えば。 ParamConverterProviderを登録していません。最初の例外トレースについては、上記のログを参照してください。

私は私のケースを解決しました:

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

(Springを使用しています。)上記のregister()呼び出しを挿入すると、例外が発生します。

これがまだ問題かどうかはわかりませんが、最近同じ問題に遭遇しました。ただし、コードをさらに詳しく調べたところ、次のメソッドシグネチャが原因でこのエラーがスローされていることがわかりました。public void parseData(@FormParam( "data")Collection data)

この行のエラーを追跡した後、グーグルを実行して、@ FormParamをCollection <>で使用しても機能しないことを発見しました。

解決策は、代わりにList <>を使用することです:public void parseData(@FormParam( "data")List data)

エラーメッセージはあまり役に立たないので、これが将来この投稿を見つけた人に役立つことを願っています。

2
egmackenzie

その例外を取得する別の考えられる理由は、HTTP Get(@GET)で@FormParamを使用してフォームパラメータを渡そうとした場合です。 HTTP Getではフォームの本文でデータを渡すことができないため、文句を言う必要があります。この例外をスローするコードの例は...

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

明らかに、失敗の主な原因は、サービスパスに重複した参照があり、これが複数のパス( "/")であることに加え、パスが定義されていないリソースの存在や、そのようなリソースクラスがいくつかの定義済み(@ GET、@ POST、@ UPDATE、@ DELETE、...)メソッド。

これを解決するには、リソースごとにパス(重複しない)を指定する必要があり、少なくとも各リソースに1つ以上の公開されたメソッドが必要です。ジャージの異なるバージョンにこれらのメソッドがないと、この例外が発生する可能性があります。

例:

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();
  }
}
1
lzgrillo

同じエラーメッセージが表示されました。私にとって問題は、コピー貼り付けのためにメソッド引数に@ RequestMapping(Springアノテーション)@ QueryParamの代わりに(JAX-RSアノテーション)を使用したことでした。エラーメッセージはそれほど有益ではありませんでしたが、それは私にとって問題でした。

0
Zolcsi

私の場合、 'int id'宣言の@PathParam("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) {
0
Jaap D

Localhost:8080/managerでROOT.warをアンデプロイしてみて、この名前(ROOT.war)でWARを再デプロイしてから、再試行してください。

それでうまくいきました。

0
Ráfagan

この問題を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>
0
salah atwa

私の場合の問題は、色付きのjarに、ジャージーがバイトコード操作を行うために使用するjavassistパッケージが含まれていないことです。 jarをシェーディングするときは、必ずorg.javassist:*を含めてください。

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