Workspace, Bundles, Projects

After completing the onboarding, your workspace will contain dozens of projects. The fall into the following categories.

GWT UI Projects

Those have names ending with .ui, such as com.sap.sse.security.ui or com.sap.sailing.gwt.ui. As they contain code for both, back end and front end, they are in particular also OSGi bundle projects and in many cases even OSGi web bundles, exposing the GWT UI for HTTP download from clients. Furthermore, they have the GWT nature (com.gwtplugins.gwt.eclipse.core.gwtNature) so that the GWT compiler knows what to do with them.

Projects Shared with Android App Projects

Those have names ending with .shared.android, such as com.sap.sse.shared.android or com.sap.sailing.server.gateway.serialization.shared.android, contain code that can be compiled for Android and therefore become a component of our Android apps, such as the Sailing Race Manager or the Buoy Pinger app. While this code may use multi-threading and locking, it cannot rely, e.g., on OSGi specifics such as a bundle activator getting started.

Projects Shared across GWT, Android and Back End

Bundles whose name ends with .common have to adhere to the strictest of all constraints. They must adhere to the GWT JRE emulation rules, must compile on Android and must be valid OSGi bundles, however, cannot use anything OSGi specific nor Android-specific and due to the GWT constraints must refrain from using anything related to multi-threading.

Regular OSGi Bundles

Most other bundles are regular OSGi bundles intended for deployment into the back end Equinox OSGi container. They can have an activator, declare their dependencies in their MANIFEST.MF (not in their Maven pom.xml), are usually lazy-loaded (Bundle-ActivationPolicy: lazy) and can be subject to auto-starting and start level management through a file called java/com.sap.sailing.feature.p2build/raceanalysis.product defining our OSGi "product" with the features and bundles from which it is constituted.

Some of these bundles wrap code that does not originally belong to the project but needs to be provided as an OSGi bundle. Examples include org.json.simple, org.moxieapps.gwt.highcharts which contains the GWT wrapper code for the Highcharts charting library, or com.amazon.aws.aws-java-api which wraps the AWS Java SDK's JAR files into an OSGi bundle, or org.openqa.selenium.osgi which wraps the Selenium test driver for browser-based tests. A more specific case is org.hamcrest.core which has a README explaining the detailed reasons for its existence.

Test Fragments

Most of our unit tests come in the form of OSGi fragments that extend their host bundle. Such fragments can add content to packages declared by their host bundle and hence can, e.g., have test classes that can access package/default-scoped class and interface members of the code they want to test. These test fragments are not part of the product and hence do not get shipped or released. Their Maven pom.xml files are characterized by the special eclipse-test-plugin packaging specification.

Interface-Only Bundles

When we want to define a service interface for which an implementation can be registered with the OSGi service registry, so it can be tracked and found using an OSGi ServiceTracker, it is a good idea to create separate bundles for the interface(s) and the implementation(s). Service consumers then typically will need a dependency only on the bundle providing the interface, and not on the implementation bundle(s). This way, consumers of a service don't need to be refreshed or reloaded or re-resolved when a different or upgraded implementation of the service is to be deployed into the running OSGi container. Instead, the service tracker will be able to resolve the new implementation as long as the interface remained stable.

Examples of this can be seen, e.g., in com.sap.sse.replication.interfaces which contains, e.g., the ReplicationService interface, and the corresponding implementation bundle com.sap.sse.replication; or com.sap.sailing.server.interface and the corresponding implementation bundle com.sap.sailing.server.

SSE vs. Sailing

The code that we deemed independent of the domain of sailing we extracted into separate bundles, so they may be used by applications in similar, yet different domains, such as tennis or equestrian applications. We introduced a virtual layer that we called the "Sport Sponsorships Engine" or "SSE." Therefore, you will find bundles prefixed with com.sap.sse and others with com.sap.sailing.

OSGi Feature and Product Definitions

Our product, as defined by raceanalysis.product in the com.sap.sailing.feature.p2build project, refers to currently four so-called OSGi "features." In addition, it lists the bundles to be started automatically when the container starts. This auto-start specification lists so-called start levels for those bundles, defining the order in which they start up. Here, it's important to understand that this order must comply with the dependencies declared in those bundles. A bundle won't start successfully if any of its dependencies has a start level greater than its own. Important to know: the default start level is 4.

The features each are basically a collection of OSGi bundles. Each feature is defined in a project of its own. These projects are

  • com.sap.sse.feature
  • com.sap.sse.feature.runtime
  • com.sap.sailing.feature
  • com.sap.sailing.feature.runtime

The .runtime features reference bundles that are not part of our development workspace but instead are sources from the so-called OSGi target platform (see also Target Platform below). The non-.runtime features reference workspace bundles. The core element of each of these projects is their feature.xml file. The pom.xml defines the eclipse-feature packaging and hence tells the Maven Tycho build what to do with these.

Target Platform

The bundles we develop in our workspace are not all there is to the OSGi product. The product consists of many more bundles we obtain from open source repositories. The set of those other bundles that we don't develop in our own workspace are called the "target platform" of our OSGi product. The target platform is specified primarily in the com.sap.sailing.targetplatform project, by the definitions/race-analysis-p2-remote.target file. It lists various external repositories and the bundles to obtain from these. In some cases, the bundles to pull from a repository are specified one by one; in other cases, such as for our embedded Jetty web server, we specify an entire "feature group" which transitively defines which bundles to obtain for this.

At the bottom of the .target file we maintain an explicit list of the bundles that actually may be used. This way we can be very specific regarding the elements that constitute our product.

See also Adding a Bundle to the Target Platform to understand more about the details of maintaining and evolving this definition.