web-dev-qa-db-fra.com

Pourquoi "Java.lang.IllegalStateException: la configuration de la ressource n'est pas modifiable dans ce contexte". semble-t-il déployer l'application Jersey?

J'ai créé une application implémentant REST services localement à l'aide de:

Eclipse Indigo Jersey 2.4 Tomcat 7.0.47

Lors de l'exécution locale à l'aide d'Eclipse, les services fonctionnent correctement, mais lors du déploiement de mon fichier WAR, j'obtiens l'exception suivante lorsque je tente d'effectuer une opération GET sur l'une des URL des services:

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)

Je n'ai pas encore trouvé de cause première et je soupçonne simplement qu'il pourrait s'agir d'une dépendance en cours d'exécution manquante ou d'une autre configuration dans Eclipse différente de mon environnement de serveur Tomcat local et du serveur distant Tomcat.

Mon code à la classe de configuration des ressources est:

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

Que pensez-vous serait une cause possible?

12
Ghasfarost

Une des causes possibles est que vous disposez de deux mappages ou plus applicables pour cet appel d'URL.

Par exemple:

@Path ("/ {myParam}")

Et ailleurs:

@Path ("/ {differentParam}")

Maintenant, Jersey n’a aucun moyen de dire quelle méthode est censée être appelée et donne cette erreur.

19
TondaCZE

Publier très tard pour quiconque tombe sur ce problème. J'ai eu exactement le même problème - j'ai travaillé localement dans Eclipse, mais lorsque j'ai essayé de me déployer en dehors d'Eclipse, il s'est écrasé et a brûlé avec le même tracé de pile dans la question. Le problème était dû au double déploiement de nos applications Web en raison d'une mauvaise désignation des fichiers de guerre que nous déployions. 

Lorsque autoDeploy est défini sur true, Tomcat attend une convention de nommage TRÈS spécifique des fichiers .war associée au chemin de contexte. Par exemple, le chemin de contexte “/ foo/bar” doit avoir un fichier .war correspondant appelé “foo # bar.war”. De plus, un chemin de contexte mappé sur “/” ou “” attend un fichier war appelé ROOT.war. 

Les règles de dénomination complètes se trouvent ici: http://Tomcat.Apache.org/Tomcat-7.0-doc/config/context.html#Naming

La résolution des noms des fichiers de guerre a résolu le problème. 

Je tiens également à noter que, finalement, Eclipse s’est également étouffé pour moi. Parfois, nettoyer le projet et essayer de l'exécuter à nouveau corrigera le problème, mais pas à chaque fois et je ne sais pas pourquoi cela le résout. J'essaie encore de trouver une solution complète. Résoudre le problème pour Eclipse est un peu plus difficile car (à ma connaissance), je ne peux pas spécifier le nom du répertoire dans lequel Eclipse publie le projet. Par exemple, un projet dans Eclipse nommé "foo" dont la racine de contexte est "bar/baz" sera publié dans un répertoire nommé "foo" plutôt que "bar # baz" et Tomcat/Jersey ne semble pas aimer cela.

J'espère que cela permettra à quelqu'un d'économiser plus de 12 heures qu'il a fallu à mon équipe et à moi-même pour résoudre ce problème la veille d'une démo :)

5
Jeff

Dans mon cas, j'avais une ressource Jersey POST pour les téléchargements de fichiers. La ressource a spécifié le paramètre: @FormDataParam("file") InputStream file

et consommé MediaType.MULTIPART_FORM_DATA.

Pour résoudre le problème, j'ai dû ajouter ce qui suit à la configuration Jersey REST dans mon fichier 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
Hervian

J'ai réussi à provoquer la même erreur, et cela était dû à deux situations 1) La définition des chemins dans les ressources ws NE DOIT PAS partir d'un "/ xyz" mais être simplement "xyz" pour ResourceConfig @ApplicationPath ("/ ") 

2) se produit également en raison de la dépendance de toute API (jar) du projet .war ou de Tomcat/lib 

