4

この投稿の長さをお許しください。私はそこにある有用な情報をすべて入手し、人々が持つかもしれない質問を予測しようとしています.

Jersey で実装され、Jetty で実行されている一連の RESTful Web サービスがあります。 jar ファイルの難読化されていないバージョンでは、すべてが正常に機能します。しかし、Proguard で難読化すると、メッセージとともに 500 エラーが発生します

The ResourceConfig instance does not contain any root resource classes.

パッケージの一部として、接続と基本的な Jersey 構成をテストできるように、非常に単純な ping サービスがあります。

ジャージーで突堤を起動する私のコードは次のようになります。

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

私のプロガード構成は次のようになります(簡潔にするためにコメントを削除しました)。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 アノテーションをマッシュアップすることに要約されると私は考えています。しかし、プロガード構成ファイルにディレクティブ ( -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] 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] 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

これが行われると、サーブレットはディレクトリをトラバースして、@Path注釈付きリソースを探すことができます。

1つの血なまぐさい指示、痛みの日。

于 2011-01-14T20:20:04.113 に答える