【发布时间】:2012-06-23 13:35:43
【问题描述】:
我正在迁移在 OSGi (Equinox) 和 Pax-web 上运行的现有 GWT 应用程序,以使用声明式服务而不是编程式服务跟踪器。
我在 Equinox 中使用 Pax-Web。 PAX-WEB War 扩展器可以毫无问题地加载基于 WAR 的 GWT 应用程序,但是在这种操作方式中您不能拥有声明式服务。
我成功地从战争中重构了所有 servlet,并将它们转换为声明性 OSGi 服务 (<provide interface="javax.servlet.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 加载资源并将路径解释为文件而不是相对于编程 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/ 下。 这似乎与bug 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? 一种可能的方法是将 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
【问题讨论】:
-
在 OSGi 容器中使用时,类加载和 GWT 似乎存在问题。这可能与您的问题有关。 GWT Issue 1888 和 GWT OSGI on clazzes.org 可能会感兴趣。
-
@pauli 谢谢。我将问题追溯到 PAX-WEB 处理 Web 应用程序上下文的方式。基本上,当你有一个war 文件时,你可以将
Webapp-Context设置为。 GWT 使用 来解决这个问题String contextPath = request.getContextPath();建立编译资源的位置,但由于 PAX-WEB 不提供此功能,因此 GWT 找不到它。我们通过手动将编译后的资源复制到..
标签: java gwt osgi declarative-services pax-web