java - jax - jersey servlet
Jersey REST La instancia de ResourceConfig no contiene ninguna clase de recurso raĆz (9)
Acabo de pasar unas buenas 5 o 6 horas luchando con esto y finalmente he solucionado el problema. Esto puede funcionar para usted también quizás.
El código fuente que he estado usando está disponible en la página de tutoriales de Lars Vogel''s . Usando Apache Tomcat 6.0.20, asm-all-3.3.1.jar, jersey-bundle-1.17.1.jar y jsr311-api-1.1.1.jar estaba obteniendo los mismos resultados que el OP, es decir
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.
Tenía la siguiente configuración en los diferentes archivos de implementación:
context root = rivets
<url-pattern>/rest</url-pattern>
@Path("/hello")
Al intentar acceder al recurso utilizando la siguiente URL se produjo un error 404
http://localhost:8080/rivets/rest/hello
Finalmente pude arreglarlo cambiando el patrón de url a:
<url-pattern>/rest/*</url-pattern>
Aunque no estoy seguro de cómo se mantendrá esto cuando empiece a introducir recursos más complejos. De todos modos, espero que esto pueda ayudar a alguien.
Esta pregunta ya tiene una respuesta aquí:
Aunque esta es una pregunta antigua, todavía no puedo encontrar la respuesta para hacer que esto funcione. Por favor corrija si encuentra que alguna de mis declaraciones no es correcta.
Tengo una aplicación Java Face y uso REST para los servicios web. No creo que Face tenga nada que ver con mi problema en absoluto. El web.xml es:
<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>
Tengo bastantes más servlets en el web.xml ya que es una aplicación de Face con Trinidad, etc.
En el paquete com.bi.nd.webservice, mi clase de recurso es:
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";
}
}
El hecho de que mi clase tenga un @GET es suficiente para identificarse como una clase de recurso.
Sin mencionar todas las otras complejidades, compilé mi código fuente con Ant en Eclipse y obtuve este error en el archivo 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.
Algunos sugirieron que copie asm.jar, jsr-api.jar, jersey-server.jar y jersey-core.jar en la aplicación WEB-INF / lib. Hice eso y todavía no funcionó. Me pareció que la sugerencia era un poco extraña ya que WEB-INF / lib es un lugar donde Eclipse instalará todas las bibliotecas de dependencias desde la ruta de compilación. No es un lugar donde ponemos bibliotecas manualmente.
Algunos explicaron que este error tenía algo que ver con el complemento de Java y la forma en que se escribió Jersey. Pero eso fue años atrás.
¿Puede alguien explicarme por qué sigo teniendo este problema?
Seguimiento: aunque desde el sitio web REST, las clases de recursos definidas como clases de recursos raíz son POJO (objetos Java antiguos) que se anotan con @ Path o tienen al menos un método anotado con @Path o un designador de métodos de solicitud como @GET, @PUT, @POST o @DELETE. Los métodos de recursos son métodos de una clase de recursos anotados con un designador de método de solicitud. Esta sección describe cómo usar Jersey para anotar objetos Java para crear servicios web RESTful.
Tengo que agregar @Path ("/ hello") a mi clase y, de repente, Jersey puede encontrar mi clase de recursos.
Ahora el archivo catalina.out se ve como:
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''
Pero el problema está lejos de terminar. Intento acceder a la URL http://localhost:8080/nd/hello
y todavía obtengo el 404 NOT FOUND. ¿La clase de proveedores NO ENCONTRADA es un mensaje importante?
Así que leí a través de las respuestas y todavía tenía el mismo problema. Lo resolví de la siguiente manera.
Se agregó "jetty-web.xml" a la carpeta "WEB-INF". Por lo tanto: src / main / webapp / WEB-INF / jetty-web.xml
El contenido del archivo jetty-web.xml es:
<?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>
Mi descanso ya está disponible en:
http://localhost:8080/YourEndpoint/webresources/someMethod
Espero que esto ayude a alguien por ahí.
Descubrí que el mensaje "no se encontraron clases de proveedores" da miedo pero no es importante.
"La instancia de ResourceConfig no contiene ninguna clase de recursos de raíz" es un problema mucho mayor.
Descubrí que la clase de recurso debe anotarse con @Path, y la clase del proveedor (si tiene una, usamos una para asignar excepciones a los códigos de respuesta HTTP) debe anotarse con @Provider, y ambas deben estar en el paquete correcto, y luego Jersey los encontrará.
En primer lugar, tenga en cuenta que tener @GET en una clase no es suficiente para identificarlo como una clase de recurso raíz; la clase debe tener una @Path en ella. Lo tuyo lo hace, así que ese no es el problema.
Tenía el mismo problema que tú: funcionaba en Eclipse, pero luego no lo hice cuando lo construí para uso externo.
Estoy usando Jetty incrustado, con un main () que se ve así:
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://.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://.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);
}
}
(Al incrustar Jetty, esto toma el lugar de un web.xml). Com.sun.jersey.api.core.PackagesResourceConfig escanea las clases nombradas en busca de clases de proveedores de recursos raíz. Estoy seguro de que el web.xml solo apunta a lo mismo. Esto funcionó bien en Eclipse. El inicio del servidor lo informa correctamente en la consola:
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
Sin embargo, cuando inicio la aplicación en un servidor, solo obtengo las dos primeras líneas de eso, y no se encuentran clases de recursos Root.
Resulta que cuando haces un tarro, hay diferentes opciones de cómo se construye; en particular, si lo haces enumerando las rutas a las clases, obtendrás solo esas entradas. Pero si apunta el tarro al directorio con un comodín, también obtiene todas las rutas intermedias. Vea este mensaje para ver el ejemplo que me avisó: https://groups.google.com/d/msg/neo4j/0dNqGXvEbNg/xaNlRiU1cHMJ .
La clase PackagesResourceConfig depende de tener un directorio con el nombre del paquete para encontrar las clases dentro de él. Regresé a Eclipse y encontré una opción en la parte inferior del cuadro de diálogo "Exportar ...> Jar" para "Agregar entradas de directorio". Encendí eso, exporté el frasco nuevamente y luego el escaneo encontró mis clases de recursos. Tendrá que encontrar alguna opción comparable en su entorno de compilación.
Encontré otra razón por la cual Jersey podría no encontrar un recurso raíz. El mensaje de error es el mismo, así que pensé que sería una buena razón para documentar la causa raíz aquí en caso de que otras personas tropiecen con él.
Tengo una clase de recurso raíz que tiene las siguientes anotaciones:
@Singleton
@Path("/helloWorld")
@Service(...) // my own custom annotation
public class MyRootResource {
...
}
Esto hará que la exploración del recurso raíz en Jersey falle.
La solución es cambiar el orden de las anotaciones:
@Service(...) // my own custom annotation
@Singleton
@Path("/helloWorld")
public class MyRootResource {
...
}
Esto funciona.
Es posible que necesites usar una URL como esta
http://localhost:8080/<web_context_root>/nd/hello
Para resolver este problema, verifique su clase MapperIn, se requiere que especifique la Ruta:
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;
}
//...
}
Tuve el mismo mensaje de error y lo resolví modificando mi archivo web.xml. Asegúrese de que tiene esto en él:
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>your.package.name.here</param-value>
</init-param>
Yo tuve el mismo problema. Resuelto resolviendo en web.xml el valor-param bajo la etiqueta init-param. Por defecto, Eclipse había establecido en el archivo web.xml el nombre del proyecto en nombre de visualización. Eso no se copiará al valor-param , sino al paquete de Java.
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.test.demo</param-value>
</init-param>
Espero que esto ayude.