Проблемы с GWT в OSGi+Pax-Web с использованием декларативных служб

Я переношу существующее приложение GWT, работающее на OSGi (Equinox) и Pax-web, для использования декларативных служб вместо программного средства отслеживания служб.

Я использую Pax-Web в Equinox. Приложение GWT на основе WAR без проблем загружается расширителем PAX-WEB War, но вы не можете использовать декларативные службы в этом режиме работы.

Я успешно провел рефакторинг всех сервлетов из войны и преобразовал их в декларативные службы OSGi (<provide interface="javax.servlet.Servlet"/>). Таким образом я избавился от всего беспорядочного кода ServiceTracker и конкретных зависимостей OSGi в сервлетах. Далее я воспроизвел все остальные функции web.xml для регистрации фильтра, обслуживания статического контента и страницы приветствия, используя информацию на [1]

На данный момент это обычно должно работать, но у меня проблемы с PAX-WEB и тем, как GWT пытается загрузить свои ресурсы:

При загрузке дескрипторов сериализации GWT загружает файл политики сериализации из локального контекста. В моем случае он пытается разрешить ресурсы следующим образом: /ctx/ctx/62394587E47773FB1594FF.gwt.rpc Этот ресурс создается компилятором GWT и помещается в папку: /war/ctx/ctx/resource...

Раньше, используя стандартное сопоставление wab (Webapp-Context: /ctx, Webapp-Root: /war), gwt правильно находил свои ресурсы. Теперь, когда я использую программное сопоставление ресурсов:

DefaultResourceMapping resourceMapping = new DefaultResourceMapping();
resourceMapping.setAlias( "/ctx" );
resourceMapping.setPath( "/war" );

GWT не может загрузить ресурс и выдает следующую ошибку:

2012-06-20 12:46:36.283:INFO:/:AbcProxy: ERROR: The serialization policy file '/ctx/ctx/600000000000000773FB1594FF.gwt.rpc' was not found; did you forget to include it in this deployment?
2012-06-20 12:46:36.283:INFO:/:AbcProxy: WARNING: Failed to get the SerializationPolicy '600000000000000773FB1594FF' for module 'https://localhost:8443/ctx/ctx/'; a legacy, 1.3.3 compatible, serialization policy will be used.  You may experience SerializationExceptions as a result.

[Примечание. Последнее предложение должно гласить: «В результате у вас возникнут адские проблемы с сериализацией»]

Я отследил проблему с HttpServiceContext, загружающим ресурс и интерпретирующим путь как файл, а не как URL-адрес относительно программного веб-контекста:

getting resource: [/mx/mx/6ECAD5B3A6F908CE17E47773FB1594FF.gwt.rpc]
HttpServiceContext | not a URL or invalid URL: [/ctx/ctx/600000000000000773FB1594FF.gwt.rpc], treating as a file path
DefaultHttpContext | Searching bundle [bundle] for resource [/ctx/ctx/600000000000000773FB1594FF.gwt.rpc]

Очевидно, что это не работает, так как этот ресурс находится в каталоге /war/ctx/ctx/ в файловой системе пакета. Похоже, это связано с ошибкой PAXWEB-314 [2], реализация которой заключается в превращении относительного пути в путь к файлу:

// IMPROVEMENT start PAXWEB-314
257              try {
258                  resource = new URL(path);
 259                  LOG.debug( "resource: [" + path + "] is already a URL, returning" );
 260                  return resource;
261              }
262                  catch (MalformedURLException e) {
 263                        // do nothing, simply log
264                      LOG.debug( "not a URL or invalid URL: [" + path + "], treating as a file path" );
 265              }
266              // IMPROVEMENT end PAXWEB-314

Есть ли способ обойти эту проблему? Кто-нибудь использует GWT и PAX-WEB, используя OSGi DS вместо WAB? Один из возможных способов - скопировать /war/ctx, созданный компилятором GWT, обратно в /ctx, но я хотел бы найти достойное решение, прежде чем переходить к хакерскому направлению.

Любые идеи?

1https://github.com/ops4j/org.ops4j.pax.web/blob/master/samples/whiteboard/src/main/java/org/ops4j/pax/web/extender/samples/whiteboard/internal/Activator.java [2] — http://team.ops4j.org/browse/PAXWEB-314


person maasg    schedule 21.06.2012    source источник
comment
Похоже, есть проблема с загрузкой классов и GWT при использовании в контейнере OSGi. Это может быть связано с вашей проблемой. проблема GWT 1888 и GWT OSGI на clazzes.org может представлять интерес.   -  person pillingworth    schedule 17.10.2012
comment
@паули спасибо. Я обнаружил проблему в том, как PAX-WEB обрабатывает контекст веб-приложения. По сути, когда у вас есть военный файл, вы можете установить Webapp-Context на ‹your-app-ctx›. GWT использует String contextPath = request.getContextPath(); для создания местоположения скомпилированных ресурсов, но поскольку PAX-WEB не предоставляет этого, GWT не находит его. Мы обошли это, вручную скопировав скомпилированные ресурсы в ...   -  person maasg    schedule 17.10.2012


Ответы (1)


Я продолжил копать.

В GWT это соответствующий фрагмент кода, отвечающий за загрузку этих файлов политик: [1]

protected SerializationPolicy doGetSerializationPolicy(
      HttpServletRequest request, String moduleBaseURL, String strongName) {
    // The request can tell you the path of the web app relative to the
    // container root.
    String contextPath = request.getContextPath();
    String modulePath = null;
    if (moduleBaseURL != null) {
      try {
        modulePath = new URL(moduleBaseURL).getPath();
      } catch (MalformedURLException ex) {
        // log the information, we will default
        log("Malformed moduleBaseURL: " + moduleBaseURL, ex);
      }
    }
...

Я подозревал, что contextPath является потенциальным подозреваемым в этом случае. Чтобы проверить эту теорию, я развернул простой сервлет, который выгружает свой контекст. Я развернул его с помощью WAB (МАНИФЕСТ: Webapp-Context + web.xml). В этом развертывании сервлет сообщает: [getContextPath]->[/ctx]

Затем изменил развертывание на OSGi-ds с программным активатором, содержащим сопоставление ресурсов. DefaultResourceMapping resourceMapping = new DefaultResourceMapping(); resourceMapping.setAlias ​​("/ctx"); resourceMapping.setPath («/ война»);

В этом случае сервлет сообщает: [getContextPath]->[]

В переводе на проблему gwt --> когда gwt развертывается с помощью WAB, он находит свою конфигурацию в /ctx/app, а когда я использую программное сопоставление ресурсов, он просматривает /app и, следовательно, не находит свои ресурсы.

Итог: в PAX-WEB Webapp-Context не эквивалентен псевдониму. Псевдоним не заполняет ContextPath так же, как это делает Webapp-Context.

Единственный текущий обходной путь для этой ситуации - позволить сборке копировать файлы, сгенерированные GWT, на один уровень вниз (исключая путь контекста приложения).

PS: Вслед за Ахимом Нирбеком из Pax-web спецификация OSGi развивается для решения проблемы app-ctx: http://wiki.osgi.org/wiki/WebExperience

[1] http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java?spec=svn5045&r=5045

person maasg    schedule 17.10.2012