Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement OSGi modularization

2025-03-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail how to implement OSGi modularization, the content of the article is of high quality, so the editor will share it for you as a reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.

OSGi Modularization-

Lars Vogel,Simon Scholz (c) 2008 jue 2017 vogella GmbH version 5.2202.02.2017

Catalogue

Introduction to OSGi Software Modularization

1.2 . OSGi specification and OSGi implementation

OSGi is a set of specifications that define the component and service model of Java in its core specification. The practical advantage of OSGi is that each software component can define its API through a set of exported Java packages, and each component can specify the dependencies it needs.

Components and services can be dynamically installed, activated, deactivated, updated, and uninstalled.

The OSGi specification has several implementations, such as Eclipse Equinox,Knopflerfish OSGi or Apache Felix.

Eclipse Equinox is a reference implementation of the basic OSGi specification. It is also the runtime environment on which Eclipse applications are based.

1.4 . Naming conventions: simple plug-ins

A plug-in can be generated through Eclipse through the file? New? Other...? Plug-in development? Plug-in project menu item. The corresponding wizard allows you to specify multiple options. This script invokes plug-ins generated with the following options: simple plug-ins or simple packages.

No activator

No contribution to the user interface

Not a rich client application

There is no template at build time

2.1 . Manifest file (MANIFEST.MF)

Technically, OSGi plug-ins are .jar files with additional meta-information. This meta-information is stored in the META-INF / MANIFEST.MF file. This file is called a manifest file and is part of the standard Java specification to which OSGi adds additional metadata. According to the Java specification, any Java runtime must ignore unknown metadata. Therefore, plug-ins can be used without restrictions in other Java environments.

The following list is an example of a manifest file.

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

The following table describes the identifiers in the manifest file. For information about the version patterns commonly used in OSGi, see using OSGi for semantic versioning.

Table 1. Description of the OSGi identifier in the manifest file

Package name

Short description of the plug-in.

Bundle-SymbolicName

Unique identifier of the plug-in. If this plug-in uses the extension point feature of Eclipse, it must be marked as Singleton. You can do this by adding the following statement after the Bundle-SymbolicName identifier:; singleton:=true

Bundle-Version

Define the plug-in version, and if a new version of the plug-in is released, it must be incremented.

Bundle-Activator

Defines an optional activator class BundleActivator that implements the interface. An instance of this class is created when the plug-in is activated. Whenever the plug-in is started or stopped, its start () and stop () methods are called. The OSGi activator can be used to configure the plug-in during startup. Activating the execution of the program increases the startup time of the application, so you should use this feature with caution.

Bundle-RequiredExecutionEnvironment (BREE)

Specify the version of Java required to run the plug-in. If this requirement is not met, the plug-in is not loaded by the OSGi runtime.

Bundle-ActivationPolicy

Setting this to delay tells the OSGi runtime that one of its plug-ins (that is, classes and interfaces) will be activated only if it is used by other plug-ins. If not set, the Equinox runtime does not activate the plug-in, that is, the services provided by this plug-in are not available.

Bundle-ClassPath

Bundle-ClassPath specifies the location where the class is loaded from bundle. The default value is "." . It allows classes to be loaded from the root of bundle. You can also add JAR files to it, which are called nested JAR files.

2.3 . Semantic versioning using OSGi

OSGi recommends using version numbers defined by field identifiers. Mode Bundle-Version. If you change the plug-in code, add the version according to the following rule set.

If all changes are backward compatible, they will be increased.

If the public API has changed, but all changes are backward compatible, it is increased.

If the change is not backward compatible, it will be increased.

For more information about this release scheme, see Eclipse version number Wiki.

2.5 . The plug-in lifecycle is in OSGi

By installing the plug-in in the OSGi runtime, the plug-in will remain in the local bundle cache. The OSGi runtime then tries to resolve its dependencies.

If all necessary dependencies are resolved, the plug-in is located in the

RESOLVED state, otherwise it remains in the INSTALLED state.

In cases where there are several plug-ins that can satisfy dependencies, use the plug-in with the most valid version.

If the version is the same, the plug-in with the lowest unique identifier (ID) is used. Each plug-in gets this ID assigned by the framework during installation.

When the plug-in starts, its status is STARTING. When it starts successfully, it becomes ACTIVE.

This lifecycle is shown in the following figure.

3. API definition of the plug-in

In the MANIFEST.MF file, the plug-in also defines its API by exporting the package identifier. All packages that are not explicitly exported are not visible to other plug-ins.

All of these restrictions implement classloader through a specific OSGi. Each plug-in has its own class loader. Cannot access restricted classes without using reflection.s

Unfortunately, OSGi does not prevent you from using Java reflection to access these classes. This is because OSGi is based on a Java runtime that does not yet support the modularization layer.

