Showing posts with label java. Show all posts
Showing posts with label java. 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.

Tuesday, June 19, 2018

OSGi R7 Highlights: Configuration Admin and Configurator

The OSGi Compendium Release 7 specification contains an update to the Configuration Admin Service specification which includes a number of new features and also introduces the new Configurator specification.

Configuration Admin


One of the most used but on the other hand barely noticed services from the OSGi compendium specification is the Configuration Admin. This service allows to create, update and delete configurations. It is up to the implementation where these configurations are stored. A configuration has a unique persistent identifier (PID) and a dictionary of properties.

Usually, configurations are tied to an implementation of an OSGi service but configurations can be used for any purpose like database connections, current temperature or the set of available nodes in a cloud setup. While the Configuration Admin service has an API to find configurations or create them, it supports a more inversion of control like behavior by supporting a callback mechanism. The callback (known as the ManagedService interface) gets invoked for existing/created configurations of a certain PID and also if that configuration is deleted.

While this callback exists, again it's not that common to use it directly. The most common and easiest way to develop OSGi components and services is to use Declarative Services. Declarative Services (DS) provides build-in support for configurations. Simply by implementing an activation method the component can get its configuration. The implementor of that component does not have to worry whether such a configuration exists, gets deleted or is modified. DS takes care of all of this and invokes the right actions on the component.

In addition to single configurations, Configuration Admin provides support for factory configurations: multiple configurations of the same type, like for example different logger configurations for different categories or different database connection configurations. These factory configurations have a factory PID which is the same for all configurations of that type and a configuration PID to distinguish those configurations.

This should explain the big picture. Let's start talking about the new things in Release 7.

Configurator Specification


The Configurator specification is a new specification in the R7 release. It basically consists of two parts. The first part describes a common textual representation of a set of configurations. Previous to this specification each and every tool was using its own format for provisioning configurations. For example, the famous Apache Felix File Install uses a properties like format. Other tools use slightly different formats. One problem is that you can't simply switch from one tool to another and the other major problem is that some of the formats do not allow to specify the real type of a property value. For example, the value for the service ranking property must be of type Integer. Or you might have a special implementation that is expecting (for whatever reason) a value to be of type Byte. However, some tools are simply always using a Long to represent numbers or a String to represent anything else.

Therefore a common definition eliminates these problems and allows interchangeability of configurations between various tools. The format is JSON based and uses the PIDs of a configuration as the keys. The value is the configuration object with the properties:

{
    "my.component.pid": {
        "port:Integer" : 300, 
        "array:int[]" : [2, 3, 4], 
        "collection:Collection<Integer>" : [2,3,4], 
        "complex": { 
            "a" : 1, 
            "b" : "two"
        }
    }
}

As you can see in the example, it is possible to specify the runtime type of a configuration property by separating the property name from the type using a colon. For example, the "port" property value is of type Integer, the "array" property value is an array of ints and the "collection" property value is of type Collection<Integer>. You can specify all allowed types for a configuration and the configurator implementation uses converting rules as defined by the Converter specification - another one of the new specifications of Release 7.

In addition, a configuration property can hold structured JSON as a string value. In the example above "complex" contains at runtime a string value of the specified JSON.

Factory configurations can be specified by using the following syntax: FACTORY_PID~NAME. With the updated Configuration Admin it is possible to use a meaningful name to address factory components. The tilde separates the factory PID from the name:

{
    "my.factory.component~foo" : {
        ...
    },
    "my.factory.component~bar" : {
        ...
    }
}

Please note the errata for the published specification.

OSGi Bundle Configurations


The second part of the configurator specification describes a new extender based mechanism that picks up configurations from within a bundle and applies them. A bundle can contain one or more JSON files with configurations and once the bundle is started the configurations will be put into Configuration Admin by the Configurator. The configurator manages the state handling and ordering in a deterministic way. For example, if two bundles contain a configuration for the same PID, a ranking mechanism is used to specify which configuration is put into Configuration Admin, regardless of their installation or start order.

In addition to provide configurations through bundles, the Configurator supports providing initial configurations through system properties on startup of the OSGi framework. This is especially useful for customising an application without changing the distributable for the application. By specifying the system property configurator.initial with either a JSON document as described above or a list of URLs pointing to such JSON documents, the Configurator will apply the contained configurations in the same manner as if they would have been provided through a bundle.