3) Cela se produit également lorsque le chemin de la ressource est dupliqué (le même nom est dupliqué) et est présenté dans le journal suivant: "AVERTISSEMENT: un modèle de ressource a une méthode de ressource (sous-) ambiguë pour la méthode HTTP GET et les types MIME d'entrée définis par @Consumes et @Produces dans les méthodes Java publiques javax.ws.rs.core.Response "

Netbeans 8.1, Apache Tomcat 8.0.12, JAX-RS 2.0 (maillot 2.12)

5
lzgrillo

J'ai rencontré le même message d'erreur. J'ai posté à ce sujet dans mon blog (espagnol).

En lisant les réponses ci-dessus et en additionnant ma propre expérience, je peux dire que si vous voyez cette exception levée, elle _ {est en fait un problème d’initialisation}. Examinez les modifications de syntaxe ou le code exécuté lors de l'initialisation. Vérifiez les journaux de vos conteneurs (comme catalina.out sur Tomcat).

2
sargue

L'exception ci-dessus peut être une exception de conséquence lorsque Jersey ne peut pas injecter un type d'utilisateur, par exemple. @QueryParam/@PathParam. Par exemple. vous n'avez pas enregistré votre ParamConverterProvider. Regardez ci-dessus dans les journaux, pour la première trace d'exception.

J'ai résolu mon cas avec:

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

(J'utilise Spring.) Lorsque j'ai inséré l'appel register() ci-dessus, l'exception a disparu.

2

Je ne sais pas si cela vous pose toujours un problème, mais j'ai récemment rencontré le même problème. Cependant, après avoir approfondi mon code, j'ai découvert que cette erreur était générée à cause de la signature de méthode suivante: Public void parseData (@FormParam ("data") Collection data)

Une fois que j'ai suivi l'erreur sur cette ligne, j'ai effectué quelques recherches sur Google et découvert que l'utilisation de @FormParam avec Collection <> ne fonctionnait pas.

La solution consiste à utiliser List <> à la place: Public void parseData (@FormParam ("data") List data)

J'espère que cela sera utile à toute personne trouvant ce post à l'avenir, car le message d'erreur n'est vraiment pas très utile!

2
egmackenzie

Si vous essayez de transmettre un paramètre de formulaire à l'aide de @FormParam avec un HTTP Get (@GET), vous pouvez également obtenir cette exception. Il faut se plaindre car vous ne pouvez pas transmettre de données dans le corps du formulaire avec un HTTP Get. Un exemple de code qui lève cette exception est ...

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

Apparemment, les principales causes d’échec sont dues au fait qu’il existe une référence en double dans le chemin des services, il s’agit d’un chemin multiple ("/"), de même que l’existence de ressources sans chemin défini ou que ces classes de ressources ne comptent GET, @POST, @UPDATE, @DELETE, ...).

Afin de résoudre ce problème, un chemin (non dupliqué) doit être indiqué pour chaque ressource et au moins dans chaque ressource, il doit exister une ou plusieurs méthodes publiées, l'absence de ces méthodes dans différentes versions de jersey peut être à l'origine de cette exception.

Exemple:

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

J'ai reçu le même message d'erreur. Pour moi, le problème était que j'ai utilisé @RequestMapping (une annotation Spring) au lieu du @QueryParam (annotation JAX-RS) sur une méthode argument dû à un copier/coller. Le message d'erreur n'était pas informatif, mais c'était le problème pour moi.

0
Zolcsi

Dans mon cas, il ne manquait que @PathParam("id") pour la déclaration 'int id'. Code erroné:

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

Code corrigé:

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

Essayez d'annuler le déploiement du fichier ROOT.war dans l'hôte local: 8080/manager et redéployez votre fichier WAR avec ce nom (ROOT.war), puis réessayez.

Cela a fonctionné pour moi.

0
Ráfagan

J'ai résolu ce problème en ajoutant ce code dans le fichier 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