ITPub博客

首页 > 应用开发 > Java > OSGi模块化 - 教程

OSGi模块化 - 教程

翻译 Java 作者:85579711 时间:2017-03-17 11:34:52 0 删除 编辑
OSGi与Eclipse Equinox。本教程概述了OSGi及其模块化层。对于本教程,使用Eclipse 4.5(Luna)。

OSGi简介软件模块化

1.1。什么是软件模块化?

应用程序由不同的部分组成,这些部分通常称为软件组件软件模块

这些组件通过应用程序编程接口(API)相互交互。API被定义为可以从其他组件使用的一组类和方法。组件还具有一组被认为是软件组件内部的类和方法。

如果组件使用来自另一个组件的API,则它对另一个组件具有依赖性,即,它需要另一个组件存在并正常工作。

由其他组件使用的组件应尽量保持其API稳定,以避免更改影响其他组件。但它应该能够自由地改变其内部实现。

Java在其当前版本(Java 8)中没有提供用于描述软件组件依赖性的结构化方法。Java只支持访问修饰符的使用,但每个公共类都可以从另一个软件组件调用。期望的是明确定义软件组件的API的方式。OSGi规范填补了这个缺口。

1.2。OSGi规范和OSGi实现

OSGi是一组规范,在其核心规范中定义了Java的组件和服务模型。OSGi的实际优点是每个软件组件可以通过一组导出的Java包来定义其API,并且每个组件可以指定其所需的依赖性。

组件和服务可以被动态地安装,激活,去激活,更新和卸载。

OSGi规范有几个实现,例如Eclipse Equinox,Knopflerfish OSGi或Apache Felix。

Eclipse Equinox是基本OSGi规范的参考实现。它也是Eclipse应用程序所基于的运行时环境。

1.3。插件或软件包作为软件组件

OSGi规范将束定义为模块化的最小单位,即在OSGi中软件组件是束。Eclipse编程模型通常调用它们 插件, 但这些术语是可互换的。有效的插件始终是有效的插件,有效的插件始终是有效的插件。在此脚本 ,首选使用 插件,以与Eclipse插件开发的术语保持一致。

插件是一个内聚的,独立的单元,它明确地定义了它对其他组件和服务的依赖性。它还通过Java包定义其API。

1.4。命名约定:简单的插件

一个插件可以通过Eclipse中通过生成文件  ? 新建  ? 其他...  ? 插件开发  ? 插件工程菜单项。相应的向导允许指定多个选项。此脚本调用使用以下选项生成的插件:简单插件简单包

  • 无激活剂

  • 对用户界面没有贡献

  • 不是一个富客户端应用程序

  • 生成时没有模板

2. OSGi元数据

2.1。清单文件(MANIFEST.MF)

技术上OSGi插件是 带有附加元信息的.jar文件。此元信息存储在 META-INF / MANIFEST.MF 文件中。此文件称为 清单 文件,是标准Java规范的一部分,OSGi向其中添加了额外的元数据。根据Java规范,任何Java运行时必须忽略未知的元数据。因此,在其他Java环境中可以无限制地使用插件。

以下列表是清单文件的示例。

Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Popup Plug-in Bundle-SymbolicName: com.example.myosgi; singleton:=true Bundle-Version: 1.0.0 Bundle-Activator: com.example.myosgi.Activator Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6

下表说明了清单文件中的标识符。有关OSGi中通常使用的版本模式的信息,请参阅使用OSGi进行语义版本控制

表1.清单文件中的OSGi标识符
标识符 描述

软件包名称

插件的简短描述。

Bundle-SymbolicName

插件的唯一标识符。如果此插件使用Eclipse的扩展点功能,则必须将其标记为Singleton。您可以通过在Bundle-SymbolicName标识符之后添加以下语句来实现: ; singleton:=true

Bundle-Version

定义插件版本,如果发布了插件的新版本,则必须递增。

