Apache Maven Assembly Plugin不支持OSGi捆绑包

我有一个Maven OSGi多模块项目。 当OSGi从各个项目模块中挑选模块jar时,该项目运行良好。 (见下文1.1.B)

但是,使用第二种方法时,每当我尝试使用maven-assembly-plugin将bundle存放到中央文件夹(D:/ parent / provider / target / modules)时, bundle.getRegisteredServices() (下面的视图1.1.A)都会返回null。 版本:2.6 :

 framework.getBundleContext().installBundle("file:D:/parent/provider/target/modules/OSGiDmHelloWorldProvider-1.0.jar"); framework.getBundleContext().installBundle("file:D:/parent/provider/target/modules/OSGiDmHelloWorldConsumer-1.0.jar"); 

使用第二种方法查看下面的1.1.C以获得控制台输出。

1.1.A

 if (bundle.getRegisteredServices() != null) { for (ServiceReference serviceReference : bundle.getRegisteredServices()) System.out.println("\tRegistered service: " + serviceReference); } 

为什么我不能用第二种方法访问捆绑包?

GitHub上

我在GitHub上有一个SSCCE。 运行主课程将显示我的困境。

谢谢大家。

1.1.B

 package main; import java.net.URISyntaxException; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; import org.osgi.framework.Bundle; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.framework.launch.Framework; import org.osgi.framework.launch.FrameworkFactory; public class App { public static void main(String[] args) throws BundleException, URISyntaxException { App app = new App(); app.initialize(); } private void initialize() throws BundleException, URISyntaxException { Map map = new HashMap(); // make sure the cache is cleaned map.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT); map.put("ds.showtrace", "true"); map.put("ds.showerrors", "true"); FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next(); Framework framework = frameworkFactory.newFramework(map); System.out.println("Starting OSGi Framework"); framework.init(); loadScrBundle(framework); framework.getBundleContext().installBundle("file:D:/parent/provider/target/OSGiDmHelloWorldProvider-1.0.jar"); framework.getBundleContext().installBundle("file:D:/parent/consumer/target/OSGiDmHelloWorldConsumer-1.0.jar"); for (Bundle bundle : framework.getBundleContext().getBundles()) { bundle.start(); System.out.println("Bundle: " + bundle.getSymbolicName()); if (bundle.getRegisteredServices() != null) { for (ServiceReference serviceReference : bundle.getRegisteredServices()) System.out.println("\tRegistered service: " + serviceReference); } } } private void loadScrBundle(Framework framework) throws URISyntaxException, BundleException { URL url = getClass().getClassLoader().getResource("org/apache/felix/scr/ScrService.class"); if (url == null) throw new RuntimeException("Could not find the class org.apache.felix.scr.ScrService"); String jarPath = url.toURI().getSchemeSpecificPart().replaceAll("!.*", ""); System.out.println("Found declarative services implementation: " + jarPath); framework.getBundleContext().installBundle(jarPath).start(); } } 

1.1.C

 Starting OSGi Framework Found declarative services implementation: file:/C:/Users/Revilo/.m2/repository/org/apache/felix/org.apache.felix.scr/1.6.2/org.apache.felix.scr-1.6.2.jar INFO : org.apache.felix.scr (1): Version = 1.6.2 DEBUG: Starting ComponentActorThread Bundle: org.apache.felix.framework Registered service: [org.osgi.service.resolver.Resolver] Registered service: [org.osgi.service.packageadmin.PackageAdmin] Registered service: [org.osgi.service.startlevel.StartLevel] Bundle: org.apache.felix.scr Registered service: [org.apache.felix.scr.ScrService] Registered service: [org.osgi.service.cm.ManagedService] Registered service: [org.apache.felix.scr.impl.ScrGogoCommand] Bundle: null Bundle: null 

我不得不做很多让你的样本复制问题。

首先关闭您的反应堆订单在父项中是错误的。 这就是你必须一直安装mvn的原因。

  OSGiDmHelloWorldProvider OSGiDmHelloWorldConsumer main dist  

接下来,如果在父级中定义依赖项(例如JUnit),则不需要在子级中对其进行redfine。

接下来,通常将父标签放在pom的顶部。

我没有理由让你的子模块与父版本有不同的版本,所以我删除了标签,所以它们都有来自父版本的1.0-SNAPSHOT

接下来,您在OSGiDmHelloWorldProvider依赖项中有错误的组ID(它应该是rev)。

   rev OSGiDmHelloWorldProvider 1.0-SNAPSHOT  

在主模块中,您具有不在reactor中的依赖项。 我猜这只是对样本的疏忽。

   rev core 1.0-SNAPSHOT  

毕竟, mvn clean package -DskipTests=true可以正常工作。

您的Main类中有一个硬编码字符串,显然对我不起作用。 (您也可以查看免费的IDEA社区而不是Eclipse!)

 String baseDir = "D:/standAloneDev/java/workingDir/Sample Projects/Eclipse/Gen/OSGiDmHelloWorld/dist/target/dist-1.0-SNAPSHOT-bin/plugins/"; 

你应该做这个亲戚。 例如

 File baseDir = new File("dist/target/dist-1.0-SNAPSHOT-bin/plugins/"); String baseDirPath = baseDir.getAbsolutePath(); loadScrBundle(framework); File provider = new File(baseDirPath, "OSGiDmHelloWorldProvider-1.0-SNAPSHOT.jar"); File consumer = new File(baseDirPath, "OSGiDmHelloWorldConsumer-1.0-SNAPSHOT.jar"); framework.getBundleContext().installBundle(provider.toURI().toString()); framework.getBundleContext().installBundle(consumer.toURI().toString()); 

无论如何,在完成它之后,我注意到bundle.getSymbolicName()上的以下javadoc。

 Returns the symbolic name of this bundle as specified by its Bundle-SymbolicName manifest header. The bundle symbolic name should be based on the reverse domain name naming convention like that used for java packages. 

所以在org.apache.felix.scr-1.6.2.jar的MANIFEST.MF中你有

 Bundle-Name: Apache Felix Declarative Services Bundle-SymbolicName: org.apache.felix.scr 

由于您没有创建清单并将其添加到jar中,因此您没有这个。

您需要添加执行阶段并告诉jar插件使用清单:

   maven-jar-plugin   ${project.build.outputDirectory}/META-INF/MANIFEST.MF     org.apache.felix maven-bundle-plugin   bundle-manifest process-classes  manifest    true   OSGiDmHelloWorldProvider com.bw.osgi.provider.able com.bw.osgi.provider.ProviderActivator Baptiste Wicht