With this new feature, provisioning of configurations through bundles and allowing to override them on startup becomes part of the OSGi specifications. You will find an example application using the Configurator at the OSGi enRoute website. The specification of the Configurator has driven the update of the Configuration Admin specification. So let's talk about the most important new features in Configuration Admin.

Improved Factory Configuration Handling


The handling of factory configurations has been greatly improved. With previous versions, when you create a factory configuration, the PID part is randomly generated which makes identifying a particular factory configuration later on much harder. In addition, as the PID is auto-generated, it has no meaning. With the updated Configuration Admin, it is now possible to specify the PID of a factory configuration, eliminating those problems.

New methods on the Configuration Admin allow to create and retrieve factory configurations based on the factory PID and a name. These methods behave the same as the already existing methods for plain configurations. The PID for those factory components is generated by appending the name to the factory PID separated by a tilde. The Configurator uses this syntax to specify factory configurations as shown above.

Improved Configuration Plugin Handling


When a configuration is delivered to a managed service, the configuration is passed through registered configuration plugin services. Such a service can manipulate the configuration. One common use case is to handle placeholders in the configuration properties and replace them with real values when delivered. For example, a property of a database connection configuration could just contain the value "${database.url}" which is replaced with the actual URL when this configuration is passed to the component processing the configuration. Or if you have sensitive configuration data, you can store it encrypted in the configuration and just decrypt it in a configuration plugin before it is passed to the managed service.

While this mechanism sounds useful, it is only useful if you register a managed service. However, when you are using Declarative Services (or other component frameworks) for your components, the plugins are not called at all. This gap is closed now and the DS implementation uses a new functionality of the Configuration Admin service and calls the plugins before it is passing the configuration to its components. This ensures plugins will be called regardless how you get your configuration. And this is making those use cases mentioned above possible.

Conclusion


The standard format for OSGi configurations is a great step forward for tooling and the Configurator implementation allows to deploy configurations through bundles in a standardized and well-specified way. The update of the Configuration Admin resolves some long outstanding issues and allows for new use cases around configuration management. For all the new features of the Configuration Admin service, have a look at the specification and make sure to also read the new Configuration specification.


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:
  1. Proposed Final Draft Now Available
  2. Java 9 Support
  3. Declarative Services
  4. The JAX-RS Whiteboard
  5. The Converter
  6. Cluster Information
  7. Transaction Control
  8. The Http Whiteboard Service
  9. Push Streams and Promises 1.1
Be sure to follow us on Twitter or LinkedIn or subscribe to our Blog feed to find out when it's available.

Tuesday, May 22, 2018

OSGi R7 Highlights: The Http Whiteboard Service

The OSGi Compendium Release 7 specification contains version 1.1 of the Http Whiteboard specification which includes a number of new features.

Before we dive into the new features, let's start with a summary of what the Http Whiteboard Specification is about: It provides a light and convenient way of using servlets, servlet filters, listeners and web resources in an OSGi environment through the use of the Whiteboard Pattern. The specification supports registration of the above-mentioned web entities and grouping them together in context. A three-part introduction into the Release 6 version of the Http Whiteboard can be found here, here and here.

Component Property Types


Registering web entities using the Http Whiteboard usually requires specifying several service registration properties. In Release 7, Declarative Services added the ability to use component property types to annotate components and set property values in a type-safe manner. A set of annotations has been added to the Http Whiteboard specification to make use of this new feature in Declarative Services, simplifying the development of such web entities.

For example, registering a servlet at the path /game looks now like this:
@Component(service = Servlet.class)
@HttpWhiteboardServletPattern("/game")
public class MyServlet extends HttpServlet {
  ...
}

Similarly, defining additional service properties can easily be done by adding more annotations to the class. In the following example, we declare the servlet to support asynchronous processing and mount the servlet in a specific Http Context (in contrast to using the default context as above):
@Component(service = Servlet.class)
@HttpWhiteboardServletPattern("/game")
@HttpWhiteboardContextSelect("(" 
  + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME
  + "=mycontext)")
@HttpWhiteboardServletAsyncSupported
public class MyServlet extends HttpServlet {
  ...
}

Further annotations have been added to simplify the development of servlet filters, resources, listeners error pages, and servlet context. A full list of these can be found here.

Multipart File Upload


