2011-01-13 91 views
3

請原諒本帖的篇幅。我試圖獲得所有有用的信息,並預測人們可能會遇到的問題。使用Proguard-obfuscated REST服務無法獲得Jersey JAX-RS資源

我有一系列REST風格的Web服務已經用Jersey實現並在Jetty中運行。 一切工作正常與jar文件的未混淆的版本。但是,當我使用ProGuard混淆我得到一個500錯誤與消息

The ResourceConfig instance does not contain any root resource classes. 

由於我的包的一部分,我有一個非常簡單的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網址:

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已正確配置並正常運行。就像我說的,這個應用程序的未混淆的版本工作正常。

當我嘗試平出現的堆棧跟蹤出現在這個帖子底部,但最麻煩的路線是:

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

我平安的資源類看起來是這樣的:

@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 註釋)。因此,我現在失去了。

任何指導將不勝感激。

堆棧跟蹤:

【JAVA] com.sun.jersey.api.container.ContainerException:本ResourceConfig實例不包含任何根資源類。 [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.jav在javax.servlet.GenericServlet.init(GenericServlet.java:211) [java] at 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)

+0

嗨jspyeatt! 我已經使用ServletHolder代碼部分以編程方式在Android上使用Jetty嵌入式Web服務器創建Jersey Servlet。 不幸的是我得到的例外: com.sun.jersey.api.container.ContainerException:沒有WebApplication提供者 你有什麼想法如何解決這個問題嗎?謝謝! – Giorgio 2012-06-25 12:51:12

回答

8

我相信我有追蹤我遇到的問題。 問題是,默認情況下,proguard不包含混淆jar文件中的目錄條目。

所以我混淆的jar文件內容看起來像這樣。

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

注意,沒有目錄條目。

當我添加-keep目錄指令到我的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註釋資源的目錄。

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