2012-06-13 122 views
1

我有关于声明式OSGi服务的问题。我有以下接口:声明式OSGi服务

public interface PrintService { 
    public void print(); 
    } 

及其实施:

public class PrintServiceImpl implements PrintService { 

     @Override 
     public void print() { 
     System.out.println("Hello from PrintServiceImpl!"); 
     } 
    } 

OSGI-INF/component.xml文件:

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="service"> 
    <implementation class="service.PrintServiceImpl"/> 
    <service> 
     <provide interface="print.PrintService"/> 
    </service> 
</scr:component> 

MANIFEST.MF:

Service-Component: OSGI-INF/component.xml 

我安装服务并启动后它什么都没有发生。我怎样才能激活它并打印“Hello PrintServiceImpl!”到控制台。

+0

您可以在管理控制台中看到您声明的服务吗?它活跃吗? –

+0

是的,我使用命令“ss”并且它是活动的,但是命令“ls”状态是“不满意”。 –

+1

检查你的软件包org.eclipse.equinox.ds及其依赖项是否添加到启动配置中 –

回答

2

为什么你期望你的print方法被调用?它是服务的接口的一部分,所以它不会被调用,直到你可以绑定到它并调用它的客户端。

如果您在控制台中键入services命令,您应该看到您的软件包正在发布print.PrintService服务;这意味着你的组件正在工作。如果您没有看到这一点,那么您可能会错过上面评论中Tom Seidel建议的SCR套件。

+0

我该如何调用打印方法? –

+0

另一个包中的一些其他代码将不得不获得该服务并调用该方法。 – Robin

+0

如果你没有客户想要打电话,你为什么要写打印方法? –

1

也许你想从你的激活方法打印?

public class PrintServiceImpl implements PrintService { 
    protected final void activate() { 
     System.out.println("Hello from PrintServiceImpl!"); 
    } 
    protected final void deactivate() { 
     System.out.println("Goodbye from PrintServiceImpl!"); 
    } 
    ... 
} 

否则,尼尔的答案是正确的:你要使用通过ServiceTracker的或<reference>服务,并明确调用print()方法的客户端。

+0

谢谢你的回答,我发现在激活XML文件可以通过激活方法:) –

+0

这是真的,你可以指定一个任意方法作为激活方法。为了代码的可维护性,我建议你坚持使用“激活”这个名称,除非你有强烈的向后兼容性理由来命名它。您可以始终使用activate()方法调用其他传统方法。 –

3

您应该明确表示希望服务在启动时启动。否则,它将被懒惰地实例化,并且认为没有其他服务需要PrintService,它将不会被实例化。

您可以使用属性enabledimmediate来控制您的服务生命周期(关于软件包生命周期)。 enabled很简单:指示您的服务在启动时是否启用。 immediate指示此服务是否懒惰。 immediate="true"将开始为您服务立刻immediate="false"将申请延迟实例(即等到其他一些服务请求该服务的依赖)

例如

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="PrintService" 
activate="activate" 
deactivate="deactivate" 
modified="modified" 
enabled="true" 
immediate="true"> 

正如克里斯提到的,如果你希望你的服务时,它的启动做一些事情,你应该添加一些代码到activate生命周期方法(注意方法的名称可以在喜欢它的组件描述符中指定在上面已明确完成)

protected final void activate() { 
    print(); 
} 
1

以上所有答案都是正确的。我们有一些像打印东西的外壳,你可以写这样的:

public interface PrintService { 
    public void print(); 
} 

Implentation:

public class PrintServiceImpl implements PrintService { 

     @Override 
     public void print() { 
     System.out.println("Hello from PrintServiceImpl!"); 
     } 
} 

component.xml文件:

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="service"> 
    <implementation class="service.PrintServiceImpl"/> 
    <service> 
     <provide interface="print.PrintService"/> 
    </service> 
</scr:component> 

现在你可以使用一个命令拨打您的打印方式:

public class PrintCommand implements Command { 

    private PrintService printer; 

    public void setPrinter(PrintService printer) { 
     this.printer = printer; 
    } 

    public void unsetPrinter(PrintService printer) { 
     this.printer = null; 
    } 

    @Override 
    public void execute(String line, PrintStream arg1, PrintStream arg2) {  
     printer.print(); 
    } 

    @Override 
    public String getName() { 
     return "print"; 
    } 

    @Override 
    public String getShortDescription() { 
     return "just a printer"; 
    } 

    @Override 
    public String getUsage() { 
     return "print"; 
    } 

} 

和你component.xml文件应该有一个新的条目:

<component name="PrintCommand"> 
    <implementation class="PrintCommand"/> 
    <service> 
     <provide interface="org.apache.felix.shell.Command"/> 
    </service> 
    <reference 
     name="printer" 
     interface="PrintService" 
     bind="setPrinter" 
     unbind="unsetPrinter" 
     cardinality="1..1" 
     policy="static" 
    /> 
</component> 

命令接口是Apache的菲利克斯Shell的一部分,如果你现在运行菲利克斯和在控制台输入help你会看到所有已注册的命令,并存在PrintCommand以及print。如果你现在在shell中输入print,你会看到文本。

0

你有没有得到这个工作?对我而言,Eclipse .ds软件包尚未开始,因此该服务尚未注册(尚未)。当我手动启动时,我的服务已正确注册。

相关问题