Support for multipart file upload handling and configuring this handling has been added. The possibilities are the same as supported by the servlet specification. The multipart handling can be enabled for a servlet by specifying additional service registration properties. Again, using a component property types simplifies the specification of the required properties. In the following example we enable multipart file upload for the servlet and restrict the size of the uploaded files to 500,000 bytes:
@Component(service = Servlet.class)
@HttpWhiteboardServletPattern("/game")
@HttpWhiteboardServletMultipart(maxFileSize=500000)
public class UploadServlet extends HttpServlet {
  ...
}

The chapter about Multipart File Upload contains a complete description of the service properties for multipart file upload.

Pre-Filtering


A servlet filter is registered with an Http Context together with some rules when the filter is applied, e.g., by specifying a path pattern or a servlet name. However, servlet filters are run after a potential user authentication and therefore never get run when this authentication fails. In addition, these filters are only run if the request is targeting an existing endpoint, either a servlet or a resource.

On the other hand, some use cases require running some code with every request or before authentication. For example, logging all requests, regardless of whether authentication is successful is one of those use cases. Preparing the request by adding additional information from a third party system might be another one.

With the updated Http Whiteboard specification, a new web entity, the Preprocessor has been added. All services registered with this interface are invoked before request dispatching or authentication is performed. Therefore such a preprocessor will receive all requests. The Preprocessor interface is just an extension of the servlet filter interface and just acts as a marker to distinguish a preprocessor from a normal servlet filter. The following example implements a simple preprocessor, logging all requests:
@Component(service = Preprocessor.class)
public class LoggingFilter implements Preprocessor {

  public void doFilter(ServletRequest request,
                       ServletResponse response,
                       FilterChain chain)
  throws IOException, ServletException {
    System.out.println("New request to "
      + ((HttpServletRequest)request).getRequestURI());
    chain.doFilter(request, response);
  }

  public void init(FilterConfig filterConfig)
  throws ServletException {
    // initialize the preprocessor
  }

  public void destroy() {
    // clean up
  }
}

As a preprocessor is invoked for every request, there are no special service properties for this type of service, especially this service is not associated with any Http Context as the dispatching to a context happens after the preprocessors are invoked.

Updated Security Handling


Security handling or authentication can be implemented by registering your own implementation of the ServletContextHelper service and implementing the handleSecurity method. Web entities like servlets or filters can then be associated with this context ensuring that they are only invoked if the authentication is successful.

While the handleSecurity methods provide a good mechanism to check for authentication and potentially add additional information to the current request like a user context which can then be used by the web components, a method for cleaning up such state was missing. With the update of the Http Whiteboard, a new method finishSecurity has been added which is now closing this gap. This new method is the counterpart of handleSecurity and is invoked when the request processing is done. By implementing this method any resources allocated through handleSecurity can be cleaned up.

More on the Http Whiteboard Update


This blog post mentions only those new features which I think are the most important ones of the new version 1.1. You can find the full list of changes at the end of the Http Whiteboard specification.


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:
  1. Proposed Final Draft Now Available
  2. Java 9 Support
  3. Declarative Services
  4. The JAX-RS Whiteboard
  5. The Converter
  6. Cluster Information
  7. Transaction Control
Be sure to follow us on Twitter or LinkedIn or subscribe to our Blog feed to find out when it's available.

Tuesday, April 10, 2018

OSGi R7 Highlights: The Converter

One of the entirely new specifications in the OSGi R7 set of specs is the Converter specification. The converter can convert between many different Java types and can also be a highly convenient tool to give untyped data a proper API.

Let's dive in with some simple converter examples:

// Obtain the converter
Converter c = Converters.standardConverter();

// Simple scalar conversions
int i = c.convert("123").to(int.class);
UUID id = c.convert("067e6162-3b6f-4ae2-a171-2470b63dff00")
           .to(UUID.class);
BigDecimal bd = c.convert(12345).to(BigDecimal.class);

Collections, arrays and maps can also be converted:

List<String> ls = Arrays.asList("978", "142", "-99");

// Convert a List of Strings to a Set of Integers, 
// note the use of TypeReference to capture the generics
Set<Integer> is = c.convert(ls)
                   .to(new TypeReference<Set<Integer>>(){});

// Convert between map-like structures
Dictionary<String, String> d = ...; // some dictionary
Map m = c.convert(d).to(Map.class);

