Jersey REST ResourceConfig实例不包含任何根资源类

时间:2011-05-24 13:20:53

标签: java jersey jax-rs

虽然这是一个古老的问题,但我仍然找不到使这项工作成为可能的答案。 如果您发现我的任何陈述不正确,请更正。

我有一个Java Face应用程序,并使用REST作为Web服务。我不认为Face与我的问题有任何关系。 web.xml是:

<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>

我在web.xml中有更多的servlet,因为它是带有Trinidad等的Face应用程序。

在com.bi.nd.webservice包中,我的资源类是:

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

我的班级有一个@GET就足以证明自己是一个资源类 更别说所有其他复杂性了,我在Eclipse中用Ant编译了我的源代码,我在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.

有人建议将asm.jar,jsr-api.jar,jersey-server.jar和jersey-core.jar复制到app WEB-INF / lib中。我这样做了,但仍然无效。 我发现这个建议有点奇怪,因为WEB-INF / lib是Eclipse将从构建路径安装所有依赖库的地方。它不是我们手动放置库的地方。

有人解释说这个错误与Java插件和Jersey编写方式有关。但那是几年前的事了。

有人可以向我解释为什么我一直有这个问题吗?

跟进: 虽然从REST Web站点,定义为Root资源类的资源类是POJO(普通旧Java对象),它们使用@Path注释或者至少有一个使用@Path注释的方法或者请求方法指示符,例如@GET,@ PUT ,@ POST或@DELETE。资源方法是使用请求方法指示符注释的资源类的方法。本节介绍如何使用Jersey注释Java对象以创建RESTful Web服务。

我必须将@Path(“/ hello”)添加到我的班级,突然泽西岛可以找到我的资源类

现在catalina.out文件看起来像:

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'

但问题远未结束。我尝试访问URL http://localhost:8080/nd/hello,我仍然得到404 NOT FOUND。 Provider类未找到重要消息吗?

9 个答案:

答案 0 :(得分:11)

我有相同的错误消息,并通过修改我的web.xml文件解决了它。确保它包含在其中:

<init-param>
   <param-name>com.sun.jersey.config.property.packages</param-name>
   <param-value>your.package.name.here</param-value>
</init-param>

答案 1 :(得分:7)

我发现泽西岛无法找到根资源的另一个原因。错误信息是一样的,所以我认为这是一个很好的理由来记录这里的根本原因以防其他人偶然发现它。

我有一个根资源类,其上有以下注释:

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

这将导致Jersey内的根资源扫描失败。

修复方法是更改​​注释的顺序:

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

这很有效。

答案 2 :(得分:5)

首先,请注意,在类上使用@GET不足以将其标识为根资源类;该类必须有一个@Path。你的确如此,所以这不是问题所在。

我遇到了和你一样的问题:它在Eclipse中运行,但是当我构建它供外部使用时,它不起作用。

我正在使用嵌入式Jetty,其main()如下所示:

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

(当嵌入Jetty时,这取代了web.xml。)com.sun.jersey.api.core.PackagesResourceConfig扫描指定类的根资源提供程序类 - 我确定web.xml是只是指着同样的。这在Eclipse中运行良好。服务器启动在控制台中正确报告:

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

但是,当我在服务器上启动应用程序时,我只获得前两行,并且没有找到Root资源类。

事实证明,当你制作一个罐子时,它的构造方式有不同的选择;特别是,如果你只是通过列出类的路径来实现它,那么你就得到了 只是那些条目。但是,如果您使用通配符将jar指向目录,则还会获得所有中间路径。请参阅此消息,了解让我知道的示例:https://groups.google.com/d/msg/neo4j/0dNqGXvEbNg/xaNlRiU1cHMJ

PackagesResourceConfig类依赖于具有包名称的目录,以便在其中查找类。我回到了Eclipse,在“Export ...&gt; Jar”对话框的底部找到了“添加目录条目”的选项。我打开它,再次导出jar,然后扫描找到我的资源类。您需要在构建环境中找到一些类似的选项。

答案 3 :(得分:3)

我刚刚花了5到6个小时摔跤,最后解决了这个问题。这也许对你有用。

我一直在使用的源代码可在Lars Vogel's tutorial page获得。使用Apache Tomcat 6.0.20,asm-all-3.3.1.jar,jersey-bundle-1.17.1.jar和jsr311-api-1.1.1.jar我获得了与OP相同的结果,即

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.

我在各种部署文件中进行了以下设置:

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

尝试使用以下网址访问资源时出现了404错误

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

最终能够通过将url-pattern更改为:

来修复它
<url-pattern>/rest/*</url-pattern>

虽然当我开始介绍更复杂的资源时,我不确定这会如何。无论如何,希望这可能有助于某人。

答案 4 :(得分:2)

我发现“找不到提供者类”的信息很可怕,但并不重要。

“ResourceConfig实例不包含任何根资源类”是一个更大的问题。

我发现资源类需要用@Path注释,而提供者类(如果你有一个 - 我们使用一个用于将异常映射到HTTP响应代码)需要用@Provider注释,并且都需要在正确的包装中,然后泽西岛会找到它们。

答案 5 :(得分:1)

你可能需要使用这样的网址

http://localhost:8080/<web_context_root>/nd/hello

答案 6 :(得分:1)

所以我通过答案阅读并仍然遇到同样的问题。我解决了以下问题。

将“jetty-web.xml”添加到“WEB-INF”文件夹中。从而: 的src /主/ web应用/ WEB-INF /码头-web.xml中

jetty-web.xml的内容是:

<?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>

我的休息现在可以在:

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

希望这可以帮助那些人。

答案 7 :(得分:0)

我遇到了同样的问题。通过在web.xml中修复init-param标记下的param-value来解决它。 默认情况下,Eclipse在web.xml中将项目名称设置为display-name。这不应该复制到 param-value ,而是复制到Java包。

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

希望这有帮助。

答案 8 :(得分:0)

要解决此问题,请验证您的MapperIn类,需要指定路径:

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;
    }
//...
}