Bundle-Activator

定义实现接口的可选激活器类BundleActivator该类的实例在插件被激活时创建。无论何时启动或停止插件,都会调用start()stop()方法。OSGi激活器可用于在启动期间配置插件。激活程序的执行会增加应用程序的启动时间,因此应谨慎使用此功能。

Bundle-RequiredExecutionEnvironment(BREE)

指定运行插件所需的Java版本。如果不满足此要求,则OSGi运行时不会加载插件。

Bundle-ActivationPolicy

将此设置为 延迟 将告诉OSGi运行时,只有当其插件之一(即类和接口)被其他插件使用时,才会激活该插件。如果未设置,Equinox运行时不会激活插件,即,此插件提供的服务不可用。

Bundle-ClassPath

Bundle-ClassPath指定从bundle加载类的位置。默认值为“。”。它允许从bundle的根加载类。您还可以向其中添加JAR文件,这些文件称为 嵌套JAR文件

2.2。Bundle-符号名称和版本

每个插件都有一个通过Bundle-SymbolicName 属性定义的符号名称 该名称以插件作者的反向域名开头,例如,如果您拥有“example.com”域,则该符号名称以“com.example”开头。

每个插件在Bundle-Version 属性中也有一个版本号 

在 Bundle-Version 和 Bundle-SymbolicName 唯一标识一个插件。

2.3。使用OSGi的语义版本化

OSGi建议对 通过 字段标识符定义的版本号使用 。。模式 Bundle-Version如果更改插件代码,请根据以下规则集增加版本。

  • 如果所有更改都向后兼容,则会增加

  • 如果公共API已更改,但所有更改都向后兼容,则增加。

  • 如果更改不向后兼容,则会增加

有关此版本方案的更多信息,请参阅 Eclipse版本编号Wiki

2.4。通过清单文件指定插件依赖关系

插件可以通过其清单文件定义对其他软件组件的依赖性。OSGi防止访问没有定义的依赖关系的类并抛出ClassNotFoundException唯一的例外是来自Java运行时环境的包(基于插件的Bundle-RequiredExecutionEnvironment定义)。JRE包始终可用于插件,而没有显式定义的依赖关系。

如果您向清单文件添加依赖项,Eclipse IDE会自动将相应的JAR 文件添加 到您的项目类路径中。

您可以将依赖关系定义为插件依赖关系或包依赖关系。如果定义插件依赖关系,则插件可以访问此插件的所有导出包。如果指定包依赖关系,则可以访问此包。使用包依赖关系允许您交换稍后提供此包的插件。如果你需要这种灵活性,更喜欢使用包依赖。

依赖管理

插件可以定义它取决于另一个bundle的某个版本(或范围),例如插件A可以定义它依赖于版本2.0中的插件C,而插件B定义它取决于插件C的版本1.0。

OSGi运行时确保所有依赖关系在启动插件之前都存在。OSGi在安装期间读取插件的清单文件。它确保所有依赖的插件也被解析,并且如果需要,在插件启动之前激活它们。

2.5。插件的生命周期在OSGi

通过在OSGi运行时中安装插件,插件将保留在本地bundle缓存中。OSGi运行时然后尝试解析它的依赖关系。

如果解决了所有必需的依赖关系,则插件位于

RESOLVED 状态,否则它保持在 INSTALLED 状态。

在存在可以满足依赖性的几个插件的情况下,使用具有最高有效版本的插件。

如果版本相同,则使用具有最低唯一标识符(ID)的插件。每个插件都会在安装期间获取框架分配的此ID。

插件启动时,其状态为 STARTING成功启动后,它将变为 ACTIVE

此生命周期如下图所示。

OSGi生命周期

2.6。动态导入包

由于遗留的原因,OSGi支持动态导入包。有关 详细信息,请参阅 OSGi Wiki中的动态导入您不应该使用此功能,它是非模块化设计的症状。

