【问题标题】:Can't get Jersey JAX-RS Resource working with Proguard-obfuscated REST service无法让 Jersey JAX-RS 资源与 Proguard 混淆的 REST 服务一起使用
【发布时间】:2011-01-13 16:09:20
【问题描述】:

请原谅这篇文章的长度。我正在尝试获取其中的所有有用信息,并预测人们可能会遇到的问题。

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

The ResourceConfig instance does not contain any root resource classes.

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

我用球衣启动码头的代码如下所示:

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

所以我认为码头的配置和运行是正确的。就像我说的,这个应用程序的未混淆版本运行良好。

当我尝试 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 配置如下所示(为简洁起见,删除了 cmets)。请注意,当我调用 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] at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:510)

【问题讨论】:

  • 嗨,jspyeatt!我已使用您的 ServletHolder 部分代码以编程方式在 Android 上创建带有 Jetty 嵌入式网络服务器的 Jersey Servlet。不幸的是,我遇到了异常:com.sun.jersey.api.container.ContainerException: No WebApplication provider is present 你知道如何解决这个问题吗?谢谢!

标签: jersey proguard


【解决方案1】:

我相信我已经找到了我遇到的问题。 问题是 proguard 默认情况下不包含混淆 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 注释资源。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 2013-10-15
    相关资源
    最近更新 更多