我做了一个maven-osgi项目,其中一个激活器应该发送一个osgi事件但是由于某种原因,EventAdmin总是为空。
这是我的java类
package com.example.eventhandler;
import java.util.Dictionary;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
public class App implements BundleActivator {
public void start(BundleContext context) throws Exception {
ServiceReference ref = context.getServiceReference(EventAdmin.class.getName());
if (ref != null) {
EventAdmin eventAdmin = (EventAdmin) context.getService(ref);
Dictionary properties = new Hashtable();
eventAdmin.sendEvent(new Event("com/acme/reportgenerator/GENERATED", properties));
} else {
System.out.println("Ref is null!!");
}
System.out.println("Hello World!!");
}
public void stop(BundleContext context) throws Exception {
System.out.println("Goodbye World!!");
}
}
这是我的pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>eventhandler</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eventhandler</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<bundle.symbolicName>com.example</bundle.symbolicName>
<bundle.namespace>com.example</bundle.namespace>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
<version>3.7.1</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.osgi.compendium</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<manifestLocation>META-INF</manifestLocation>
<instructions>
<Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName>
<Bundle-Version>${pom.version}</Bundle-Version>
<Bundle-Activator>${bundle.namespace}.eventhandler.App</Bundle-Activator>
<Import-Package>
org.osgi.framework,
org.osgi.service.event
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
EventAdmin为空的原因是什么?
答案 0 :(得分:2)
您已在OSGi中实现了经典的反模式:您认为在捆绑包启动时,EventAdmin服务已经可用。这是一个固有的不安全假设,因为您的bundle实际上可能在提供EventAdmin服务的bundle之前启动。
有一种错误的方法和正确的方法来解决这个问题。错误的方法是坚持在EventAdmin之后必须启动捆绑包。这种方式导致了启动顺序依赖性和极端脆弱性。请参阅:http://wiki.osgi.org/wiki/Avoid_Start_Order_Dependencies
正确的方法是使用声明式服务(DS)等框架来声明捆绑包中引用EventAdmin服务的组件。然后,DS将激活您的组件,并在它可用时立即将其注入EventAdmin实例。请参阅:http://wiki.osgi.org/wiki/Declarative_Services