我有一个使用Groovy来解释脚本的小包.
清单Import-Package指令如下所示:
Import-Package: groovy.util;version="[1.8,2)"
Run Code Online (Sandbox Code Playgroud)
上面的版本范围明确指出导入版本必须介于1.8(含)和2.0(独占)之间.
当我在仅安装了Groovy 1.8.6的OSGi环境中运行此捆绑包时,它按预期工作...当我键入时inspect package requirement 4,它打印:
-> com.athaydes.gradle.osgi.groovy-1-8-6-runner [4] imports packages:
------------------------------------------------------------------
ipojo.example.code; version=0.0.0 -> com.athaydes.gradle.osgi.code-runner-api [1]
groovy.util; version=1.8.6 -> groovy-all [5]
Run Code Online (Sandbox Code Playgroud)
这正是我所期望的,当我要求CodeRunner解释这个Groovy片段时:
GroovySystem.version
Run Code Online (Sandbox Code Playgroud)
它正确返回1.8.6.
现在,当我启动安装了Groovy 1.8.6和2.3.3的OSGi环境时,当我检查包的包时,我得到了这个:
-> com.athaydes.gradle.osgi.groovy-1-8-6-runner [4] imports packages:
------------------------------------------------------------------
ipojo.example.code; version=0.0.0 -> com.athaydes.gradle.osgi.code-runner-api [1]
Run Code Online (Sandbox Code Playgroud)
该groovy.util进口消失(即使清单仍然有它,当然)!现在,当我跑步时,GroovySystem.version我得到2.3.3,而不是1.8.6应该是!
这是一个疯狂的东西,似乎只是一个新版本的Groovy存在的事实打破了OSGi的承诺,我应该能够使用我想要的任何版本的依赖.
我已经在Felix和Equinox中对此进行了测试,结果完全相同.
我还在清单中使用了精确版本而不是范围,但这并没有改变任何东西.
任何人都可以看到这里到底发生了什么?
PS.如果你不相信我,试试自己,这是GitHub上的项目:https://github.com/renatoathaydes/osgi-run/tree/next/osgi-run-test/ipojo-dosgi
我一直在使用OSGi一段时间,我遇到了各种问题的解决方案.我想重新审视其中一个,看看人们是否提出了不同的解决方案.
我与OSGi(Equinox 3.4.2)最常见的问题之一是Thread的上下文ClassLoader经常不可用.我知道这部分是一个Equinox问题,但我也遇到了Felix的问题.我遇到的主要是第三方库启动自己的Threads或ThreadPools.当这些在Bundle或DS激活期间启动时,它们最终可能没有它们的ClassLoader.如果第三方库有防止上下文ClassLoader丢失,那么没问题,但不是每个人都检查它.后来,如果所述库需要进行动态类加载,它可能会爆炸.
我已经使用了一段时间的成语如下(简要):
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
/*
* Start threads, or establish connections, here, now
*/
} finally {
Thread.currentThread().setContextClassLoader(tccl);
}
Run Code Online (Sandbox Code Playgroud)
这个习惯用法通常最终出现在Activator或DS activate()方法中.有一些小的变化,我检查是否tccl不为空,我不会覆盖上下文类加载器.
现在,我有一些代码贴在各个地方,我知道一些第三方库可能会产生一个线程并破坏我的一天.虽然一开始它是可以管理的,但我最终在许多随机的地方都有这个,这让我感到烦恼.
还有其他人遇到这个问题,他们提出了什么解决方案?我还想知道在新的Equinox 3.5.x中是否解决了这个问题,是否有人真正看到它有效?
问候.
我是整个Java和OSGi世界的新手,我无法理解OSGi Web应用程序的生态系统.
更确切地说,我目前正试图了解生态系统的所有部分是如何相互关联的:
为了让您直观地了解我对他们的关系的实际理解,请查看此图片:
alt text http://img253.imageshack.us/img253/1631/osgiwebenvironmentschem.png
据我所知,OSGi框架是OSGi规范的一个实现.运行时是一种分发,它在OSGi规范之上添加了额外的功能,例如日志记录.由于OSGi和Web容器(如Tomcat)的类路径机制似乎存在一些差异,因此您需要某种翻译器.这部分由"Web Extender"处理.
请你澄清一下这件事吗?我理解一切正确吗?
OSGi似乎通过不将大量JAR依赖项包装到lib目录中而具有小型可部署工件的优点.但是,我找不到任何能告诉我将依赖项部署到容器的简单可靠方法.例如,我有一个使用CXF和几个Spring子项目的应用程序.如果我需要将此应用程序部署到新的Glassfish服务器,那么最好的方法是什么,确保安装所有依赖项?
我正在使用Maven,似乎可以通过某种方式获得一个查看META-INF/maven目录的钩子并从pom.xml中提取依赖项列表并获取所需的库(可能来自当地的回购).有没有办法做到这一点?
Pax插件听起来像是在做这个,但它似乎是基于提升一个Felix容器?这不是我想要的,我正在处理已经运行的远程容器.
是否有任何镜头这样的东西存在作为命令行工具而不是GUI?
我看到很多关于OSGi的演讲,我认为这对于实施更好的模块化听起来很有希望.显然,"热部署"和"并行运行不同版本的x"也是市长的卖点.
我想知道OSGi承诺解决的问题是否是一个问题......?它让我想起OO的早期时代,类似的声称是女仆:
当OO是新的时,最重要的论点是可重用性.人们普遍声称,当使用面向对象时,人们只需要"一次写入",然后就可以"随处使用".
在实践中,我只看到这个适用于一些非常低级的例子.我认为这样做的原因是编写可重用的代码很难.从技术上讲,但从界面设计的角度来看.您必须预测未来的客户将如何使用您的课程并提前做出正确的选择.根据定义,这很困难,因此潜在的可重用性益处通常无法实现.
有了OSGi,我怀疑在这里我们可能会再次陷入承诺,我们没有真正拥有的问题的潜在解决方案.或者如果我们拥有它们,我们没有足够大的数量和严重程度,以便购买OSGi以获得帮助."Hotdeployment",例如模块的子集的绝对是一个好主意,但多久它真正的工作?多久没有,因为事实证明你对特定问题的模块化是错误的?如何在多个模块之间共享模型实体?这些模块都必须同时更换吗?或者,您是否将对象展平为基元并仅使用模块间通信中的对象,以便能够保持接口契约?
应用OSGi时最困难的问题是,我认为,使模块化"正确".类似于在OO中使用OSGi获取类的接口,问题保持不变,这次是更大规模,包甚至服务级别.
正如您可能已经猜到的那样,我目前正在尝试评估OSGi以用于项目.我们遇到的主要问题是随着代码库的增长而增加复杂性,并且我希望在具有越来越多定义的交互的较小模块中打破系统.
谢谢!
我正在使用非常大的JSF/Facelets应用程序,它们使用Spring进行DI/bean管理.我的应用程序具有模块化结构,我目前正在寻找标准化模块化的方法.
我的目标是从许多模块(可能相互依赖)组成Web应用程序.每个模块可能包含以下内容:
我想避免(几乎不惜一切代价)是需要将模块资源(如Facelets模板)复制或提取到WAR或扩展web.xmlfor模块的servlet,过滤器等.它必须足以添加模块(JAR,捆绑,伪影,...)到web应用(WEB-INF/lib,bundles,plugins,...)来延伸,以与该模块的Web应用程序.
目前,我使用自定义模块化解决方案来解决此任务,该解决方案主要基于使用类路径资源:
classpath*:com/acme/foo/module/applicationContext.xml加载应用程序上下文 - 这会加载模块JAR中定义的应用程序上下文.最后几天我读了很多关于OSGi的内容,我正在考虑,如何(以及如果)我可以将OSGi用作标准化的模块化方法.我在考虑如何使用OSGi解决单个任务:
ResourceLoader用bundle上下文注册实例.中央ResourceServlet使用这些资源加载器从bundle加载资源.ResourceResolver使用bundle注册的服务.#{myBean.property}if myBean在其中一个bundle中定义.我的问题是:
我一般都很感谢你的评论.
我一直在与OSGi合作一段时间,但我仍然不了解私有包.
并非所有未导出的捆绑包对所有其他包都不可见吗?如果是这样,那么未导出的私有包和包有什么区别?
我已经阅读了OSGi in Action和"OSGi和Apache Felix 3.0 - 初学者指南",但我无法找到差异.
是否首先 显示了OSGi的http://wiki.osgi.org/wiki/Tooling_Approaches gradle插件?或者如何用gradle做到这一点?
OSGi容器有一个很大的旧项目,许多项目在MANIFEST.MF中声明了复杂的关系.构建很长.现在我们想要简化并采用Gradle.但首先不要破坏事物并保持蚂蚁和gradle并行构建一段时间.但是我看到的是gradle建议在里面定义MANIFEST build.gradle.
https://docs.gradle.org/current/userguide/osgi_plugin.html
这会使很多复制工作.
更新有近100个模块,模块之间有很多依赖关系信息,嵌套jar.平均MANIFEST.MF长度约为50行(从20到300行不等).如何捆绑嵌套jar是另一个问题.这个问题是关于使用现有的MANIFEST.MF文件.我看到的所有插件bnd都与第一种方法完全相反.
我希望能够轻松启动OSGi框架(最好是Equinox)并从java main加载我的pom中列出的所有bundle.
这可能吗?如果是这样,怎么样?
似乎pax工具会这样做,但我似乎找不到任何指示这样的文档.我知道我可以像这样启动Equinox:
BundleContext context = EclipseStarter.startup( ( new String[] { "-console" } ), null );
Run Code Online (Sandbox Code Playgroud)
但我想做更多 - 就像我说的:加载更多的捆绑包,可能会启动一些服务,等等.
osgi ×10
java ×8
equinox ×2
apache-felix ×1
gradle ×1
groovy ×1
manifest.mf ×1
maven ×1
maven-2 ×1
modularity ×1
module ×1
pax ×1
spring ×1
tomcat ×1