我有一个Maven OSGi多模块项目。当OSGi从各个项目模块中选择模块罐时,该项目运行良好。 (查看以下1.1.B) 。
但是,使用第二种方法,bundle.getRegisteredServices()
(在下面查看1.1.A) ,每当我尝试使用存放在中央文件夹中的包时,都会返回null (D:/ parent / provider / target / modules)使用maven-assembly-plugin version : 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 HERE 上有一个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<String, String> map = new HashMap<String, String>();
// 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
答案 0 :(得分:1)
我必须做很多事情才能让你的样本重复这个问题。
首先关闭您的反应堆订单在父项中是错误的。这就是你必须一直安装mvn的原因。
<modules>
<module>OSGiDmHelloWorldProvider</module>
<module>OSGiDmHelloWorldConsumer</module>
<module>main</module>
<module>dist</module>
</modules>
接下来,如果您在父级中定义了一个依赖项(例如JUnit),则不需要在子级中重新定义它。
接下来,通常将父标签放在pom的顶部。
我没有理由让您的子模块与父版本具有不同的版本,因此我删除了标记,因此它们都有来自父级的1.0-SNAPSHOT
。
接下来,您在OSGiDmHelloWorldProvider依赖项中有错误的组ID(它应该是rev)。
<dependency>
<groupId>rev</groupId>
<artifactId>OSGiDmHelloWorldProvider</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
在主模块中,您有一个不在反应堆中的依赖项。我猜这只是对样本的疏忽。
<dependency>
<groupId>rev</groupId>
<artifactId>core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
毕竟,mvn clean package -DskipTests=true
有效。
您的Main类中有一个硬编码字符串,显然对我不起作用。 (您也可能希望查看免费的IDEA Community而不是Eclipse!)
String baseDir = "D:/standAloneDev/java/workingDir/Sample Projects/Eclipse/Gen/OSGiDmHelloWorld/dist/target/dist-1.0-SNAPSHOT-bin/plugins/";
你应该做这个亲戚。 e.g。
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插件使用清单:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>OSGiDmHelloWorldProvider</Bundle-SymbolicName>
<Export-Package>com.bw.osgi.provider.able</Export-Package>
<Bundle-Activator>com.bw.osgi.provider.ProviderActivator</Bundle-Activator>
<Bundle-Vendor>Baptiste Wicht</Bundle-Vendor>
</instructions>
</configuration>
</plugin>