web-dev-qa-db-fra.com

Jersey REST L'instance ResourceConfig ne contient aucune classe de ressources racine

Bien que ce soit une question ancienne, je ne trouve toujours pas la réponse pour que cela fonctionne ..__ S'il vous plaît corriger si vous trouvez l'une de mes déclarations est inexacte.

J'ai une application Java Face et j'utilise REST pour les services Web. Je ne pense pas que Face ait quoi que ce soit à faire avec mon problème . Le fichier web.xml est:

<servlet>
    <servlet-name>NDREST</servlet-name>
    <servlet-class>
        com.Sun.jersey.spi.container.servlet.ServletContainer
    </servlet-class>
    <init-param>
        <param-name>com.Sun.jersey.config.property.packages</param-name>
        <param-value>com.bi.nd.webservice</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>NDREST</servlet-name>
    <url-pattern>/nd/*</url-pattern>
</servlet-mapping>

J'ai encore pas mal de servlets dans le web.xml car c'est une application Face avec Trinidad, etc.

Dans le package com.bi.nd.webservice, ma classe de ressources est la suivante:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Produces(MediaType.APPLICATION_XML)
@Path("/hello")
public class TransactionResource 
{
public TransactionResource() 
{
}

@GET
@Produces(MediaType.TEXT_PLAIN)
public String itWorks()
{
    return "Get is OK";
}
}

Le fait que ma classe ait un @GET est suffisant pour s'identifier comme une classe de ressources.
Sans parler de toutes les complexités, j’ai compilé mon code source avec Ant dans Eclipse et j’ai eu cette erreur dans le fichier catalina.out:

May 24, 2011 8:48:46 AM com.Sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
     com.bi.nd.webservice
May 24, 2011 8:48:46 AM com.Sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.7 05/20/2011 11:04 AM'
May 24, 2011 8:48:46 AM com.Sun.jersey.server.impl.application.RootResourceUriRules <init>
SEVERE: The ResourceConfig instance does not contain any root resource classes.

Certains ont suggéré de copier les fichiers asm.jar, jsr-api.jar, jersey-server.jar et jersey-core.jar dans l'application WEB-INF/lib. Je l'ai fait et cela n'a toujours pas fonctionné. J'ai trouvé la suggestion un peu étrange car WEB-INF/lib est un endroit où Eclipse installera toutes les bibliothèques de dépendances à partir du chemin de compilation. Ce n'est pas un endroit où nous mettons manuellement des bibliothèques.

Certains ont expliqué que cette erreur avait quelque chose à voir avec le plug-in Java et la manière dont Jersey était écrit. Mais c'était il y a des années.

Quelqu'un peut-il m'expliquer pourquoi je continue à avoir ce problème?

Suivi: Bien que provenant du site Web REST, la classe de ressources définie en tant que classes de ressources racines sont des objets POJO (Plain Old Java Objects) annotés avec @ Path ou ayant au moins une méthode annotée avec @Path ou une requête désignateur de méthode tel que @GET, @PUT, @POST ou @DELETE. Les méthodes de ressources sont les méthodes d'une classe de ressources annotée avec un indicateur de méthode de requête. Cette section explique comment utiliser Jersey pour annoter des objets Java afin de créer des services Web RESTful.

Je dois ajouter @Path ("/ hello") à ma classe et, tout à coup, Jersey peut trouver ma classe de ressources.

Le fichier catalina.out ressemble maintenant à:

May 24, 2011 3:13:02 PM com.Sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
com.bi.nd.webservice
May 24, 2011 3:13:02 PM com.Sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class com.bi.nd.webservice.TransactionResource
May 24, 2011 3:13:02 PM com.Sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
May 24, 2011 3:13:02 PM com.Sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.7 05/20/2011 11:04 AM'

Mais le problème est loin d'être résolu. J'essaie d'accéder à l'URL http://localhost:8080/nd/hello et j'obtiens toujours le 404 NOT FOUND. La classe de fournisseur NON TROUVÉE est-elle un message important?

20
user759646

J'avais le même message d'erreur et je l'ai résolu en modifiant mon fichier web.xml. Assurez-vous qu'il contient ceci:

<init-param>
   <param-name>com.Sun.jersey.config.property.packages</param-name>
   <param-value>your.package.name.here</param-value>
</init-param>
11
Conor Pender

J'ai trouvé une autre raison pour laquelle Jersey pourrait ne pas trouver une ressource racine. Le message d'erreur est identique, j'ai donc pensé que ce serait une bonne raison de documenter la cause fondamentale ici au cas où d'autres personnes tomberaient dessus.

J'ai une classe de ressources racine qui comporte les annotations suivantes:

@Singleton
@Path("/helloWorld")
@Service(...) // my own custom annotation
public class MyRootResource {
...
}

Cela entraînera l'échec de l'analyse des ressources racine dans Jersey.

Le correctif consiste à changer l'ordre des annotations:

@Service(...) // my own custom annotation
@Singleton
@Path("/helloWorld")
public class MyRootResource {
...
}

Cela marche.

7
Tero Paananen

Tout d'abord, notez qu'avoir @GET sur une classe ne suffit pas pour l'identifier en tant que classe de ressources racine; la classe doit avoir un @Path dessus. Le vôtre, alors ce n’est pas le problème.

J'avais le même problème que vous: cela fonctionnait sous Eclipse, mais cela ne fonctionnait pas lorsque je l'ai construit pour un usage externe.

J'utilise Embedded Jetty, avec un main () qui ressemble à ceci:

public static void main(String argv[])
{
    try
    {
        // from http://wiki.Eclipse.org/Jetty/Tutorial/Embedding_Jetty
        Server server = new Server(8080);
        ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        contextHandler.setContextPath("/");
        server.setHandler(contextHandler);

        // http://stackoverflow.com/questions/9670363/how-do-i-programmatically-configure-jersey-to-use-jackson-for-json-deserializa
        final PackagesResourceConfig prc = new PackagesResourceConfig("com.ultimatefoodfight.server.api");
        final Map<String, Object> prcProperties = prc.getProperties();
        prcProperties.put(JSONConfiguration.FEATURE_POJO_MAPPING, true);

        // from http://stackoverflow.com/questions/7421574/embedded-jetty-with-jersey-or-resteasy
        contextHandler.addServlet(new ServletHolder(new ServletContainer(prc)), "/*");

        server.start();
        server.join();
    }
    catch(Exception e)
    {
        System.out.println(e);
    }
}

(Lors de l'intégration de Jetty, cela remplace un fichier web.xml.) Com.Sun.jersey.api.core.PackagesResourceConfig analyse les classes nommées pour les classes de fournisseur de ressources racine. le même. Cela a bien fonctionné dans Eclipse. Le démarrage du serveur indique correctement ceci dans la console:

INFO: Scanning for root resource and provider classes in the packages:
  com.ultimatefoodfight.server.api
Jul 29, 2012 7:31:28 AM com.Sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
  class com.ultimatefoodfight.server.api.Users
  class com.ultimatefoodfight.server.api.Contests

Cependant, lorsque je lance l'application sur un serveur, je n'en ai que les deux premières lignes et aucune classe de ressources racine n'est trouvée.

Il se trouve que lorsque vous créez un pot, il existe différentes options pour sa construction. en particulier, si vous le faites simplement en listant les chemins d'accès aux classes, vous obtenez uniquement ces entrées. Mais si vous pointez jar sur le répertoire avec un caractère générique, vous obtenez également tous les chemins intermédiaires. Voir ce message pour l'exemple qui m'a averti: https://groups.google.com/d/msg/neo4j/0dNqGXvEbNg/xaNlRiU1cHMJ .

La classe PackagesResourceConfig dépend de la présence d'un répertoire avec le nom du package afin de trouver les classes qu'il contient. Je suis retourné à Eclipse et j'ai trouvé une option au bas de la boîte de dialogue "Export ...> Jar" pour "Ajouter des entrées de répertoire". Je l'ai allumé, j'ai à nouveau exporté le pot, puis l'analyse a trouvé mes classes de ressources. Vous aurez besoin de trouver une option comparable dans votre environnement de construction.

5
Chris Westin

Je viens de passer 5 ou 6 heures à lutter contre cela aussi et j'ai finalement résolu le problème. Cela peut fonctionner pour vous aussi peut-être.

Le code source que j'ai utilisé est disponible sur La page de tutoriel de Lars Vogel . En utilisant Apache Tomcat 6.0.20, asm-all-3.3.1.jar, jersey-bundle-1.17.1.jar et jsr311-api-1.1.1.jar, j’obtenais les mêmes résultats que l’OP, c.-à-d. 

INFO: Root resource classes found:
  class com.mypackage.MyClass
13/03/2013 4:32:30 PM com.Sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.

J'avais les paramètres suivants dans les divers fichiers de déploiement:

context root = rivets
<url-pattern>/rest</url-pattern>
@Path("/hello")

Essayer d'accéder à la ressource en utilisant l'URL suivante a donné une erreur 404

 http://localhost:8080/rivets/rest/hello

Je pouvais éventuellement pouvoir le réparer en modifiant le modèle d'URL en:

<url-pattern>/rest/*</url-pattern>

Bien que je ne sois pas sûr de savoir comment cela va se passer lorsque je commencerai à introduire des ressources plus complexes. Quoi qu'il en soit, j'espère que cela pourra aider quelqu'un.

3
Dave Durbin

J'ai trouvé que le message "Aucune classe de fournisseur trouvée" est effrayant mais pas important.

"L'instance de ResourceConfig ne contient aucune classe de ressources racine" est un problème beaucoup plus important.

J'ai trouvé que la classe de ressources doit être annotée avec @Path et que la classe de fournisseur (si vous en avez une - nous en utilisons une pour mapper les exceptions aux codes de réponse HTTP) doit être annotée avec @Provider, et les deux doivent figurer dans le bon paquet, puis Jersey les trouvera.

2
metamatt

vous pourriez avoir besoin d'utiliser une URL comme celle-ci 

http://localhost:8080/<web_context_root>/nd/hello
1
Alex Curvers

J'ai donc lu les réponses et j'ai toujours le même problème. Je l'ai résolu comme suit.

Ajout de "jetty-web.xml" dans le dossier "WEB-INF". Ainsi: Src/main/webapp/WEB-INF/jetty-web.xml

Le contenu du fichier jetty-web.xml est le suivant: 

<?xml version="1.0"  encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-" "http://www.Eclipse.org/jetty/configure.dtd">
<Configure class="org.Eclipse.jetty.webapp.WebAppContext">
    <Set name="contextPath">/YourEndpoint</Set>
</Configure>

Mon repos est maintenant disponible sur:

http://localhost:8080/YourEndpoint/webresources/someMethod

J'espère que cela aide quelqu'un là-bas.

1
Darrel Kleynhans

Pour résoudre ce problème, veuillez vérifier votre classe MapperIn. Il est nécessaire de spécifier le chemin:

import javax.ws.rs.GET;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.lot.account.api.doc.GetMemberAccountsIn;
import com.lot.common.doc.CommonApi;
import com.lot.common.doc.FlowData;
import com.lot.security.authorization.RequestData;


@Path("/account/member/")
public class MapperIn {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/{memberId}")
    public GetAccountIn prepareGetAccount(@PathParam("memberId") String memberId) {

        // create apiInput
        GetAccountIn apiInput = new GetAccountIn ();

        // map values from url
            apiInput.setMemberId(memberId);


        return apiInput;
    }
//...
}
0
Sylwester Z

J'ai eu le même problème. Pour le résoudre, fixez dans le fichier web.xml la valeur param sous la balise init-param . Par défaut, Eclipse avait défini dans le fichier web.xml le nom du projet en nom d'affichage. Cela ne doit pas être copié dans la param-value , mais dans le paquet Java.

  <init-param>
    <param-name>com.Sun.jersey.config.property.packages</param-name>
    <param-value>com.test.demo</param-value>
    </init-param> 

J'espère que cela t'aides.

0
sari