With the x-internal flag, the OSGi runtime can mark exported packages as temporary. This allows other plug-ins to use the corresponding classes, but indicates that these classes are not considered official API.

The following screenshot shows how x-internal sets the package in the manifest editor.

This is the appearance of the corresponding manifest file.

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

You can configure how the Eclipse Java editor displays the use of temporary API. This access can be configured to display errors, warnings, or if such access should not result in additional messages.

The default value is to display a warning message. Can you adjust this window according to Eclipse's preferences? Preferences? Java? Compiler? Error / warning preference settings.

You can define a set of plug-ins that can access temporary API without warning or error messages. This can be done through the x-friends instruction. This flag is added if you add a plug-in in the package visibility section of the runtime tab of the manifest editor.

Manifest-Version: 1.0Bundle-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"

This x-friends setting has the same effect, but x-internal but all plug-ins mentioned in the x-friends setting can access the package without receiving error or warning messages.

4.1 . OSGi console

The OSGi console is like a command line shell. In this console, you can type commands to perform OSGi operations. This can be used to analyze problems on the OSGi layer of the application.

For example, use the command ss to get an overview of all packages, their status, and bundle-id. The following table is a reference to the most important OSGi commands.

Table 2. OSGi command description

Help

Lists the available commands.

Ss

Lists the installed packages and their status.

Ss vogella

Lists the bundles and their states that include vogella in their names.

Start

Start the package using ID.

Stop

Use ID to stop bundling.

Diag

Diagnose specific packages. It lists all missing dependencies.

Install URL

Install the package from URL.

Uninstall

Uninstall the bundled software using ID.

Bundle

Displays information about bundles with ID, including registered and used services.

Headers

Displays the MANIFST.MF information for the package.

Services filter

Displays all available services and their consumers. The filter is an optional LDAP filter, for example, viewing all services that provide a ManagedService implementation uses the "services (objectclass = * ManagedService)" command.

4.3 . Telnet

If you specify the-console parameter in the startup configuration, Eclipse will allow you to interact with the OSGi console. By default, OSGi startup configurations created with Eclipse IDE contain this parameter. With the following parameters, you can open a port to which you can connect through the telnet protocol.

-console 5555

If you open a telnet session to the OSGi console, you can use tab to complete and command history similar to Bash shell under Linux.

5. Download Eclipse SDK

If you plan to add features to the Eclipse platform, you should download the latest version of Eclipse. The official version has a stable API, so it is a good foundation for adding plug-ins and features.

Different versions are available for Eclipse IDE. Although you can install the necessary tools in any Eclipse package, it is usually easier to download the Eclipse Standard distribution, which contains all the necessary tools for plug-in development. Other packages add more tools that are not needed for Eclipse plug-in development.

Browse to the Eclipse download site and download the Eclipse Standard package.

Eclipse 4.5 also provides a new Eclipse installer installer. If you are downloading multiple versions of Eclipse, the installer is useful because it uses a shared installation pool for common plug-ins. 6.1 . Create plug-ins for the data model

Create a simple plug-in project called com.example.e4.rcp.todo.model (see naming conventions: simple plug-ins).

The following screenshot describes the second page of the plug-in project wizard and its corresponding settings. Press the finish button on this page to avoid using templates.

6.5 . Adjust the generated getter and setter methods

Adjust the generated getter and setter dueDate () fields for defensive replication. The Date class is not immutable, we want to avoid an example of this situation where Todo can be changed externally while the corresponding setter.

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

The generated class should be similar to the following list.

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.7. Write a copy () method

Add the following copy () method to the class.

Public Todo copy () {return new Todo (this.id, this.summary, this.description, this.done, getDueDate ());} 6.9 Define the API of the model plug-in

Export the com.example.e4.rcp.todo.model package to define it as API.

To do this, open the MANIFEST.MF file and select the Runtime tab. Add com.example.e4.rcp.todo.model to the exported package.

7.1 . Create a data model provider plug-in (service plug-in)

Create a new simple plug-in project called com.example.e4.rcp.todo.services (see naming conventions: simple plug-ins). This plug-in is called a to-do service plug-in in the following description.

The folder at the end of MacOS's operating system kick. The service is special, so we use it. The service is over.

7.3 . Provide the implementation of ITodoService interface

Com.example.e4.rcp.todo.services.internal creates the package in the service plug-in and creates the following classes.

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 rootTag; public MyTodoServiceImpl () {todos = createInitialModel (); createRootTag (todos);} @ Override public void getTodos (Consumer todosConsumer) {/ / always pass a new copy of the data todosConsumer.accept (todos.stream (). Map (t-> t.copy ()) .requests (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 (newTodo (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 ();} Appendix A: copyright and license

Copyright ©2012-2016 vogella GmbH. Examples of free use of the software are granted under the terms of the EPL license. This tutorial is released under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany license.

On how to implement OSGi modularization is shared here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report