无法让 Jersey JAX-RS 资源与 Proguard 混淆的 REST 服务一起使用

发布于 2024-10-12 10:54:09 字数 4389 浏览 2 评论 0原文

请原谅这篇文章的篇幅。我试图获取其中所有有用的信息,并预测人们可能提出的问题。

我有一系列 RESTful Web 服务,这些服务已使用 Jersey 实现并在 Jetty 中运行。 使用未混淆版本的 jar 文件一切正常。但是当我使用 Proguard 进行混淆时,我收到了 500 错误,并显示消息

The ResourceConfig instance does not contain any root resource classes.

作为我的包的一部分,我有一个非常简单的 ping 服务,所以我可以测试连接性和基本 Jersey 配置。

我用 jersey 启动 jetty 的代码如下所示:

ServletHolder sh = new ServletHolder(ServletContainer.class);
sh.setInitParameter("com.sun.jersey.config.property.packages", "com.sw.pr.hq");
sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
            "com.sun.jersey.api.core.PackagesResourceConfig");
ServletContextHandler sch = new ServletContextHandler(server, "/pr");
sch.addServlet(sh, "/");

当我尝试从浏览器访问我的 ping url 时,调试日志显示以下几行:

Jan 13, 2011 9:33:35 AM com.sun.jersey.api.core.PackagesResourceConfig init
[java] INFO: Scanning for root resource and provider classes in the packages:
[java]   com.sw.pr.hq

所以我认为 jetty 已正确配置并运行。正如我所说,该应用程序的未混淆版本运行良好。

当我尝试 ping 时出现的堆栈跟踪出现在这篇文章的底部,但最令人不安的行是:

[java] SEVERE: The ResourceConfig instance does not contain any root resource classes.
[java] 2011-01-13 09:33:35.585:WARN:/pr:unavailable

我的 proguard 配置如下所示(为简洁起见,删除了注释)。请注意,当我执行 jar -tvf obfuscated.jar 调用时,我会看到 com.sw.pr.HQServerResource.class 类文件。

-dontskipnonpubliclibraryclasses
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-overloadaggressively
-repackageclasses com.sw.rtm
-adaptresourcefilenames    **.properties,**.png,**.css
-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF
-keep public class * {
    public *;
}
-keepclassmembernames class * {
    java.lang.Class class$(java.lang.String);
    java.lang.Class class$(java.lang.String, boolean);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

我的 ping 资源类如下所示:

@Path("/")
public class HQServerResource {
    @GET
    @Produces(MediaType.APPLICATION_XML)
    @Path("/ping")
    public PingResponse pingGet(@Context HttpServletRequest httpRequest) {
        LOGGER.debug("pingGet()");
        return getPingResponse(httpRequest);
    }
}

由于我对 Proguard 不熟悉,现在我将进入猜测阶段。

我认为我的问题归结为 Proguard 在我的类文件中混合了我的 @Path 注释。但我的 proguard 配置文件中有指令(-keepattributes Annotation)。因此我现在迷失了。

任何指导将不胜感激。

堆栈跟踪:

[java] com.sun.jersey.api.container.ContainerException:ResourceConfig 实例不包含任何根资源类。 [java] 在 com.sun.jersey.server.impl.application.RootResourceUriRules.(RootResourceUriRules.java:103) [java] 在 com.sun.jersey.server.impl.application.WebApplicationImpl._initiate(WebApplicationImpl.java:1182) [java] 在 com.sun.jersey.server.impl.application.WebApplicationImpl.access 600 美元(WebApplicationImpl.java:161) [java] 在 com.sun.jersey.server.impl.application.WebApplicationImpl$12.f(WebApplicationImpl.java:698) [java] 在 com.sun.jersey.server.impl.application.WebApplicationImpl$12.f(WebApplicationImpl.java:695) [java] 在 com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:197) [java] 在 com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:695) [java] 在 com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:690) [java] 在 com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:438) [java] 在 com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.initiate(ServletContainer.java:287) [java] 在 com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:587) [java] 在 com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:213) [java] 在 com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:342) [java] 在 com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:516) [java] 在 javax.servlet.GenericServlet.init(GenericServlet.java:211) [java] 在 org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:431) [java] 在 org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:330) [java] 在 org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:510)

Please excuse the length of this posting. I am trying to get all of the useful information in it and anticipate questions people might have.

I have a series of RESTful web services that have been implemented with Jersey and running in Jetty.
Everything works fine with the un-obfuscated version of the jar file. But when I obfuscate with Proguard I get a 500 error with the message

The ResourceConfig instance does not contain any root resource classes.

As part of my package I have an extremely simple ping service just so I can test connectivity and the basic Jersey configuration.

My code that starts up jetty with jersey looks like this:

