Не удается получить ресурс JAX-RS в Джерси, работающий с сервисом REST, скрытым Proguard - PullRequest
3 голосов
/ 13 января 2011

Пожалуйста, извините за длину этого сообщения. Я пытаюсь получить всю полезную информацию и предвидеть вопросы, которые могут возникнуть у людей.

У меня есть серия веб-сервисов RESTful, которые были реализованы на Джерси и работают в Jetty. Все отлично работает с необфусцированной версией файла jar. Но когда я запутываю Proguard, я получаю ошибку 500 с сообщением

The ResourceConfig instance does not contain any root resource classes.

Как часть моего пакета, у меня есть чрезвычайно простая служба проверки связи, чтобы я мог проверить подключение и базовую конфигурацию Джерси.

Мой код, который запускается с джерси, выглядит так:

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

Так что я считаю, что причал настроен и работает правильно. Как я уже сказал, незапутанная версия этого приложения работает нормально.

В нижней части этой публикации появляется трассировка стека, которая появляется, когда я пытаюсь пинговать, но самая тревожная строка:

[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 в моем файле класса. Но у меня есть директива (-keepattributes Annotation ) в моем файле конфигурации proguard. Поэтому я сейчас потерян.

Будем благодарны за любые рекомендации.

STACK TRACE:

[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.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)

1 Ответ

9 голосов
/ 14 января 2011

Мне кажется, я нашел проблему, с которой столкнулся.Проблема в том, что 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.

Одна кровавая директива, дни боли.

...