Showing posts with label bnd. Show all posts
Showing posts with label bnd. Show all posts
Wednesday, September 13, 2023
BND Tools 7.0 Release Candidate 1 is available
We are happy to announce the BND Tools 7.0.0 Release Candidate, which can now be downloaded here. Thanks to the support by members of the OSGi Working Group the code base has been ported to Java 17 and the release features the support of multi release JARs (among many other changes). For the changelog and release notes, please check out Github. You can also contribute via the issue tracker or discuss the latest release in the bnd forums.
Wednesday, March 14, 2018
OSGi R7 Highlights: Declarative Services
The OSGi Compendium Release 7 specification contains version 1.4 of the Declarative Services specification which includes a number of exciting new features.
If you are not familiar with Declarative Services (DS), it is the dependency injection model for OSGi programming that fully supports OSGi modularity and services and the dynamic nature of both. Declarative Services uses a declarative model for publishing, finding and binding to OSGi services. This model simplifies the task of authoring OSGi services by performing the work of registering the service and handling service dependencies. This minimizes the amount of code a programmer has to write; it also allows service components to be loaded only when they are needed. As a result, bundles need not provide a BundleActivator class to collaborate with others through the service registry.
Declarative Services was introduced as an OSGi specification in 2005 supporting method injection. DS has been updated to add an annotation-based programming model in version 1.2 and to add support for field injection, component property types, and introspection in version 1.3. Version 1.4 of DS now adds support for constructor injection, activation fields, enhancements to component property types, and a number of smaller enhancements.
A Service Component is a Java class which can be optionally registered as an OSGi service and can optionally use OSGi services. The runtime for DS is called Service Component Runtime (SCR) and uses component descriptions in the bundle (in XML form) to instantiate and wire components and services together. The component descriptions are used by SCR as a performance choice so that SCR can avoid processing all classes in a bundle to search for annotations at runtime. But writing XML is not really great for developers, so DS provides annotations which can be used in source code. Tooling, such as Bnd, is then used to generate the component description XML from the annotations during bundle building. So when the following example service component is included in a bundle by Bnd, Bnd will process the annotations and generate the component description XML for the component in the bundle.
Prior to 1.4, DS supported method injection:
and field injection:
New to DS 1.4 is support for constructor injection:
The Activate annotation is used to mark the constructor to be used by SCR for constructor injection. By default, SCR will use the public no-parameter constructor. Since, by their nature, constructors can only be called once per object instance, only static policy references can be used for constructor injection. For dynamic policy references, you will need to use either field or method injection.
Both scalar and multiple cardinality references are supported for constructor injection. Here is an example of multiple cardinality where the type of the referenced service is determined from the generic signature of the parameter.
In addition to injecting the service objects for referenced services, you can also inject objects related to referenced services just as you can also do for method and field injection.
Finally, constructor injection also supports passing activation objects to the component constructor. Activation objects are the objects you can pass to the activate method. Any constructor parameter not annotated with Reference must be an activation object.
In addition to supporting injecting activation objects using constructor injection, and also method injection via the activate method, DS 1.4 adds support for field injection of activation objects. A field of the type of an activation object can be annotated with Activate and SCR will inject the activation object into the field after object construction.
Component property types were added to DS in version 1.3. A component property type is an annotation that is used to both define and consume component properties in a type safe manner. For example, we can define the following component property type:
When this component property type is used in a component:
it both defines the component property named my.port (the annotation element names are mapped to component property names) and sets its value to 8080 in the generated component description. SCR will also generate an instance of the component property type which can be injected into the component instance and then be used to access the component property in a type safe manner.
And since DS supports type conversion for the component property value, even if the component property value was a string value of "8080", your component implementation does not need to worry.
Lets say you wanted to set the my.port component property for your component to a value other than 8080 and could not change the declaration of the component property type (because other components might also use the same component property type), in DS 1.3 you would have to use a non-type-safe string:
New for DS 1.4 is the ability to also use component property types to annotate components and set property values in a type-safe manner. To use a component property type in this way, you must annotate the component property type with ComponentPropertyType. This meta-annotation lets Bnd know the annotation on the component class must be processed as a component property type for setting component property values.
Now when Bnd processes the component during bundle creation, the generated component description will set the value of the my.port component property to 9080.
There is also special support for component property types which are single-element annotations and marker annotations. For a single-element annotation, the component property name for the value element is derived from the component property type name instead of the element name value. For a marker annotation, a component property name is derived from the component property type name, just as for single-element annotations, and the component property value is Boolean.TRUE. Marker annotations are only useful for setting a component property to the value true. They cannot be used to get a property value since they have no elements to call from your component implementation.
Sometimes component property names can be long. For example, osgi.http.whiteboard.servlet.name. In order to make using component property types more friendly in source code, DS supports the use of the PREFIX_ final field so that shorter element names can be mapped to longer component property names. For example, if we need the component property name com.acme.server.port and we don't want to name the element com_acme_server_port or name the single-element annotation ComAcmeServerPort, we can use the PREFIX_ final field to add a name prefix to the mapped component property name.
This new support for component property types is so useful, you will see we have defined quite a number of them throughout many of the R7 specifications to make using those specifications with DS much nicer. The DS spec defines some component property types for basic service properties and both the updated Http Whiteboard and the new JAX-RS Whiteboard specifications define component property types specific to their specifications.
I just touched on, what I feel, are the major updates for Declarative Services in the new version 1.4 specification which is part of OSGi Compendium Release 7. Make sure to check out the Changes section in the spec to see all the updates for 1.4.
PS. While the DS 1.4 specification is done, tooling and runtimes which support all of these new features may still be under development (at the time of this writing).
If you are not familiar with Declarative Services (DS), it is the dependency injection model for OSGi programming that fully supports OSGi modularity and services and the dynamic nature of both. Declarative Services uses a declarative model for publishing, finding and binding to OSGi services. This model simplifies the task of authoring OSGi services by performing the work of registering the service and handling service dependencies. This minimizes the amount of code a programmer has to write; it also allows service components to be loaded only when they are needed. As a result, bundles need not provide a BundleActivator class to collaborate with others through the service registry.
Declarative Services was introduced as an OSGi specification in 2005 supporting method injection. DS has been updated to add an annotation-based programming model in version 1.2 and to add support for field injection, component property types, and introspection in version 1.3. Version 1.4 of DS now adds support for constructor injection, activation fields, enhancements to component property types, and a number of smaller enhancements.
Service Component
A Service Component is a Java class which can be optionally registered as an OSGi service and can optionally use OSGi services. The runtime for DS is called Service Component Runtime (SCR) and uses component descriptions in the bundle (in XML form) to instantiate and wire components and services together. The component descriptions are used by SCR as a performance choice so that SCR can avoid processing all classes in a bundle to search for annotations at runtime. But writing XML is not really great for developers, so DS provides annotations which can be used in source code. Tooling, such as Bnd, is then used to generate the component description XML from the annotations during bundle building. So when the following example service component is included in a bundle by Bnd, Bnd will process the annotations and generate the component description XML for the component in the bundle.
@Component
public class ExampleImpl implements Example {
@Reference(service=LoggerFactory.class)
private Logger logger;
@Override
public void say(String message) {
logger.info(message);
}
}
<scr:component name="example.provider.ExampleImpl"
xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0">
<implementation class="example.provider.ExampleImpl"/>
<service>
<provide interface="example.api.Example"/>
</service>
<reference field="logger"
interface="org.osgi.service.log.LoggerFactory"
name="Logger"/>
</scr:component>
Constructor Injection
Prior to 1.4, DS supported method injection:
private Example example;
@Reference
void setExample(Example example) {
this.example = example;
}
and field injection:
@Reference
private Example example;
New to DS 1.4 is support for constructor injection:
private final Example example;
@Activate
public ExampleImpl(@Reference Example example) {
this.example = example;
}
The Activate annotation is used to mark the constructor to be used by SCR for constructor injection. By default, SCR will use the public no-parameter constructor. Since, by their nature, constructors can only be called once per object instance, only static policy references can be used for constructor injection. For dynamic policy references, you will need to use either field or method injection.
Both scalar and multiple cardinality references are supported for constructor injection. Here is an example of multiple cardinality where the type of the referenced service is determined from the generic signature of the parameter.
private final List<Example> examples;
@Activate
public ExampleImpl(@Reference List<Example> examples) {
this.examples = examples;
}
In addition to injecting the service objects for referenced services, you can also inject objects related to referenced services just as you can also do for method and field injection.
@Activate
public ExampleImpl(
@Reference
ServiceReference<Example> sr,
@Reference
ComponentServiceObjects<Example> so,
@Reference(service=Example.class)
Map<String,Object> serviceProps,
@Reference
Map.Entry<Map<String,Object>,Example> tuple) {
…
}
Finally, constructor injection also supports passing activation objects to the component constructor. Activation objects are the objects you can pass to the activate method. Any constructor parameter not annotated with Reference must be an activation object.
public @interface Props {
int my_port() default 8080;
}
@Activate
public ExampleImpl(
ComponentContext context,
BundleContext bc,
Map<String,Object> componentProps,
Props props) {
…
}
Activation Fields
In addition to supporting injecting activation objects using constructor injection, and also method injection via the activate method, DS 1.4 adds support for field injection of activation objects. A field of the type of an activation object can be annotated with Activate and SCR will inject the activation object into the field after object construction.
@Activate
private ComponentContext context;
@Activate
private BundleContext bc;
@Activate
private Map<String,Object> componentProps;
@Activate
private Props props;
Component Property Type Enhancements
Component property types were added to DS in version 1.3. A component property type is an annotation that is used to both define and consume component properties in a type safe manner. For example, we can define the following component property type:
public @interface Props {
int my_port() default 8080;
}
When this component property type is used in a component:
@Activate
private Props props;
it both defines the component property named my.port (the annotation element names are mapped to component property names) and sets its value to 8080 in the generated component description. SCR will also generate an instance of the component property type which can be injected into the component instance and then be used to access the component property in a type safe manner.
int my_port = props.my_port();
And since DS supports type conversion for the component property value, even if the component property value was a string value of "8080", your component implementation does not need to worry.
Lets say you wanted to set the my.port component property for your component to a value other than 8080 and could not change the declaration of the component property type (because other components might also use the same component property type), in DS 1.3 you would have to use a non-type-safe string:
@Component(property={"my.port:Integer=9080"})
New for DS 1.4 is the ability to also use component property types to annotate components and set property values in a type-safe manner. To use a component property type in this way, you must annotate the component property type with ComponentPropertyType. This meta-annotation lets Bnd know the annotation on the component class must be processed as a component property type for setting component property values.
@ComponentPropertyType
public @interface Props {
int my_port() default 8080;
}
@Component
@Props(my_port=9080)
public class ExampleImpl implements Example {
@Activate
private Props props;
…
}
Now when Bnd processes the component during bundle creation, the generated component description will set the value of the my.port component property to 9080.
There is also special support for component property types which are single-element annotations and marker annotations. For a single-element annotation, the component property name for the value element is derived from the component property type name instead of the element name value. For a marker annotation, a component property name is derived from the component property type name, just as for single-element annotations, and the component property value is Boolean.TRUE. Marker annotations are only useful for setting a component property to the value true. They cannot be used to get a property value since they have no elements to call from your component implementation.
Sometimes component property names can be long. For example, osgi.http.whiteboard.servlet.name. In order to make using component property types more friendly in source code, DS supports the use of the PREFIX_ final field so that shorter element names can be mapped to longer component property names. For example, if we need the component property name com.acme.server.port and we don't want to name the element com_acme_server_port or name the single-element annotation ComAcmeServerPort, we can use the PREFIX_ final field to add a name prefix to the mapped component property name.
@ComponentPropertyType
public @interface ServerPort {
String PREFIX_ = "com.acme.";
int value() default 8080; // com.acme.server.port property
}
This new support for component property types is so useful, you will see we have defined quite a number of them throughout many of the R7 specifications to make using those specifications with DS much nicer. The DS spec defines some component property types for basic service properties and both the updated Http Whiteboard and the new JAX-RS Whiteboard specifications define component property types specific to their specifications.
And There is More
I just touched on, what I feel, are the major updates for Declarative Services in the new version 1.4 specification which is part of OSGi Compendium Release 7. Make sure to check out the Changes section in the spec to see all the updates for 1.4.
PS. While the DS 1.4 specification is done, tooling and runtimes which support all of these new features may still be under development (at the time of this writing).
Want to find out more about OSGi R7?
This is one post in a series of 12 focused on OSGi R7 Highlights. Previous posts are:
Labels:
bnd,
bndtools,
compendium,
component design,
declarative services,
osgi,
OSGi R7
Wednesday, May 17, 2017
OSGi Community Event 2017 CFP
![]() |
is licensed under CC BY_SA 2.0.
|
The OSGi Community Event Program Committee is pleased to announce that the Call For Papers (CFP) for the 2017 event is NOW OPEN.
We are looking for submissions from anyone who has something to share about OSGi technology, the OSGi ecosystem or OSGi community. All successful submissions receive a free speaker all access pass to the OSGi Community Event and EclipseCon Europe.
Popular topics often include use cases and case studies of using OSGi, OSGi open source projects or commercial OSGi products where you have some experience to share. Presentations on tools and frameworks that can improve the developer experience are also well received. We are also looking for a 3-hour tutorial, so if you have a project or some examples on an OSGi specification where the audience can participate with you then we would welcome your submissions.
OSGi is used in many different environments and markets and we are interested in hearing from your use in any of them, be it enterprise, telecommunications, transport, retail, IoT, Industry 4.0, M2M, Cloud, or Smart Home, to name just a few.
It's always great to get submissions from new members to the community and/or new speakers so please don't be shy and get your submissions in. Whether what you have to share is small or large, state-of-the-art or traditional, business critical or a pet project, we want to hear from you.
It's always great to get submissions from new members to the community and/or new speakers so please don't be shy and get your submissions in. Whether what you have to share is small or large, state-of-the-art or traditional, business critical or a pet project, we want to hear from you.
Your submission should be either for a 35-minute talk or a 3-hour tutorial.
We are sharing the submission system with EclipseCon Europe so please be sure to select OSGi as the track when making your submission to be sure the OSGi Program Committee will get to review your proposal.
The CFP is open until July 17, however the Early Bird submission deadline is June 30.
As an added incentive to get your submissions in for the Early Bird deadline we will award a €50 Amazon Voucher to the talk selected for the OSGi Early Bird pick. Be sure to submit by June 30 to be in with a chance of winning this.
The OSGi Community Event 2017 will be taking place between October 24 to 26. Once again this year the event is being held at the Forum am Schlosspark in Ludwigsburg, Germany. As always there will be plenty of talks, BOFs, social events, beer, wine and food so make sure you have the dates in diary and start planning your travel and accommodation early.
If you have any questions please contact us by email.
Labels:
bnd,
bndtools,
cfp,
cloud,
eclipse,
EclipseCon Europe,
enterprise,
Germany,
Industry 4.0,
IoT,
ludwigsburg,
M2M,
maven,
microservices,
osgi,
OSGi Community Event,
osgi tooling
Monday, February 25, 2013
New OSGi Tool Chain Documentation
People sometimes say that OSGi is hard to use because tooling support is lacking. Well, there are actually quite a lot of OSGi-related tools out there, but many of them address a specific area. They often work together with other tools to address a larger context. A modular approach to tooling, if you like... One of the issues with this approach was however that it could be hard to find out how these tools are working together to address a real life scenario. An example scenario would be how to set up an entire development environment that includes a headless build, and IDE with debugging facilities and a testing environment. Documentation describing how to do all this using a combination of existing tools was not easily available.
Over the past months a number of people have worked together on creating a set of documentation pages that describe various OSGi toolchains: how a number of tools can be combined to create an end-to-end solution. For example, it describes how Bndtools can be used with Ant and Eclipse to create a comprehensive development setup. But there are more options. Not everyone uses Bndtools, other people might use Tycho with Eclipse and Maven. This is also documented. As is how to use Maven with Bnd, Eclipse and Pax-Exam.
Additionally there is a page describing how to set up a Scala build environment for OSGi using SBT.
All the details of how to get going are described on a new set of pages focusing on documenting OSGi tool chains on the OSGi wiki. You can find them here: http://wiki.osgi.org/wiki/ToolChains
All the details of how to get going are described on a new set of pages focusing on documenting OSGi tool chains on the OSGi wiki. You can find them here: http://wiki.osgi.org/wiki/ToolChains
The pages that are there now are just a starting point. They should get you going with a number of OSGi tooling technologies. As most of the pages use a similar example it is also possible to compare the various approaches. However, there is always room for improvement. As this is an open environment feel free to contribute. If you are using a different toolset, document it! Or if you have anything to improve the descriptions add it in!
http://wiki.osgi.org/wiki/ToolChains
http://wiki.osgi.org/wiki/ToolChains
Subscribe to:
Posts (Atom)