ServletHolder sh = new ServletHolder(ServletContainer.class);
sh.setInitParameter("com.sun.jersey.config.property.packages", "com.sw.pr.hq");
sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
            "com.sun.jersey.api.core.PackagesResourceConfig");
ServletContextHandler sch = new ServletContextHandler(server, "/pr");
sch.addServlet(sh, "/");

When I try to hit my ping url from a browser the debug log shows the following lines:

Jan 13, 2011 9:33:35 AM com.sun.jersey.api.core.PackagesResourceConfig init
[java] INFO: Scanning for root resource and provider classes in the packages:
[java]   com.sw.pr.hq

So I am of the opinion that jetty is configured and running correctly. Like I said, the un-obfuscated version of this application works fine.

The stack trace that appears when I try to ping appears at the bottom of this posting, but the most troubling line is:

[java] SEVERE: The ResourceConfig instance does not contain any root resource classes.
[java] 2011-01-13 09:33:35.585:WARN:/pr:unavailable

My proguard configuration looks like this (comments removed for brevity). Note that when I do a jar -tvf obfuscated.jar call I see the class com.sw.pr.HQServerResource.class file there.

-dontskipnonpubliclibraryclasses
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-overloadaggressively
-repackageclasses com.sw.rtm
-adaptresourcefilenames    **.properties,**.png,**.css
-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF
-keep public class * {
    public *;
}
-keepclassmembernames class * {
    java.lang.Class class$(java.lang.String);
    java.lang.Class class$(java.lang.String, boolean);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

My ping resource class looks like this:

@Path("/")
public class HQServerResource {
    @GET
    @Produces(MediaType.APPLICATION_XML)
    @Path("/ping")
    public PingResponse pingGet(@Context HttpServletRequest httpRequest) {
        LOGGER.debug("pingGet()");
        return getPingResponse(httpRequest);
    }
}

Now I will enter into my speculation phase due to my unfamiliarity with Proguard.

I am of the opinion that my problem boils down to Proguard mashing my @Path annotations in my class file. But I have the directive (-keepattributes Annotation) in my proguard configuration file. Hence I am now lost.

Any guidance would be appreciated.

STACK TRACE:

[java] com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.
[java] at com.sun.jersey.server.impl.application.RootResourceUriRules.(RootResourceUriRules.java:103)
[java] at com.sun.jersey.server.impl.application.WebApplicationImpl._initiate(WebApplicationImpl.java:1182)
[java] at com.sun.jersey.server.impl.application.WebApplicationImpl.access$600(WebApplicationImpl.java:161)
[java] at com.sun.jersey.server.impl.application.WebApplicationImpl$12.f(WebApplicationImpl.java:698)
[java] at com.sun.jersey.server.impl.application.WebApplicationImpl$12.f(WebApplicationImpl.java:695)
[java] at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:197)
[java] at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:695)
[java] at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:690)
[java] at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:438)
[java] at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.initiate(ServletContainer.java:287)
[java] at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:587)
[java] at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:213)
[java] at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:342)
[java] at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:516)
[java] at javax.servlet.GenericServlet.init(GenericServlet.java:211)
[java] at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:431)
[java] at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:330)
[java] at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:510)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

亚希 2024-10-19 10:54:09

我相信我已经找到了我遇到的问题。
问题是,默认情况下,混淆的 jar 文件中不包含目录条目。

所以我混淆的 jar 文件内容看起来像这样。

com/sw/pr/hq/HQServerResource.class
com/sw/pr/hq/a.class
com/sw/pr/hq/a.class

请注意,没有目录条目。

当我将 -keepdirectories 指令添加到我的 proguard 文件中时,我混淆的 jar 文件如下所示。

com/
com/sw/
com/sw/pr/
com/sw/pr/hq/
com/sw/pr/hq/HQServerResource.class
com/sw/pr/hq/a.class
com/sw/pr/hq/a.class

完成此操作后,Servlet 能够遍历目录寻找我的 @Path 注释资源。

一个血腥的指令,痛苦的日子。

I believe I have tracked down the problem I was having.
The issue is that proguard, by default, doesn't include the directory entries in the obfuscated jar file.

So my obfuscated jar file contents looked something like this.

com/sw/pr/hq/HQServerResource.class
com/sw/pr/hq/a.class
com/sw/pr/hq/a.class

Note, no directory entries.

when I add the -keepdirectories directive to my proguard file my obfuscated jar file looks like this.

com/
com/sw/
com/sw/pr/
com/sw/pr/hq/
com/sw/pr/hq/HQServerResource.class
com/sw/pr/hq/a.class
com/sw/pr/hq/a.class

When this is done, Servlet is able to traverse the directories looking for my @Path annotated resources.

One bloody directive, days of pain.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文