我想将我的EE应用程序迁移到OSGi.我的应用程序包括业务库,数据库JPA/Entities和REST/WS接口.它还有一个Web客户端.
我首先对结构进行原型设计,并使所有接口和捆绑包以OSGi方式相互通信.我希望在没有任何特定供应商或框架的情况下尽可能使用干净的规范.
我正在使用bnd maven插件来生成清单和声明性服务.我想使用注入从我的其余资源调用OSGI服务(在另一个包上),如下所示:
@Path("some-resources")
@Component
public class SomeResources{
private SomeService service = null;
@Reference
public void setController(SomeService service) { // <- this is never called
this.service = service;
}
@GET
@Produces(javax.ws.rs.core.MediaType.APPLICATION_XML)
public Object getSomeService() { // <- called
try {
service.process("Hello World"); // <- Error null object
}
...
}
Run Code Online (Sandbox Code Playgroud)
我可以使用bnd注释资源@Component并且可以@Resource注入吗?一切正常,但服务始终为空.
为BND声明我的捆绑包以使其成为web/wab包的方法应该是什么?
我使用maven包:
<packaging>bundle</packaging>
...
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<dependencies>
<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
<version>1.50.0</version>
</dependency>
</dependencies>
<configuration>
<supportedProjectTypes>
<supportedProjectType>ejb</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
<supportedProjectType>wab</supportedProjectType>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>jar</supportedProjectType>
</supportedProjectTypes> …Run Code Online (Sandbox Code Playgroud) 我正在使用Gradle构建一个OSGi jar,我在使用清单时遇到了一些麻烦.这是我的构建脚本的摘录:
apply plugin: 'java'
apply plugin: 'osgi'
jar {
baseName = 'awesome'
manifest {
name = 'An Awesome Application'
symbolicName = 'com.example.awesome'
// instruction 'Import-Package', 'org.springframework.orm'
}
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,Gradle会检测我的依赖项并添加一个Import-Package包含所有编译时依赖项的函数.但是说我的应用程序也有运行时依赖性org.springframework.orm,我如何告诉Gradle将其作为参数包含在内Import-Package?
如果上面的注释行未注释,则生成的Import-Package指令仅 指定org.springframework.orm.这让我困惑,因为在摇篮文档OsgiManifest状态
OsgiManifest instruction(String name, String... values)为指令添加参数.如果指令不存在,则创建它.如果它存在,则参数将附加到现有参数.
但是,这似乎不适用于自动检测到的Import-Package参数.如果我指定instruction 'Import-Package', 'my.dependency.1'等等,并jar.manifest.instructions在其间打印,我可以看到它们是如何按顺序添加的,它们都出现在生成的清单中,但似乎Gradle的OSGi插件如果Import-Package手动指定则不会添加自动检测到的参数.
Import-Package指令,它将自动生成所有编译时依赖项,但不是运行时依赖项.manifest { instruction 'Import-Package', 'org.springframework.orm' },那么编译时依赖关系不会自动包含在内.如何告诉Gradle我的运行时依赖项,以便将它们添加到Import-Package?
我有一个带有单个源文件的项目,在此完整列出:
package com.acme.el;
public class ExpressionUtils {
public static Object evaluate() {
new org.apache.commons.el.ExpressionEvaluatorImpl();
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
功能与问题无关.当我使用Gradle将项目构建为OSGi包时,清单包含以下指令:
Export-Package: com.acme.el;uses:="org.apache.commons.el";version="1.0"
Run Code Online (Sandbox Code Playgroud)
令我感到困惑的是该uses指令.正如我已经理解了该指令,它意味着定义其他包的依赖关系,这些包需要传播到导入这个导出包的其他包 - 例如,如果我的类定义或方法签名引用org.apache.commons.el包中的类.但是在这个类中,依赖性org.apache.commons.el完全包含在方法体内.它没有在API中公开,也没有其他的bundle导入com.acme.el可以获得ExpressionEvaluatorImpl在方法中创建的实例的保留.所以依赖不应该传播,对吧?
我是否误解了该uses指令的含义,还是在这里使用它是不必要的?
我做了一个最小的例子GitHub repo for reproduction,你可以在Eclipse中克隆和导入Gradle项目.
我正在使用BndTools(http://bndtools.org/)来开发OSGI应用程序.一切都很好,但我想在导出我的应用程序时想要改变一些东西.
我正在努力实现两件事(我认为它们可能是相关的):
aQute.launcher自定义的BndTools启动器替换默认的BndTools启动器(或者将其.JAR格式化)如何摆脱或更改默认的BndTools启动器(aQute.launcher)到自定义的启动器?
我在这个主题上唯一能找到的就是:http://goo.gl/jYliih
发射器没有构建成bnd,实际的发射策略是参数化的.启动器通过在其上放置JAR与bnd或bndrun文件相关联
-runpath.A.JAR应该有一个Launcher-Plugin标头作为启动器.如果未找到启动器,-runpath则将使用内置启动器biz.aQute.launcher.
原因是我需要我的应用程序接受命令args而不是干扰aQute启动器(就像所有-run args).另一方面,我想摆脱.bat/.sh启动应用程序的批处理方法,并使用单个.jar文件来启动应用程序.
那可能吗?
默认情况下,BndTools在导出应用程序时会创建此文件结构:
jar/ - >这是OSGI jar包文件夹
aQute/ - >默认的BndTools Launcher(Launcher.class里面)
META-INF/ - >为什么这里有META-INF文件夹?这不是JAR
launcher.properties - >启动器属性
start.sh - >从这个批处理文件中启动Launcher.class.
start.bat /与JAR相比,这有什么好处?
基本上,我想删除aQute,META-INF和start.*文件,并添加一个bin文件夹的二进制文件.
这应该可以用"Ant","Maven"或"Gridle"脚本来实现.但我可以创建一个没有BndTools支持的"BndTools项目"或"Gradle项目".我安装了"BndTools Gradle插件",但我找不到任何有关此主题的有用文档.
希望有人可以帮助我,或者指出我正确的方向.问候.
我正在从使用 Embed-Dependency 提供“方便”配置的 maven-bundle-plugin 迁移,但似乎我需要在使用bnd-maven-plugin. 我从旧包中添加了相同的包头,但它似乎没有包含实际依赖项的 jar 文件。有人有快速/简洁的方法吗?
如何使用maven-bundle-plugin中的bnd指令指令?bnd指令以' - '字符开头,这是一个无效的xml标记:
<-foo>bar</-foo>
Run Code Online (Sandbox Code Playgroud)
我已经检查了maven-bundle-plugin 的官方页面,他们说它应该以' - '字符开头:
指令 - 任何以" - "字符开头的指令都被视为指示BND执行某些特殊处理而不会复制到清单的指令.
该包目标的描述似乎并不具备这种信息也是如此.执行一些特殊处理并且不会复制到清单.
使用 JDK 10 构建我的 OSGi 包时,maven-bundle-plugin (3.5.1) 生成以下清单属性:
Require-Capability: osgi.ee;filter:="(osgi.ee=UNKNOWN)"
Run Code Online (Sandbox Code Playgroud)
这在运行时失败:
Unresolved requirements: [[com.mycompany.mybundle [1](R 1.0)] osgi.ee; (osgi.ee=UNKNOWN)]
Run Code Online (Sandbox Code Playgroud)
使用 JDK 9 构建时,我得到了预期:
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=9.0))"
Run Code Online (Sandbox Code Playgroud)
我将 maven-compiler-plugin 的源和目标版本分别设置为“1.9”和“10”。
目前,我正在使用一种解决方法来阻止插件添加osgi.ee到清单:
<configuration>
<instructions>
<_noee>true</_noee>
</instructions>
</configuration>
Run Code Online (Sandbox Code Playgroud)
.. 但我宁愿有正确的 Java 10 要求。
我有一个Vaadin应用程序,我正在尝试使用Maven + BND构建一组OSGI包.
我无法将捆绑包部署到Apache Felix,因为某些依赖项无法解析.Apache Felix抱怨找不到包"A"所需的包XYZ,尽管这个包在同一个包中定义!!
我查看了Maven + BND生成的MANIFEST.MF文件,发现该包中的包(XYZ)被添加到"import"和"export"部分.我理解为什么"出口",但为什么"进口"?为什么捆绑包试图导入自己的包?
我的MANIFEST.MF
Manifest-Version: 1.0
Export-Package: myexample.admin;uses:="com.vaadin.ui,myexample.webshared,
com.vaadin.terminal,myexample.mvc.view.impl,
myexample.mvc.model,myexample.mvc.renderer.map.impl,
myexample.mvc.renderer,myexample.mvc.model.impl,myexample.util"
Built-By: ask
Tool: Bnd-0.0.384
Bundle-Name: admin
Created-By: 1.6.0_21 (Sun Microsystems Inc.)
Bundle-Version: 0
Build-Jdk: 1.6.0_26
Bnd-LastModified: 1315674240833
Bundle-ManifestVersion: 2
Import-Package: myexample.admin;version="1.0",myexample.mvc.model,
myexample.mvc.model.impl,myexample.mvc.renderer,
myexample.mvc.renderer.map.impl,myexample.mvc.view.impl,
myexample.util,myexample.webshared,com.vaadin.terminal,com.vaadin.ui
Bundle-SymbolicName: admin
Include-Resource: ..\classes
Originally-Created-By: Apache Maven Bundle Plugin
Run Code Online (Sandbox Code Playgroud) 我正在使用OSGI声明性服务(SCR)来创建组件包.我并不热衷于使用maven-scr-plugin生成的基于注释的组件xml文件.我正在手工编写component.xml.但是,我需要将Service-Component标头添加到MANIFEST文件中.我正在使用maven-bundle-plugin来构建osgi包,我可以在插件配置中给出任何指令,将这些头添加到清单文件中?
一些有用的链接:
谢谢
我已经开始为apache felix开发一个包,并使用ops4j pax插件.
我创建了项目结构,pax-create-project并且在那里做了正常的pax-create-bundle.然后你得到了用maven构建整个事物的初始项目结构.这里的重要部分是,你的bundle拥有它自己的pom(bundlename/pom.xml)和bnd文件(bundlename/osgi.bnd),但是maven-bundle-plugin已经提供了配置poms/compiled/pom.xml.捆绑元数据在下配置,poms/compiled/pom.xml但标准激活器在上述osgi.bnd文件下配置.bnd文件中的默认值是Bundle-Activator: ${bundle.namespace}.internal.ExampleActivator.
现在我想开始使用注释,org.apache.felix.scr所以我把它包含在捆绑包自己的pom下依赖:
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr</artifactId>
<version>1.6.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我创建了我的服务接口:
package namespace;
public interface Sample {
void sayHello();
}
Run Code Online (Sandbox Code Playgroud)
以及来自org.apache.felix.scr以下注释的实现:
package namespace.internal;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import namespace.Sample;
@Component
@Service
public class SampleImpl implements Sample{
@Activate
void start(){
System.out.println("Started SampleImpl.");
}
@Deactivate
void stop(){
System.out.println("Stopped SampleImpl.");
}
@Override
public void sayHello() {
System.out.println("Hello!");
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试最近在gradle 1.5中发布的新Sonar Runner任务.我想做的是能够使声纳转轮任务依赖于另一个任务,这样我就可以为这个项目正确设置声纳属性(即sonar.sources,sonar.binaries,sonar.libraries,sonar.java.source ,sonar.java.target).
具体来说,我正在使用一个名为bnd的osgi构建工具,它将在执行ant init任务时提供这些值(请注意,虽然我包含了默认的bnd build.xml文件,但我的完整构建实际上是使用gradle完成的).
我认为通过这样做可以自定义声纳运行器任务(这是一个多模块构建):
subprojects {
sonarRunner.dependsOn init
}
Run Code Online (Sandbox Code Playgroud)
最终添加这样的东西(从我对bnd ant变量的理解):
subprojects {
sonarRunner {
sonarProperties {
property "sonar.java.source", ant.property["project.sourcepath"]
property "sonar.java.target", ant.property["project.output"]
property "sonar.sources", ant.property["project.allsourcepath"]
property "sonar.libraries", ant.property["project.buildpath"]
}
}
sonarRunner.dependsOn init
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我尝试添加dependsOn时,我收到错误:
* What went wrong:
A problem occurred evaluating root project 'myproject'.
> Could not find property 'init' on project ':com.company.myproject.mymodule'.
Run Code Online (Sandbox Code Playgroud)
如果我尝试让sonarRunner依赖于gradle任务,我会收到以下错误:
* What went wrong:
A problem occurred evaluating root project 'myproject'.
> Could not find method dependsOn() for arguments [task …Run Code Online (Sandbox Code Playgroud) 我有一个问题,我正在使用maven war插件构建一个战争并使用bnd插件覆盖它,如在不改变包装类型的情况下将OSGi元数据添加到现有项目中所述. 该项目定义了以下依赖项:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.12</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
当我运行构建时,它在MANIFEST.MF中生成以下条目
Import-Package: .., javax.ws.rs.core, ..
Run Code Online (Sandbox Code Playgroud)
只要我将版本更改为1.13或更高版本,Import-Package条目就会变为:
Import-Package: .., javax.ws.rs;version="[1.1,2)", ..
Run Code Online (Sandbox Code Playgroud)
这对我来说是一个真正的问题因为我的目标中有javax.ws.rs.javax.ws.rs-api_2.0.0.m16.哪个将解决无版本所需案例的导入,但在范围限制存在时停止这样做.
所以,我的一般问题是:bnd如何决定版本范围?两个次要版本之间发生了一些变化,使其从无版本限制变为特定范围,因此我认为了解bnd如何做出这一决定将有助于我发现这个特定问题是什么.
我继承了一个带有import!javax的.bnd文件.,如果我拿出那个语句,我的程序会产生运行时错误.我目前需要将JavaHelp添加到我的应用程序中,该应用程序位于javax.help下..当我在.bnd中同时拥有这两个导入并使用JavaHelp中的类时,它会为特定类生成ClassNotFoundException,例如javax.help.JHelp.有没有办法处理这种情况,我感到困惑.