3.插件的API定义

MANIFEST.MF文件中,插件还通过导出包标识符定义其API。未显式导出的所有软件包对其他插件不可见。

依赖管理

所有这些限制都通过特定的OSGi实施classloader每个插件都有自己的类加载器。不使用reflection.s不能访问受限类

不幸的是,OSGi不能阻止你使用Java反射来访问这些类。这是因为OSGi基于尚不支持模块化层的Java运行时。

通过x-internal标志,OSGi运行时可以将导出的包标记为临时。这允许其他插件使用相应的类,但表示这些类不被视为官方API。

以下屏幕截图显示如何x-internal在清单编辑器中设置包

设置x内部标志

这是相应的清单文件的外观。

Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Provider Bundle-SymbolicName: de.vogella.osgi.xinternal.provider Bundle-Version: 1.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: de.vogella.osgi.xinternal.provider;x-internal:=true

您可以配置Eclipse Java编辑器如何显示临时API的使用。这种访问可以被配置为显示为,错误,警告或者如果这种访问应当不导致附加消息。

默认值为显示警告消息。您可以通过Eclipse的喜好调整这个窗口  ? 首选项  ? 的Java  ? 编译器  ? 错误/警告首选项设置。

Eclipse中的设置,用于已弃用的API使用的警告

您可以定义一组插件可以访问临时API,而不会出现警告或错误消息。这可以通过x-friends指令完成如果您在清单编辑器的“ 运行时 ”选项卡上的“ 包可见性”部分添加插件,则会添加此标志

Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Provider Bundle-SymbolicName: de.vogella.osgi.xinternal.provider Bundle-Version: 1.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: de.vogella.osgi.xinternal.provider;x-friends:="another.bundle"

x-friends设置具有相同的效果,x-internal但是x-friends设置中提到的所有插件都可以访问包,而不会收到错误或警告消息。

4.使用OSGi控制台

4.1。OSGi控制台

OSGi控制台就像一个命令行shell。在此控制台中,您可以键入命令以执行OSGi操作。这可以用于分析应用程序的OSGi层上的问题。

例如,使用命令 ss 获取所有包的概述,它们的状态和bundle-id。下表是最重要的OSGi命令的参考。

表2. OSGi命令
命令 描述

help

列出可用的命令。

ss

列出安装的软件包及其状态。

ss vogella

列出捆绑包及其在其名称中包含vogella的状态

start 

使用 ID 启动包

stop 

使用 ID 停止捆绑

diag 

诊断特定包。它列出所有缺失的依赖项。

install URL

从URL安装包。

uninstall

使用 ID 卸载捆绑软件

bundle 

显示具有 ID的捆绑包的信息,包括已注册和已使用的服务。

headers 

显示包的MANIFST.MF信息。

services filter

显示所有可用的服务及其消费者。过滤器是一个可选的LDAP过滤器,例如,查看提供ManagedService实现的所有服务使用“services(objectclass = * ManagedService)”命令。

4.2。必需的包

您必须将以下包添加到运行时配置中才能使用OSGi控制台。

  • org.eclipse.equinox.console

  • org.apache.felix.gogo.command

  • org.apache.felix.gogo.runtime

  • org.apache.felix.gogo.shell

4.3。Telnet

如果 在启动配置中指定 -console参数,Eclipse将允许您与OSGi控制台交互。默认情况下,使用Eclipse IDE创建的OSGi启动配置包含此参数。通过以下参数,您可以打开一个端口,您可以通过telnet协议连接到该端口。

-console 5555

如果打开到OSGi控制台的telnet会话,您可以使用tab完成和类似于 Linux下Bash shell 的命令历史记录 

4.4。访问Eclipse OSGi控制台

您还可以访问运行的Eclipse IDE的OSGi控制台。在 控制台视图中, 您可以使用工具提示打开控制台找到一个菜单项 如果选择主机OSGi控制台,您将可以访问正在运行的OSGi实例。

