使用声明式服务在OSGi的+大同的Web使用GWT问题(Issues with GWT in OSG

2019-09-18 07:57发布

I'm migrating an existing GWT app running on OSGi (Equinox) and Pax-web to use Declarative Services instead of programmatic Service Tracker.

I'm using Pax-Web in Equinox. A WAR-based GWT application is loaded with no problems by PAX-WEB War extender, but you cannot have Declarative Services in this modus operandis.

I successfully refactored all servlets out of the war and converted them into declarative OSGi services (<provide interface="javax.servlet.Servlet"/>). That way I got rid of all the messy ServiceTracker code and specific OSGi dependencies in the servlets. I further replicated all other web.xml functionality to register a filter, serve static content and welcome page using the info on [1]

At this point, it normally should work, but I'm having issues with PAX-WEB and the way GWT tries to load its resources:

While loading the serialization descriptors, GWT loads the serialization policy file from the local context. In my case it tries to resolve resources like this: /ctx/ctx/62394587E47773FB1594FF.gwt.rpc This resource is created by the GWT compiler and placed under : /war/ctx/ctx/resource...

Before, using the standard wab mapping (Webapp-Context: /ctx, Webapp-Root: /war) gwt would find its resources correctly. Now that I'm using the programmatic resource mapping:

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

GWT fails to load the resouce and produces the following error:

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.

[N.B. The last sentence should read "you will experience a hell of serialization issues as a result"]

I've tracked the issue to the HttpServiceContext loading the resource and intrepreting the path as a file and not as an url relative to the programmatic web context:

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]

This obviously fails, as this resource is located under /war/ctx/ctx/ in bundle file system. This seems to relate to bug PAXWEB-314 [2] which implementation is to turn the relative path into a file path:

// 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

Is there a way to work around this issue? Is somebody using GWT and PAX-WEB using OSGi DS instead of a WAB? One possible way is to copy the /war/ctx produced by the GWT compiler back to /ctx, but I'd like to find a decent solution before going into the hack direction.

Any ideas?

1 - https://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

Answer 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是在这种情况下,潜在的候选人嫌疑。 为了检验这一理论,我部署了一个简单的servlet,清除其背景。 我部署它采用WAB(声明:的webapp - 语境+ web.xml中)。 在这种部署中,servlet的报告:[getContextPath] - > [/ CTX]

然后,改变了部署到OSGi的DS与含有资源映射的编程活化剂。 DefaultResourceMapping resourceMapping =新DefaultResourceMapping(); resourceMapping.setAlias( “/ CTX”); resourceMapping.setPath( “/战争”);

在这种情况下,小服务程序报告:[getContextPath] - > []

翻译成GWT问题 - >当GWT是部署一个WAB,发现在/ CTX /应用它的配置,当我用它正在调查/应用程序的编程资源映射,因此没有找到它的资源。

底线:在PAX-WEB,的webapp-上下文是不等同于别名。 别名不填充的contextPath以同样的方式的webapp - 语境一样。

目前唯一的变通针对这种情况,就是让构建复制GWT生成的文件下一层(消除了应用程序上下文路径)

PS:从大同的Web继阿希姆Nierbeck,在OSGi规范正在演变管理的应用-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



文章来源: Issues with GWT in OSGi+Pax-Web using Declarative Services