我正在迁移一个在OSGi (Equinox)和Pax-web上运行的现有GWT应用程序,以使用声明性服务而不是程序性服务跟踪器。
我正在使用Equinox中的Pax-Web。PAX-WEB War扩展器加载基于War的GWT应用程序时没有任何问题,但是您不能在这种工作方式中使用声明性服务。
我成功地将所有servlets从war中重构出来,并将它们转换为声明性OSGi服务(<provide interface="javax.servlet.Servlet"/>)。这样,我就摆脱了servlet中所有凌乱的ServiceTracker代码和特定的OSGi依赖项。我使用[1]上的信息进一步复制了所有其他web.xml功能,以注册过滤器、提供静态内容和欢迎页面
在这一点上,它应该正常工作,但我在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加载资源并将路径作为文件而不是相对于编程式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-3142有关,它的实现是将相对路径转换为文件路径:
// 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?一种可能的方法是将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
发布于 2012-10-17 22:23:43
我做了进一步的调查。
在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。新建resourceMapping = DefaultResourceMapping 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
https://stackoverflow.com/questions/11136105
复制相似问题