// Even though properties contain String keys and values, you 
// can't assign them to a Map<String, String>, the converter 
// can make this easy...
Properties p = ...; // a properties object
Map<String, String> n = c.convert(p)
           .to(new TypeReference<Map<String,String>>(){});

The above examples show that many different types of conversions can be made with the converter, using the same convert(object).to(type) API.

Note that the converter is obtained by calling Converters.standardConverter() so by default it's not registered in the service registry. This makes the converter usable in both OSGi Framework as well as in plain Java environments.

Backing Objects

An interesting feature of the converter is that it can convert between maps and Java types such as interfaces, annotations and java beans. Together we call these map-like types. In certain cases the conversion can provide a live view over the backing object. 

For example, let's say you have an interface MyAPI:

interface MyAPI {
    long timeout();
    long timeout(long defval);
}

Now you have a map that contains a timeout key with some value, if you want to expose that via the MyAPI interface the converter can do this:

Map<String, Long> m = new HashMap<>();
m.put("timeout", 999L);
MyAPI o = c.convert(m).to(MyAPI.class);
System.out.println(o.timeout()); // prints 999
m.put("timeout", 1000L);         // update the underlying map
System.out.println(o.timeout()); // prints 1000

The other way around is also possible. For example, if you have a JavaBean that you need to view as a Map, then the converter can do this. In the following example, we see that in order for the converter to handle a source object as a JavaBean you need to specify the sourceAsBean() modifier. Additionally, live views for maps are not enabled by default and are enabled with the view() modifier.

MyBean bean = new MyBean();
bean.setLength(120);
bean.setWidth(75);
Map<String, String> bm = c.convert(bean).sourceAsBean().view()
           .to(new TypeReference<Map<String,String>>(){});
System.out.println("Bean map:" + bm);
bean.setWidth(125)                    // update the bean
System.out.println("Bean map:" + bm); // map reflects the update

In addition to the map-like types mentioned above, the converter can handle DTOs and when an object exposes a method called getProperties(), it can take this as the source map as well.

Defaults

Converting a map or properties object to a Java interface can be a really useful way to give some untyped configuration a well-defined API. Often you'd want to be able to specify some defaults for the configuration values that you're using, in case they are not specified. When converting to interfaces or annotations defaults can be specified.

When converting to an interface, the interface may define a one-argument method to specify the default, as is done with the MyAPI interface above. To specify the default pass it into the method:

Map<String, Long> m = new HashMap<>(); // empty map
MyAPI o = c.convert(m).to(MyAPI.class);

// default to 750 if no timeout is in the map
System.out.println(o.timeout(750L));

Handling defaults via an annotation is even a little neater, as the Java annotation syntax allows for the specification of defaults.     

@interface MyAnn {
    long timeout() default 100;
}

MyAnn a = c.convert(m2).to(MyAnn.class);
System.out.println(a.timeout()); // use default 100
m2.put("timeout", 500L);
System.out.println(a.timeout()); // now get the actual value 500


Customizing Converters

While the converter can convert between many types (see the spec chapter for the actual list of supported types) it doesn't understand every single Java type ever created. Let's say we have two custom types Foo and Bar. There is a conversion between the two, but the converter doesn't know about it. We can create a customized converter that, on top of its existing conversions, knows about our special conversion as well!

Let's say our custom classes look a bit like this. The Foo class can be represented as a string which you can obtain via its read() method. The Bar class can hold a byte array.

public class Foo {
    // ...
    public String read() {
        return val;
    }
}

public static class Bar {
    byte[] buf;

    public static Bar create(byte[] b) {
        Bar bar = new Bar();
        bar.buf = b;
        return bar;
    }
}

To create a converter that, on top of the existing conversions, knows about Foo and Bar, we use a converter builder and register a rule with that to do the conversion. In the example below, the Rule object declares the source and the target of the rule. The conversion is provided as a lambda:

Foo f = ...; // Some Foo object
Converter custom = c.newConverterBuilder()
    .rule(new Rule<Foo, Bar>(
        foo -> Bar.create(foo.read().getBytes())){})
    .build();

// Now we can convert Foo to Bar!
Bar b = custom.convert(f).to(Bar.class);

Now the converter can convert our custom objects. An additional benefit is that the converter is an immutable object. You can customize an already customized converter by creating a new converter based on the previously created custom one.