请注意,通过OSGi控制台干扰您运行的Eclipse IDE可能会使Eclipse IDE处于错误状态。

5.下载Eclipse SDK

如果您计划向Eclipse平台添加功能,则应下载最新的Eclipse版本。官方版本具有稳定的API,因此是添加插件和功能的良好基础。

Eclipse IDE提供了不同的版本。虽然可以在任何Eclipse包中安装必要的工具,但通常更容易下载Eclipse Standard发行版,其中包含插件开发的所有必要工具。其他软件包增加了Eclipse插件开发不需要的更多工具。

浏览到Eclipse下载站点并下载Eclipse Standard软件包。

下载Eclipse插件IDE
Eclipse 4.5还提供了一个新的Eclipse安装程序安装程序。如果您要下载多种版本的Eclipse,安装程序将非常有用,因为它使用共享安装池用于常用插件。

6.练习:数据模型插件

在本练习中,您将为数据模型的定义创建一个插件。还可以将此数据模型用于其他插件。

6.1。为数据模型创建插件

创建一个名为com.example.e4.rcp.todo.model的简单插件项目(请参阅命名约定:简单插件

以下屏幕截图描述了插件项目向导的第二页及其相应的设置。按此页上完成按钮,以避免使用模板。

创建一个简单的插件

6.2。创建基类

创建com.example.e4.rcp.todo.model包和以下模型类。

package com.example.e4.rcp.todo.model;  import java.util.Date;  public class Todo {  private final long id; private String summary = ""; private String description = ""; private boolean done = false; private Date dueDate = new Date();  }
您的最终ID字段出现错误。此错误在下一节中解决。

6.3。生成构造函数

选择来源  ? 使用字段...生成构造成利用各个领域的构造函数。使用相同的方法仅使用id字段创建另一个构造函数

确保您已创建两个构造函数,因为它们在以下练习中是必需的。

6.4。生成getter和setter方法

使用来源  ? 生成getter和setter ...菜单来创建getter和setter方法为您的字段。

为什么id字段标记为final?

ID是终局的,因此Eclipse将创建只有一个getter。这是正确和希望的。我们将使用此字段来生成equalshashCode()方法,因此它不应该是可变的。更改这是在使用的字段equalshashCode()方法可以创建错误,这些错误是难以确定的,即,一个对象包含在一个HashMap,但没有找到。

getter和setter生成

6.5。调整生成的getter和setter方法

调整生成的getter和setter dueDate()字段以进行防御性复制。Date班是不是一成不变的,我们要避免这种情况的一个实例Todo可以从外部改变,而相应的setter。

public Date getDueDate() { return new Date(dueDate.getTime()); }  public void setDueDate(Date dueDate) { this.dueDate = new Date(dueDate.getTime()); }

生成的类应该类似于以下列表。

package com.example.e4.rcp.todo.model;  import java.util.Date;  public class Todo {  private final long id; private String summary = ""; private String description = ""; private boolean done = false; private Date dueDate = new Date();  public Todo(long id) { this.id = id; }  public Todo(long id, String summary, String description, boolean done, Date dueDate) { this.id = id; this.summary = summary; this.description = description; this.done = done; setDueDate(dueDate);  }  public long getId() { return id; }  public String getSummary() { return summary; }  public void setSummary(String summary) { this.summary = summary; }  public String getDescription() { return description; }  public void setDescription(String description) { this.description = description; }  public boolean isDone() { return done; }  public void setDone(boolean done) { this.done = done; }  public Date getDueDate() { return new Date(dueDate.getTime()); }  public void setDueDate(Date dueDate) { this.dueDate = new Date(dueDate.getTime()); }  }

6.6。生成toString(),hashCode()和equals()方法

使用Eclipse 根据id 和 summary 字段toString() 为Todo类 生成一个 方法 这可以通过Eclipse菜单来完成   ? 生成的toString()...

还使用Eclipse生成 基于id 字段的方法hashCode() 和 equals()方法 这可以通过Eclipse菜单来完成   ? 生成的hashCode()和equals()...

6.7。编写一个copy()方法

将以下copy() 方法添加 到类中。

public Todo copy() { return new Todo(this.id, this.summary, this.description, this.done, getDueDate()); }

6.8。创建todo服务的接口

创建以下 ITodoService 界面。

package com.example.e4.rcp.todo.model;  import java.util.List; import java.util.Optional; import java.util.function.Consumer;  public interface ITodoService {  void getTodos(Consumer<List> todosConsumer);  boolean saveTodo(Todo todo);  Optional getTodo(long id);  boolean deleteTodo(long id);  }

6.9。定义模型插件的API

导出com.example.e4.rcp.todo.model包以将其定义为API。

为此,请打开MANIFEST.MF文件并选择“ 运行时 ”选项卡。添加com.example.e4.rcp.todo.model到导出的包。

导出的API

练习:创建服务包

在本练习中,您为服务实现创建一个插件,该插件提供对数据的访问。

此服务实现使用临时数据存储,即,数据不在应用程序重新启动之间持久化。要持久化数据,您可以扩展此类以将数据存储在数据库或文件系统中。由于此存储对于Eclipse RCP应用程序不是特殊的,因此不在此脚本中。

7.1。创建数据模型提供程序插件(服务插件)

创建一个名为com.example.e4.rcp.todo.services的新简单插件(请参阅命名约定:简单插件)项目此插件在以下描述中称为待办服务插件。

MacOS的操作系统踹结尾的文件夹。服务特殊,因此我们使用。服务结束。

7.2。定义服务插件中的依赖关系

com.example.e4.rcp.todo.model插件作为依赖项添加到服务插件。要实现这一点,请打开MANIFEST.MF文件。然后选择“ 依赖关系 ”选项卡,将com.example.e4.rcp.todo.model软件包添加到“ 导入的软件包”

7.3。提供ITodoService接口的实现

com.example.e4.rcp.todo.services.internal 在服务插件中创建 包并创建以下类。

package com.example.e4.rcp.todo.services.internal;  import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.stream.Collectors;  import com.example.e4.rcp.todo.model.ITodoService; import com.example.e4.rcp.todo.model.Tag; import com.example.e4.rcp.todo.model.Todo;  public class MyTodoServiceImpl implements ITodoService {  private static AtomicInteger current = new AtomicInteger(1); private List todos;  private Tag<tag> rootTag;  public MyTodoServiceImpl() { todos = createInitialModel(); createRootTag(todos); }  @Override public void getTodos(Consumer<List> todosConsumer) { // always pass a new copy of the data todosConsumer.accept(todos.stream().map(t -> t.copy()).collect(Collectors.toList())); }  protected List getTodosInternal() { return todos; }  // create or update an existing instance of Todo @Override public synchronized boolean saveTodo(Todo newTodo) { // hold the Optional object as reference to determine, if the Todo is // newly created or not Optional todoOptional = findById(newTodo.getId());  // get the actual todo or create a new one Todo todo = todoOptional.orElse(new Todo(current.getAndIncrement())); todo.setSummary(newTodo.getSummary()); todo.setDescription(newTodo.getDescription()); todo.setDone(newTodo.isDone()); todo.setDueDate(newTodo.getDueDate());  if (!todoOptional.isPresent()) { todos.add(todo); } return true; }  @Override public Optional getTodo(long id) { return findById(id).map(todo -> todo.copy()); }  @Override public boolean deleteTodo(long id) { Optional deleteTodo = findById(id);  deleteTodo.ifPresent(todo -> { todos.remove(todo); });  return deleteTodo.isPresent(); }  // Example data, change if you like private List createInitialModel() { List list = new ArrayList<>(); list.add(createTodo("Application model", "Flexible and extensible")); list.add(createTodo("DI", "@Inject as programming mode")); list.add(createTodo("OSGi", "Services")); list.add(createTodo("SWT", "Widgets")); list.add(createTodo("JFace", "Especially Viewers!")); list.add(createTodo("CSS Styling", "Style your application")); list.add(createTodo("Eclipse services", "Selection, model, Part")); list.add(createTodo("Renderer", "Different UI toolkit")); list.add(createTodo("Compatibility Layer", "Run Eclipse 3.x")); return list; }  private Todo createTodo(String summary, String description) { return new Todo(current.getAndIncrement(), summary, description, false, new Date()); }  private Optional findById(long id) { return getTodosInternal().stream().filter(t -> t.getId() == id).findAny(); }  }</tag

7.4。更新产品配置(通过您的功能)

将新的.model 和 .services 插件添加 到您的 com.example.e4.rcp.todo.feature 功能。确保您使用 feature.xml 文件中的“插件 ”选项卡 

每次创建一个新插件并在MANIFEST.MF文件中引用它时,都必须将其添加到产品配置文件中(通过特性项目)。

练习:创建服务包

8.1。创建工厂以访问服务实现

[dataservice_plugin]中 创建两个插件。为了向消费者提供服务实现,最好的解决方案是使用 OSGi服务, 但为了保持这种描述,我们在本练习中简单使用一个工厂。

在 包中创建一个名为TodoServiceFactory的新类 com.example.e4.rcp.todo.services为此,您可能需要以下提示。

在其默认配置中,Eclipse IDE会隐藏父包(如果它们不包含任何类)。在指定类期间,您可以定义正确的包。这在下面的屏幕截图中描述。
指定用于创建类的包

该类ITodoService 通过静态方法访问您的 实现。它可以被认为是一个 工厂 的 ITodoService 接口。工厂隐藏了某个接口的具体实例的创建。

package com.example.e4.rcp.todo.services;  import com.example.e4.rcp.todo.model.ITodoService; import com.example.e4.rcp.todo.services.internal.MyTodoServiceImpl;  /**
 * factory provides access to the todo service provider
 *
 */ public class TodoServiceFactory {  private static ITodoService todoService = new MyTodoServiceImpl();  public static ITodoService getInstance() { return todoService; }  }

8.2。导出服务插件中的包

com.example.e4.rcp.todo.services 通过“ 运行时 ”选项卡上的MANIFEST.MF 文件 导出 包 ,以便其他插件可用。

请注意,Eclipse工具不支持导出空包。您必须在包中至少创建一个类,然后才能将其导出。

9.教程:使用激活器并导出包

在本练习中,您创建另一个使用 Activator您还在Eclipse中运行它在本章结尾,您还将导出您的包,以便稍后在独立的OSGi服务器中使用它。

9.1。创建新的捆绑包

通过创建一个新的简单的插件项目“com.vogella.osgi.firstbundle.internal” 文件  ? 新建  ? 其他...  ? 插件开发  ? 插件项目

9.2。编码

创建以下线程类。

package com.vogella.osgi.firstbundle.internal;  public class MyThread extends Thread { private volatile boolean active = true;  public void run() { while (active) { System.out.println("Hello OSGi console"); try { Thread.sleep(5000); } catch (Exception e) { System.out.println("Thread interrupted " + e.getMessage()); } } }  public void stopThread() { active = false; } }

将Activator.java类更改为以下类。

package com.vogella.osgi.firstbundle;  import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext;  import de.vogella.osgi.firstbundle.internal.MyThread;  public class Activator implements BundleActivator { private MyThread myThread;  public void start(BundleContext context) throws Exception { System.out.println("Starting com.vogella.osgi.firstbundle"); myThread = new MyThread(); myThread.start(); }   public void stop(BundleContext context) throws Exception { System.out.println("Stopping com.vogella.osgi.firstbundle"); myThread.stopThread(); myThread.join(); }  }

9.3。

选择您的 MANIFEST.MF 文件,右键单击它并选择菜单:运行方式[运行配置]。创建OSGi Framework启动配置。取消选择除de.vogella.osgi.firstbundle之外的所有包。然后按 添加所需捆绑这会将org.eclipse.osgi 包添加 到运行配置中。

firstbundle30

运行此配置。每5秒钟一个新消息写入控制台。

firstbundle40
如果你想知道OSGi开始在哪个文件夹中找到它在$ {workspace_loc} /。metadata / plugins / org.eclipse.pde.core / 。此文件夹通过文件“dev.properties”列出已安装的软件包,并通过osgi.bundles = reference \:file \ statement将Eclipse工作区设置为config.ini文件中的引用。这样,您可以在运行的OSGi环境中直接更新您的软件包,无需任何部署。

9.4。导出您的捆绑包

导出您的捆绑包。这将允许您将其安装到OSGi运行时。选择您的捆绑包,然后选择文件  ? 导出  ? 插件开发  ?可部署的插件和碎片

firstbundle50
firstbundle60

取消标记导出源的选项。

firstbundle65

10.运行独立OSGi服务器

本章将介绍如何将Equinox作为OSGi独立运行时运行。在Eclipse安装目录中标识文件org.eclipse.osgi * .jar。此文件应位于plugin文件夹中。将此jar文件复制到新位置,例如c:\ temp \ osgi-server将文件重命名为“org.eclipse.osgi.jar”。通过以下命令启动OSGi服务器。

java -jar org.eclipse.osgi.jar

但是单独运行osgi jar通常是不需要的。

因此,org.eclipse.osgi束需要由被配置的config.ini位于一个文件结构的文件夹。

为了从命令行传递命令到OSGi运行时,需要额外的bundle。

  • org.eclipse.equinox.console

  • org.apache.felix.gogo.command

  • org.apache.felix.gogo.runtime

  • org.apache.felix.gogo.shell

要使用org.eclipse.osgi包启动这些包,config.ini文件必须如下所示:

osgi.bundles=org.eclipse.equinox.console@start, org.apache.felix.gogo.command@start, org.apache.felix.gogo.shell@start, org.apache.felix.gogo.runtime@start osgi.noShutdown=true eclipse.ignoreApp=true

使用此配置,其他bundle必须位于org.eclipse.osgi包之外。

osgi独立dir结构

使用此设置,可以使用附加-console参数类似地启动OSGi运行时

java -jar org.eclipse.osgi_3.11.2.v20161107-1947.jar -console

一旦这样开始,可以使用OSGi控制台,例如,通过使用命令ss来查看可用的软件包。

osgi standalone show bundles命令

您还可以使用“安装URL”从某个URL安装捆绑包。例如,从c:\ temp \ bundles安装软件包 use:

install file:c:\temp\bundles\plugins\de.vogella.osgi.firstbundle_1.0.0.jar

您可能需要更正系统上的路径和包名称。

您可以使用start和id启动包。

firstbundle70

您可以使用-clean参数删除所有已安装的软件包。

12. OSGi资源

12.1。vogella GmbH培训和咨询支持

训练 服务和支持

vogella公司提供 来自Eclipse RCP,Android,Git,Java,Gradle和Spring等领域专家的全面培训和教育服务我们提供公共和内部培训。无论你决定采取什么样的课程,你都可以在参考之前体验到许多之前的“我参加的最好的IT类”

vogella公司提供专家咨询服务,开发支持和辅导。我们的客户范围从财富100强公司到个人开发商。

版权所有©2012-2016 vogella GmbH。免费使用软件示例是根据EPL许可证的条款授予的。本教程是根据 Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany许可证发布的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29063131/viewspace-2135522/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2013-07-22

  • 博文量
    39
  • 访问量
    99757