使用声明式服务的OSGi + Pax-Web中的GWT问题 [英] Issues with GWT in OSGi+Pax-Web using Declarative Services
问题描述
我正在迁移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映射( GWT无法加载资源并产生以下错误: [N.B。最后一句应该是你将经历一系列序列化问题] 我已经将问题追踪到HttpServiceContext,加载资源并解释路径作为一个文件,而不是一个相对于编程web上下文的url: 这显然失败,因为此资源位于/ war / ctx / ctx / in包文件系统中。 有没有解决这个问题的方法?有人使用OSGi DS而不是WAB使用GWT和PAX-WEB? 有什么想法? 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 我做了一些进一步的挖掘。 在GWT上,这是负责加载这些策略文件的相关代码片段:[1] 我怀疑contextPath在这种情况下成为潜在的候选嫌疑犯。为了测试这个理论,我部署了一个简单的servlet来转储它的上下文。 在这种情况下,servlet报告: 转换为gwt问题 - >当gwt与WAB一起部署时,它会在/ ctx / app中找到它的配置,当我使用编程资源映射时,它正在调查/ app,因此找不到它的资源。 底线: 这种情况唯一的解决方法是让构建将GWT生成的文件复制到一个PS:遵循Pax-web中的Achim Nierbeck,OSGi规范正在发展以管理app-ctx问题: =http://wiki.osgi.org/wiki/WebExperience =nofollow> http://wiki.osgi.org/wiki/WebExperience 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 ( 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 ( GWT fails to load the resouce and produces the following error: [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: 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: 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] 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 这篇关于使用声明式服务的OSGi + Pax-Web中的GWT问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! Webapp-Context:/ ctx,Webapp-Root:/ war
)gwt会正确地找到它的资源。
现在我正在使用编程资源映射:
$ p $ Default $ Resource $ Default $ Resource $
resourceMapping.setAlias(/ ctx);
resourceMapping.setPath(/ war);
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。
获取资源:[/ mx / mx / 6ECAD5B3A6F908CE17E47773FB1594FF。 gwt.rpc]
HttpServiceContext |不是URL或无效URL:[/ctx/ctx/600000000000000773FB1594FF.gwt.rpc],视为文件路径
DefaultHttpContext |为资源搜索bundle [bundle] [/ctx/ctx/600000000000000773FB1594FF.gwt.rpc]
这似乎与错误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
一种可能的方法是将GWT编译器生成的/ war / ctx复制回/ ctx,但我希望在进入黑客方向之前找到一个体面的解决方案。
[2] - http:/ /team.ops4j.org/browse/PAXWEB-314
受保护的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);
}
}
...
我使用WAB部署了它(MANIFEST:Webapp-Context + web.xml)。在这个部署中,servlet报告:
[getContextPath] - > [/ ctx]
DefaultResourceMapping resourceMapping = new DefaultResourceMapping();
resourceMapping.setAlias(/ ctx);
resourceMapping.setPath(/ war);
[getContextPath] - > []
在PAX-WEB中,Webapp-Context不等同于别名。别名不会像Webapp-Context那样填充ContextPath。
<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]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" );
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.
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]
// 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
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);
}
}
...