Because the converter is immutable it's ideal for sharing, so once you've customized the perfect converter for your application, a good way to share it is by registering it in the OSGi Service Registry, and because the default converter isn't available in the service registry, your application components can simply look up the Converter service to get the one you registered for application wide usage.

Getting Started

This blog post doesn't cover all the details of the converter specification. See the spec chapter for more info on those. Like to get started straight away? At the time of this writing the specs are still under vote and not yet finally released. However, you can obtain a snapshot converter implementation from the OSGi Maven Repo: https://oss.sonatype.org/content/repositories/osgi/org/osgi/org.osgi.util.converter/ or you can build one yourself from the codebase in the Apache Felix project: https://svn.apache.org/repos/asf/felix/trunk/converter/converter.



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:
  1. Proposed Final Draft Now Available
  2. Java 9 Support
  3. Declarative Services
  4. The JAX-RS Whiteboard
Be sure to follow us on Twitter or LinkedIn or subscribe to our Blog feed to find out when it's available.

An evening of OSGi with BGJUG on April 17 Sofia, Bulgaria

The BGJUG and Software AG are kindly hosting an Evening of OSGi on Tuesday April 17 from 7pm.

The OSGi Alliance is in Sofia conducting its Expert Group face to face meetings and Board meeting so this evening event will provide an excellent opportunity to meet with the local Java community while we are in town.

There are two talks lined up from the OSGi Alliance:

  • the first is an 'Introduction to OSGi' by BJ Hargrave (OSGi Alliance CTO) and 
  • the second is a look at 'How OSGi Alliance specifications have influenced the IoT market' by Pavlin Dobrev & Kai Hackbath (Bosch). 

In addition Todor Boev from Software AG will be presenting 'OSGi and JPMS in practice' which will discuss Software AG's experiences with OSGi and Jigsaw/JPMS now that Java 9 is released.

The event is being held at Sofia Tech Park / Incubator building, Tsarigradsko shoes 111B, 1784 Sofia [MAP].

Please be sure to register in advance to secure your place.

Thanks to BGJUG and Software AG for their assistance in arranging this event and of course to the speakers for their support.

We hope you can join us.

Monday, May 1, 2017

OSGi and JSR 376 Java Platform Module System (JPMS)

The OSGi Alliance is aware that there are a number of conversations taking place about the Public Review draft of JSR 376 Java Platform Module System (JPMS). This is planned to be a major feature of Java 9 and is under ballot to complete Public Review. The OSGi Alliance will analyze JPMS and may comment on our findings in the future.

In the meantime our Expert Groups are busy working on the OSGi Release 7 which is planned for October this year. You can find the RFPs and RFCs for the new Release 7 features at https://github.com/osgi/design and draft specifications at https://www.osgi.org/developer/specifications/drafts/.

BJ Hargrave
OSGi Alliance CTO

Thursday, September 29, 2016

InfoQ: A comparison of OSGi and the Java 9 Java Platform Module System

In Java 9, OSGi and the Future of Modularity, Neil Bartlett and Kai Hackbarth provide part 1 of an excellent comparison of OSGi modularity and the current state of Java 9's Java Platform Module System (JPMS) modularity.
One of the most common complaints about OSGi is that it can increase complexity for a developer. There is a grain of truth here, but people who make this complaint are mistaking the medicine for the disease.
Modularity is not a magic dust that can be sprinkled onto an application just before release. It is a discipline that must be followed throughout all phases of design and development. Developers who adopt OSGi early and apply modular thinking before writing a line of code realise enormous gains[...]
Project Jigsaw started with a goal of being simple, but the JPMS specification has increased enormously in complexity: the interplay of modules with class loaders; hierarchical layers and configurations; re-exporting requirements; weak modules; static requirements; qualified exports; dynamic exports; inherited readability across layers; multi-module JARs; automatic modules; unnamed modules… all these features have been added as the need for them became clear. A similar process happened in OSGi, just with a 16-year head start.
The article is well written and provides a clear understanding of the differences between OSGi and JPMS as it stands today. Looking forward to part 2.

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

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

Friday, October 26, 2012

4.3 Companion Code for Java 7

