OSGI (Open Services Gateway Initiative) specification is about modularity and service platform for the Java applications. It helps in reorganising and splitting big applications to smaller stand alone units, called bundles. It has several implementations, as Equinox, Apache Felix, Knopflerfish etc.
Important element of OSGi is a JVM-level service registry that bundles can use to publish, discover and bind to services in a service-oriented architecture (SOA).

The reason for developing OSGi framework is that Java become too complex and big to cope with monolithic architecture. Although Java 9 introduced a new level of abstraction above packages, formally known as the Java Platform Module System (JPMS), OSGi is still in use. First version is released in 2000 by OSGi Alliance. Latest version(8) is released in December 2020.

OSGi architecture consist of bundles, services, life cycle management, modules and execution environment. Also there is security model, which is cross-cutting concern. Module/Bundle is a unit of encapsulation which interacts with other modules and follow specific rules. OSGi achieves this by limiting visibility of bundle. Bundle is aggregation of classes, jars, and configuration files, that have declared their external dependencies. Each bundle has itself ClassLoader and set off classes that are visible to it (Class Space). So it can see its private content and all explicitly imported types, but it can not see private types from other bundles. Difference between Java .jar and OSGi bundle is that second one has MANIFEST.MF file, in which metadata are defined. That are specific headers which contains information about version, name, declaration of its dependencies and other.

In OSGi, bundles can share Java packages (by exporting/importing it) or they can make it private, so each module can use different version of some package. It support versioning of bundles and packages. OSGi bundles can be dynamically installed, activated, de-activated, updated and uninstalled, which enables installing and updating minimal set of dependencies. That is very useful because changes happens often and it is possible to adapt to them with minimal costs.

OSGi Components and Services

You can create components with @Component:

public class Foo {…}

which will produce xml file that define internal component:
<implementation class=“org.testBundle.internal.Foo”/>

Service component runtime will create component called Foo and menages objects for as.
Components lifecycle is managed by component framework. There are active (can be started/stopped) and passive(it doesn’t need to be started/stoped) components. Component can be bind to OSGi service (it will exist only when service is available), and it can use services.
Components are less declarative than service. Service is an object that is registered in the OSGi Service Registry. If we want to create a service, then we must create interface (or use existing one) which the service will implement. Interface name will be used for finding service object. For example, we can create implementation of java.lang.Runnable:

@Component(immediate = true, service = Runnable.class)
public class RunnableImplementation implements Runnable {…}
Property ‘service’ gives information that this component is a service which is exposed via the Runnable interface. While components have a lifecycle, services have dependency management. Services are published by bundles (in the service registry), so they can be found and used by other bundles.

OSGi can is used in applications like IDEs, application servers, email systems, content management systems, application frameworks, residential gateways and onboard telematics systems. It is adopted in different industries, like IoT, Smart Home, Assisted Living, Healthcare, Automotive,Energy Management, Telecommunications, Enterprise and many other.