4

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

我有一系列用 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 配置看起来像这样(为简洁起见,删除了注释)。请注意,当我调用 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:

4

1 回答 1

10

我相信我已经找到了我遇到的问题。问题是 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 注释资源。

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

于 2011-01-14T20:20:04.113 回答