Starting in version 4.3, OSGi started to use generics in some of the API including the Core specification. Generics were introduced to the Java language in Java 5. However, OSGi needed to continue to support embedded use cases which use the CDC/Foundation 1.1 runtime which is still based upon the Java 1.4 language level and JVM. To address this issue, OSGi compiled the APIs with -target jsr14; an undocumented javac flag introduced before Java 5 was final. So we had the best of both worlds: we can use generics and still compile to run on Java 1.4 based runtimes.

This worked for Java 5 and Java 6. But when Java 7 shipped, two things changed: javac no longer understood the jsr14 option to -target and javac refused to recognize the attributes containing the generics information in class files already compiled with -target jsr14. The change to no longer support creating -target jsr14 class files was ok; we could continue to compile with Java 6 javac. But the change to the javac to cease to recognize the class file attributes with the generics information in existing class files was a bigger problem. It meant that the 4.3 API jars published by OSGi were not useable by people who need to compile with Java 7 javac. By not useable, I mean javac treated the classes as if they did not contain any generics information: they were raw. A bug was filed against Java to see if this was some mistake or oversight. The reply was that the change was intentional.

At the time this was first noticed, Java 7 was new and not too widely used. OSGi also included the source code in the jars so you could recompile the code yourself if you needed. Later, when it came time to ship Core R5, we changed to compile the API classes with -target 1.5 and so they work fine on Java 7. So problem solved; the new release's jars don't use -target jsr14! Except some of the current OSGi implementations (I'm looking at you Felix and Karaf) are still based upon Core 4.3 and thus people using those implementations still need to use the Core 4.3 API. And if they also want to use Java 7, they need to recompile the OSGi API source. So after some prodding by a few folks, OSGi rebuilt the Core and Compendium API jars as Core 4.3.1 and Compendium 4.3.1. The new jars have the same packages at the same package versions having the same API signatures. They are just not compiled with -target jsr14 so they work fine with Java 7.

So if you need to use the 4.3 API with Java 7, pick up these new 4.3.1 jars. They should also be available on maven shortly.

Wednesday, August 29, 2012

OSGi Picking Up The Pieces

Jigsaw – the prototype project that was widely expected to become the Java™ SE 8 Module System – might now be deferred to at least Java 9. Given this uncertainty, the OSGi Alliance felt it was appropriate to state our position with respect to Java platform modularity.

Modular systems reduce maintenance and development time and so cost. For these reasons, the OSGi Alliance has dedicated more than a dozen years to the pursuit of modularity, creating the dynamic module system for Java. Now in 2012, OSGi is in daily use creating highly maintainable, extensible, and agile business applications and solutions. Application and systems developers already benefit from the mature OSGi dynamic module system for Java, proven with its adoption worldwide in Fortune Global 100 company products and services and in diverse markets including enterprise, mobile, home, telematics and consumer. The OSGi Alliance and its members continue to simplify the use of OSGi and invite the wider Java community to support this work, including documentation efforts.

Clearly, a modularized Java platform would complete this story: reducing both bloat and memory footprint, improving startup times, better accommodating embedded environments, and future-proofing Java with removable components would be highly beneficial for Java developers, architects and users.

Designing a module system takes time and experience and so the OSGi Alliance supports Oracle’s consideration not to ship Java SE 8 with Jigsaw. Especially as an incomplete modularity design would hurt the Java community. Yet, we should not delay the work on the Java Module System JSR.

The solution

OSGi technology is based on open industry specifications and more than a decade of experience. The OSGi Alliance recommends that the Java community use OSGi as the cornerstone technology to modularize the Java platform; OSGi already providing not only the necessary technology foundation to successfully achieve modularization of Java SE, but also a growing ecosystem of developers and deployers of OSGi technology. The Module System JSR should be based on OSGi concepts, and enable similar maintenance, extensibility, and agility benefits for the Java platform, creating a single, coherent modularization approach from the Java platform up through the application.

How do we move forwards?

Today the only module framework that exists for Java is that defined by the OSGi Alliance standards. Based on these foundations, the Alliance is willing to work with our existing ecosystem of experienced partners, the JCP and the wider Java community to collectively design the best Java Module System to secure the future of the Java platform. Collectively, we can accelerate the JCP process and related projects like Penrose; and most importantly deliver the module system design that the Java community deserves. The Java Module System JSR needs to be started right away to begin this challenging work.

Richard Nicolson
OSGi Alliance President