使用声明式服务的OSGi + Pax-Web中的GWT问题 [英] Issues with GWT in OSGi+Pax-Web using Declarative Services

查看:216
本文介绍了使用声明式服务的OSGi + Pax-Web中的GWT问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在迁移OSGi(Equinox)和Pax-web上运行的现有GWT应用程序,以使用声明式服务而不是程序化服务跟踪器。我使用的是Equinox中的Pax-Web。基于WAR的GWT应用程序没有被PAX-WEB War extender加载,但是你不能在这个模式操作中使用声明式服务。



我成功地重构了所有servlet并将它们转换为声明式OSGi服务(< provide interface =javax.servlet.Servlet/> )。这样我摆脱了Servlet中所有混乱的ServiceTracker代码和特定的OSGi依赖关系。
我进一步复制了所有其他web.xml功能来注册过滤器,使用 [1]
p>

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



加载序列化描述符时,GWT从本地上下文加载序列化策略文件。
在我的情况下,它会尝试解析像这样的资源:/ctx/ctx/62394587E47773FB1594FF.gwt.rpc
这个资源由GWT编译器创建并放在:
/ war / ctx / ctx / resource ...

之前,使用标准wab映射( Webapp-Context:/ ctx,Webapp-Root:/ war )gwt会正确地找到它的资源。
现在我正在使用编程资源映射:

$ p $ Default $ Resource $ Default $ Resource $
resourceMapping.setAlias(/ ctx);
resourceMapping.setPath(/ war);

GWT无法加载资源并产生以下错误:

  2012-06-20 12:46:36.283:INFO:/:AbcProxy:错误:序列化策略文件'/ctx/ctx/600000000000000773FB1594FF.gwt.rpc'没找到;你忘了把它包含在这个部署中吗? 
2012-06-20 12:46:36.283:INFO:/:AbcProxy:警告:未能获取模块'https:// localhost:8443 / ctx / ctx /'的SerializationPolicy'600000000000000773FB1594FF';将使用传统的兼容1.3.3的序列化策略。作为结果,您可能会遇到SerializationException。

[N.B。最后一句应该是你将经历一系列序列化问题]

我已经将问题追踪到HttpServiceContext,加载资源并解释路径作为一个文件,而不是一个相对于编程web上下文的url:

 获取资源:[/ mx / mx / 6ECAD5B3A6F908CE17E47773FB1594FF。 gwt.rpc] 
HttpServiceContext |不是URL或无效URL:[/ctx/ctx/600000000000000773FB1594FF.gwt.rpc],视为文件路径
DefaultHttpContext |为资源搜索bundle [bundle] [/ctx/ctx/600000000000000773FB1594FF.gwt.rpc]

这显然失败,因为此资源位于/ war / ctx / ctx / in包文件系统中。
这似乎与错误PAXWEB-314 [2]有关,它将相对路径转换为文件路径:

  // IMPROVEMENT start PAXWEB-314 
257 try {
258 resource = new URL(path);
259 LOG.debug(resource:[+ path +]已经是一个URL,返回);
260返回资源;
261}
262 catch(MalformedURLException e){
263 //什么都不做,只需记录
264 LOG.debug(不是URL或无效的URL:[+ path +],视为文件路径);
265}
266 //改进结束PAXWEB-314

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



有什么想法?

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]

 受保护的SerializationPolicy doGetSerializationPolicy(
HttpServletRequest请求,字符串moduleBaseURL,字符串strongName){
//请求可以告诉您相对于$ b的web应用程序的路径$ b //容器根。
String contextPath = request.getContextPath();
String modulePath = null;
if(moduleBaseURL!= null){
try {
modulePath = new URL(moduleBaseURL).getPath();
} catch(MalformedURLException ex){
//记录信息,我们将默认
log(格式错误的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 =nofollow> 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


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

解决方案

I did some further digging.

On GWT, this is the relevant piece of code in charge of loading those policy files: [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);
      }
    }
...

I suspected the contextPath to be a potential candidate suspect in this case. To test that theory, I deployed a simple servlet that dumps its context. I deployed it using WAB (MANIFEST: Webapp-Context + web.xml). In this deployment, the servlet reports: [getContextPath]->[/ctx]

Then, changed the deployment to OSGi-ds with a programmatic activator containing the resource mapping. DefaultResourceMapping resourceMapping = new DefaultResourceMapping(); resourceMapping.setAlias( "/ctx" ); resourceMapping.setPath( "/war" );

In this case, the servlet reports: [getContextPath]->[]

Translated to the gwt issue --> when gwt is deployed with a WAB, it finds its config in /ctx/app and when I use the programmatic resource mapping it is looking into /app and therefore does not find its resources.

Bottom line: In PAX-WEB, Webapp-Context is not equivalent to the alias. The alias does not populate ContextPath the same way Webapp-Context does.

The only current work-around for this situation is to let the build copy the GWT-generated files one level down (eliminating the application context path)

PS: Following Achim Nierbeck from Pax-web, the OSGi spec is evolving to manage the app-ctx issue: 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

这篇关于使用声明式服务的OSGi + Pax-Web中的GWT问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