使用声明性服务在OSGi + Pax-Web中使用GWT的问题

我正在迁移在OSGi(Equinox)和Pax-web上运行的现有GWT应用程序,以使用Declarative Services而不是程序化Service Tracker。

我在Equinox中使用Pax-Web。 PAX-WEB War扩展器没有加载基于WAR的GWT应用程序,但是你不能在这种操作方法中使用声明式服务。

我成功地重构所有servlet退出战争并转换它们变成声明OSGi服务( 这样我就可以摆脱servlet中所有混乱的ServiceTracker代码和特定的OSGi依赖关系。 我进一步复制了所有其他web.xmlfunction,以使用[1]上的信息注册filter,提供静态内容和欢迎页面

此时,它通常应该可以工作,但我遇到了PAX-WEB的问题以及GWT尝试加载其资源的方式:

在加载序列化描述符时,GWT从本地上下文加载序列化策略文件。 在我的情况下,它试图解决这样的资源:/ctx/ctx/62394587E47773FB1594FF.gwt.rpc这个资源是由GWT编译器创建并划归:/战/ CTX / CTX /资源…

之前,使用标准的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. 

[NB最后一句应该是“您将因此而遇到一系列序列化问题”]

我已经将问题跟踪到加载资源的HttpServiceContext并将路径作为文件进行归类,而不是相对于程序化Web上下文的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 

有办法解决这个问题吗? 是否有人使用OSGi DS而不是WAB使用GWT和PAX-WEB? 一种可能的方法是将GWT编译器生成的/ war / ctx复制回/ ctx,但我想在进入hack方向之前找到一个不错的解决方案。

有任何想法吗?

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

我做了一些进一步的挖掘。

在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(MANIFEST:Webapp-Context + web.xml)部署它。 在此部署中,servlet报告:[getContextPath] – > [/ ctx]

然后,使用包含资源映射的编程激活器将部署更改为OSGi-ds。 DefaultResourceMapping resourceMapping = new DefaultResourceMapping(); resourceMapping.setAlias(“/ ctx”); resourceMapping.setPath(“/ war”);

在这种情况下,servlet报告:[getContextPath] – > []

转换为gwt问题 – >当gwt与WAB一起部署时,它在/ ctx / app中找到它的配置,当我使用程序化资源映射时,它正在查找/ app,因此找不到它的资源。

结论:在PAX-WEB中,Webapp-Context并不等同于别名。 别名不会像Webapp-Context那样填充ContextPath。

这种情况的唯一当前解决方法是让构建将GWT生成的文件复制一级(消除应用程序上下文路径)

PS:继Pax-web的Achim Nierbeck之后,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

Interesting Posts