我想创建一些依赖于其他(第 3 方)罐子的包(这是否是一个好的做法是另一个话题)
我能够使用 gradle 生成一个胖 jar(它包含所有依赖的 jar)和 osgi 清单
我的项目 Layout 将 jar 存储在 libs/ 文件夹中 制作 jar 后,第 3 方 jar(例如 ibm.jar)位于 jar 的根目录中。
我将我的 gradle 任务是使用带有一些基本 osgi 指令的 osgi 插件,我仅手动将导出包指定为我的程序包,而不是其他 3 个 jar
但是,当我尝试安装该捆绑包时,它显示错误
Error starting file:****.jar (org.osgi.framework.BundleException: Unresol
ved constraint in bundle ***** [24]: Unable to resolve 24.0: missi
ng requirement [24.0] osgi.wiring.package; (osgi.wiring.package=com.ibm.mq))
org.osgi.framework.BundleException: Unresolved constraint in bundle **** [24]: Unable to resolve 24.0: missing requirement [24.0] osgi.wiring.package; (osgi.wiring.package=com.ibm.mq)
at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:382
6)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1868)
at …Run Code Online (Sandbox Code Playgroud) 我们使用Apache Felix (version 4.4.1)嵌入式 OSGi 框架。提供框架的主要应用程序用作Log4j2 (version 2.0.1)日志记录框架。log4j-api 和 log4j-core 存在依赖关系。当然,当主应用程序启动时,Log4j2 也会被加载和配置。在主要部分中触发的所有日志消息都会正确写入配置的附加程序。
现在是重点。加载的所有包应该能够使用相同的配置,并且使用与主应用程序相同的 LoggingContext。我试图做的是将所有 Log4j2 包(来自 log4j2-api 和 log4j-core)作为org.osgi.framework.system.packages.extra. 但是,当加载捆绑包时,log4j2 包不会像其他提供的包那样出现在接线包列表中,并且当捆绑包类尝试访问 Log4j2 类时,将引发异常。
所有捆绑包都以相同的方式配置,并且 Log4j2 依赖于 log4j2-api 和 log4j2-core 并提供了范围。当我查看 MANIFEST.MF 时,使用的 Log4j2 包位于该Import-Packages部分内
所以我的问题是。
为什么以这种方式导出 Log4j2 包不起作用?我必须如何配置我的环境,以便我可以在我的包和主应用程序中使用相同的 LoggingContext?
这是我在 java 代码中的 OSGi 框架的配置部分:
Map<String, String> temp = new HashMap<String, String>();
// setting parameter that the felix cache is new initialized on each
// start of the application
temp.put(org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN, "onFirstInit");
// setting …Run Code Online (Sandbox Code Playgroud) 我遇到了maven-bundle-plugin生成的MANIFEST.MF问题.出于某种原因,当我在<Import-Package>字段中列出版本号时,OSGi框架不会加载我的包.
我已经尝试并注意到如果我删除清单中的版本号,那么捆绑包已正确加载.
如何指示maven-bundle-plugin跳过版本号?
目前,它生成:
Import-Package: com.ghc.ghTester.expressions,org.apache.ws.security.proc
essor;version="[1.5,2)",org.apache.ws.security;version="[1.5,2)",org.ap
ache.ws.security.message;version="[1.5,2)",org.apache.ws.security.compo
nents.crypto;version="[1.5,2)",org.apache.ws.security.message.token;ver
sion="[1.5,2)"
Run Code Online (Sandbox Code Playgroud)
但我需要它来生成:
Import-Package:com.ghc.ghTester.expressions,org.apache.ws.security.proc essor,org.apache.ws.security,org.apache.ws.security.message,org.apache.ws.security.components.crypto,org.apache.ws.security.message.token
我的插件配置是:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.0.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${pom.groupId}.${pom.artifactId};singleton:=true</Bundle-SymbolicName>
<Bundle-Name>${pom.name}</Bundle-Name>
<Bundle-Version>${pom.version}</Bundle-Version>
<Bundle-ClassPath>{maven-dependencies},.</Bundle-ClassPath>
<Embed-Dependency>*;scope=compile</Embed-Dependency>
<Export-Package/> <!-- nothing for this bundle to export -->
<Import-Package>com.ghc.ghTester.expressions,org.apache.ws.*</Import-Package>
</instructions>
</configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)
如果我尝试加载版本,我会收到以下错误:
org.osgi.framework.BundleException: Could not resolve module: com.rit.message-level-security [978]
Unresolved requirement: Import-Package: org.apache.ws.security; version="[1.0.0,3.0.0)"
at org.eclipse.osgi.container.Module.start(Module.java:434)
at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:393)
at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:412)
at com.ghc.ghTester.Activator.installTempBundle(Activator.java:157)
Run Code Online (Sandbox Code Playgroud) 我目前正在开发一个 OSGi 项目。我没有很多AOP与OSGi结合的经验,我想知道如何在OSGi环境中最好地进行AOP?我们已经实现了 AOP 场景来创建一个控制台来拦截对捆绑包的调用,以便存储该捆绑包启动的每个任务的运行时间。今天,这个方面已经使用aspectj提供的LoadTimeWeaver部署在jboss容器上(向jboss启动脚本添加一个代理,以便检测容器中的jar -javaagent:%APP_HOME%\application\lib\aspectjweaver-1.6)。 11.jar)。我读过一些关于这个问题的文章,但没有找到适合我的解决方案。例如,AspectJ 有一个 Equinox 孵化器项目。但由于我使用 Apache Felix 和 Bnd(tools),我想避免使用 Equinox 中的东西。编织过程的一个要求是它也应该在加载时(aspectj 的包在另一个包中检测方法)。有人可以分享使用 AOPspectj 和 OSGI Felix 的此类用例的经验吗?
以下是当我向现有代码添加任何新方法时遇到的错误(特别是当我向接口或类添加任何方法时)
--- animal-sniffer-maven-plugin:1.15:check (default) @ deepser ---
[INFO] Checking unresolved references to org.codehaus.mojo.signature:java18:1.0
[INFO]
[INFO] --- maven-bundle-plugin:3.0.1:bundle (default-bundle) @ deepser ---
[INFO]
[INFO] --- maven-bundle-plugin:3.0.1:baseline (baseline) @ deepser ---
[INFO] Baseline Report - Generated by Apache Felix Maven Bundle Plugin on 2018-07-09T20:24Z based on Bnd - see http://www.aqute.biz/Bnd/Bnd
[INFO] Comparing bundle deepser version 18.6.5-SNAPSHOT to version 18.6.4
[INFO]
[INFO] PACKAGE_NAME DELTA CUR_VER BASE_VER REC_VER WARNINGS
[INFO] = ================================================== ========== ========== ========== ========== ==========
[INFO] * com.myowncompany.analytica.deepser.config major 18.6.5 18.6.4 19.0.0 …Run Code Online (Sandbox Code Playgroud) 我正在尝试将我的项目转换为 OSGI 应用程序。我几乎没有怀疑。假设我的应用程序中的 ModuleA 依赖于外部 jarA 和 jarB。现在为了让 ModeuleA 运行,我使用 maven-bundle-plugin 的 embed-dependency 属性嵌入了两个 jar。现在假设我有另一个模块 ModuleB,它也依赖于 jarA。所以这个模块也嵌入了jarA。我的项目最终将 jarA 嵌入了 2 次,这将不必要地膨胀项目的大小。
有什么方法可以告诉 OSGI 只加载一次 jarA 并将其提供给两个模块。
如果将这些 jars 转换为 OSGI 包是唯一的解决方案,我还有几个问题:
将 jar 转换为包的最简单方法是什么。BND 工具看起来是一个不错的解决方案,但我找不到有关它的正确文档。
jarA 也会有一些依赖的 jars。那么我是否需要将所有依赖的 jar 也转换为包。我的项目有 100 多个罐子。我怎样才能自动化这个过程。
提前致谢 :)
编辑:用最新信息更新了这个问题...
我遇到了依赖功能背靠背"功能:卸载"命令的问题.OSGi回应"状态正在改变......",但通过接受其他请求,我们遇到了问题.
奇怪的是,这会导致功能卸载成功,但捆绑卸载失败.我们通过尝试适当地订购卸载请求并在步骤之间添加延迟来解决这个问题,但我希望有一个更强大的解决方案.
正如所建议的那样,我也尝试在步骤之间添加"osgi:refresh"......同样的行为.是否有另一种方法可以检测"刷新包"是否仍在运行以延迟后续请求等?
这是详细信息......
karaf @ root>功能:卸载PolicyUtil
karaf @ root>功能:卸载Policy1
karaf @ root>功能:卸载策略2
通过线程"刷新包"对包"file:/policy2.jar"进行状态更改.
karaf @根>特点:卸载策略3
在捆绑"文件:/policy3.jar"进步状态改变的线程"刷新包".
karaf @ root>功能:卸载Policy4
karaf @ root>功能:卸载Enabler1
通过线程"刷新包"对包"file:/enabler1.jar"进行状态更改.
karaf @ root> features:卸载Enabler2
状态正在通过线程"刷新包"对包"file:/enabler2.jar"进行状态更改.
之后...我们最终安装了未安装的功能(正确),但仍安装了一些软件包(不正确)
OSGi的:列表
[277] [已安装] [] [] [60] Policy2
[278] [已安装] [] [] [60] Policy3
[280] [已安装] [] [] [60] Enabler1
[281] [已安装] [] [] [60]启动器2
特点:列表
[uninstalled] [1.0] PolicyUtil repo-0
[uninstalled] [1.0] Policy1 repo-0
[uninstalled] [1.0] Policy2 repo-0
[uninstalled] [1.0] Policy3 repo-0
[uninstalled] [1.0] Enabler1 repo-0
[uninstalled] [1.0] Enabler2 repo-0
是否可以使用某种api添加声明性服务?
一点背景:
我有一个基于动态脚本的服务器应用程序(可以随时添加,编辑或删除它们).这些脚本依赖于OSGi服务,并且可能相互依赖.每当编辑脚本时,脚本都会编译为javascript,并检测其依赖关系.
那时,我想(重新)将其注册为声明性服务,因此当它的依赖性来去时它将被激活/停用.
我有一个OSGi组件MyComponent.
该组件引用了一项服务MyService.现在MyService有几个实现MyServiceImpl1和MyServiceImpl2.MyComponent也有财产MyProperty.
现在我想要的是,只要MyProperty是1,就会MyComponent.MyService绑定MyServiceImpl1.如果我更改MyProperty为2,则MyComponent.MyService动态更新MyService绑定到"MyServiceImpl2".
我怎么做到这一点?作为参考,我使用的是Apache Felix容器,并且更愿意避免使用较低级别的OSGi api.
当我们在Apache Felix Web OSGi控制台的"配置"选项卡中更新组件的任何配置时,这些配置设置保存在哪里?这与AEM 6.0或以上有关.
apache-felix ×10
osgi ×10
maven ×3
aem ×1
aem-6 ×1
aop ×1
apache-karaf ×1
equinox ×1
fuse ×1
gradle ×1
java ×1
log4j2 ×1
logging ×1
spring-aop ×1