Module org.apache.felix.atomos
Package org.apache.felix.atomos

## Interface Atomos

    @Header(name="Main-Class",
            value="org.apache.felix.atomos.Atomos")
    @ProviderType
    public interface Atomos

Atomos can be used for creating new OSGi `Framework` instances with bundles loaded from the module or class path. The Framework instance will have a set of contents discovered and installed as connected bundles automatically when the Framework is `initialized`.

When loading Atomos from the module path the contents will be loaded from the Java modules included on the module path and will use the class loader provided by the Java module system. This implies that the normal protection provided by the OSGi module layer will not be available to the classes loaded out of the module path bundles. Classes in one bundle will be able to load classes from other bundles even when the package is not exported. But the Java module system will provide protection against modules trying to execute code from packages that are not exported. This means you may find cases where a bundle can load a class from another bundle but then get runtime exceptions when trying to execute methods on the class. Other limitations are also imposed because a single class loader is used to load all contents from connected bundles. For example, multiple versions of a package cannot be supported because the class loader can only define a single package of a given name.

When loading from the module path Atomos contents are discovered using the module layer which loads the Atomos framework. This is typically the boot layer. Atomos contents are discovered by searching the current module layer for the available modules as well as the modules available in the parent layers until the `empty` layer is reached.

When loading Atomos from the class path (i.e as an unnamed module) the contents will be loaded from JARs included on the class path along side the Atomos JARs and will use the application class loader provided by the JVM. This also implies that the normal protection provided by the OSGi module layer will not be available to the classes loaded out of the class path bundles. But unlike when loading bundles from the module path, the Java module system will not provide any protection against executing code from other bundles from private packages. This mode also suffers from the typical issues that arise if you have multiple JARs on the class path that provide the same package. When in module path mode the JVM will fail to launch and inform you that it detected duplicate packages from the modules on the module path. In class path mode the JVM does no such check, this leaves you open to have unexpected shadowing if you have multiple versions of the same package on the class path.

When loading from the class path Atomos contents are discovered by searching the class path for bundle manifests (META-INF/MANIFEST.MF) resources and discovering any that contain OSGI meta-data (e.g. Bundle-SymbolicName). The boot layer is also searched and loads all boot modules as bundles similar to when loading from the module path.

The Framework can be created using the `ConnectFrameworkFactory` APIs. The following will launch using the standard `ConnectFrameworkFactory`:

     Map<String, String> config = getConfiguration();
     config.put(Constants.FRAMEWORK_SYSTEMPACKAGES, "");
     ModuleConnector atomosConnector = Atomos.newAtomos().newModuleConnector();
     Framework framework = ServiceLoader.load(ConnectFrameworkFactory.class).iterator().next().newFramework(config, atomosConnector);
     framework.start();

Note that the `Constants.FRAMEWORK_SYSTEMPACKAGES` must be set to an empty value to prevent discovery of packages from the `boot` layer. Without doing this the OSGi R7 framework will discover all modules from the boot layer and assume they all should be exported by the system bundle. That is normally desired so the packages available from the boot layer (typically the modules provided by the Java platform itself) can be available for import from bundles installed into the framework. But with Atomos you may load all your bundles within the boot layer itself. In that case you obviously do not want all the packages from the bundles in the boot layer also be exported by the system bundle. Setting `Constants.FRAMEWORK_SYSTEMPACKAGES` to the empty value will prevent this from happening. Atomos still needs to make the packages exported by the Java platform modules available for import. In order to do this Atomos will create an `Atomos content` for each module contained in the `boot` layer.

The following code uses the Atomos to first create a child layer which is then used to load more modules in addition to the ones included on the module path.

     Atomos atomos = Atomos.newAtomos();

     // Add a new layer using a Path that contains a set of modules to load
     Path modulesDir = getModulesDir();
     atomos.getBootLayer().addLayer("child", LoaderType.OSGI, modulesDir);

     Framework framework = atomos.newFramework(frameworkConfig);
     framework.start();

When using the `newFramework(Map)` to create a new Framework the `Constants.FRAMEWORK_SYSTEMPACKAGES` is set to the empty value automatically. By default all Atomos contents will be installed and started in the OSGi framework when the framework is started. If `atomos.content.install` is set to `false` in the framework configuration then the boot contents will not be installed by default. In that case the `AtomosContent.install(String)` method can be used to selectively install Atomos contents. If `atomos.content.start` is set to `false` in the framework configuration then the Atomos bundles will not be started by default. The system.bundle of the initialized framework will also have an Atomos service registered with its bundle context.

### Nested Class Summary

Nested Classes
`static interface` `Atomos.HeaderProvider` A function that maps each `AtomosContent` `location` and its existing headers to a new optional map of headers to be used for the `headers` of the `ConnectContent`.

### Field Summary

Fields
`static String` `ATOMOS_CONTENT_INSTALL` Framework launching property specifying if the Atomos contents will not be automatically installed as bundles.
`static String` `ATOMOS_CONTENT_START` Framework launching property specifying if the Atomos contents installed as connected bundles will not be marked for start.

### Method Summary

All Methods Static Methods Instance Methods Abstract Methods
`AtomosLayer` `addLayer​(List<AtomosLayer> parents, String name, AtomosLayer.LoaderType loaderType, Path... modulePaths)` Adds a layer as a child of the specified parents and loads modules from the specified module paths
`AtomosLayer` `getBootLayer()` The initial Atomos boot layer.
`static Map<String,​String>` `getConfiguration​(String... args)` Converts a string array into a `Map<String,String>`
`AtomosContent` `getConnectedContent​(String bundleLocation)` Returns the Atomos content that is connected with the specified bundle location.
`ModuleConnector` `getModuleConnector()` Returns the module connector for this runtime instance.
`static void` `main​(String... args)` A main method that can be used by executable jars to initialize and start Atomos with an available OSGi `Framework` implementation.
`static Atomos` `newAtomos()` Creates a new Atomos that can be used to create a new OSGi framework instance.
`static Atomos` `newAtomos​(Map<String,​String> configuration)` Creates a new Atomos that can be used to create a new OSGi framework instance.
`static Atomos` `newAtomos​(Map<String,​String> configuration, Atomos.HeaderProvider headerProvider)` Creates a new Atomos that can be used to create a new OSGi framework instance.
`static Atomos` `newAtomos​(Atomos.HeaderProvider headerProvider)` Creates a new Atomos that can be used to create a new OSGi framework instance.
`Framework` `newFramework​(Map<String,​String> frameworkConfig)` Creates a new `Framework` instance that uses this Atomos instance.

### Field Detail

#### ATOMOS_CONTENT_INSTALL

    static final String ATOMOS_CONTENT_INSTALL

Framework launching property specifying if the Atomos contents will not be automatically installed as bundles. Default is true, which will install all discovered Atomos content as bundles.

See Also:
  Constant Field Values

#### ATOMOS_CONTENT_START

    static final String ATOMOS_CONTENT_START

Framework launching property specifying if the Atomos contents installed as connected bundles will not be marked for start. Default is true, which will start all discovered Atomos content that are installed as bundles.

See Also:
  Constant Field Values

### Method Detail

#### getConnectedContent

    AtomosContent getConnectedContent​(String bundleLocation)

Returns the Atomos content that is connected with the specified bundle location. The Atomos content returned is used by the connected bundle installed in the framework with the specified bundle location.

Parameters:
  `bundleLocation` - the bundle location.
Returns:
  the Atomos content with the specified location or `null` if no Atomos content is installed at the location.

#### getBootLayer

    AtomosLayer getBootLayer()

The initial Atomos boot layer. Depending on the mode Atomos is running this may be the backed by `ModuleLayer.boot()` or by the class path.

Returns:
  the boot Atomos layer

#### getModuleConnector

    ModuleConnector getModuleConnector()

Returns the module connector for this runtime instance. The module connector can be used to create a new framework by using a `ConnectFrameworkFactory` directly by calling the `ConnectFrameworkFactory.newFramework(Map, ModuleConnector)` method.

Returns:
  the module connector for this runtime

#### addLayer

    AtomosLayer addLayer​(List<AtomosLayer> parents,
                         String name,
                         AtomosLayer.LoaderType loaderType,
                         Path... modulePaths)

Adds a layer as a child of the specified parents and loads modules from the specified module paths

Parameters:
  `parents` - the parent layers. Must include at least one parent layer
  `name` - the name of the new layer
  `loaderType` - the type of class loader to use
  `modulePaths` - the paths to load modules for the new layer
Returns:
  a newly created layer
Throws:
  `UnsupportedOperationException` - if the `boot` layer `AtomosLayer.isAddLayerSupported()` returns false.

#### newFramework

    Framework newFramework​(Map<String,​String> frameworkConfig)

Creates a new `Framework` instance that uses this Atomos instance. The `ServiceLoader` is used to load an implementation of a `ConnectFrameworkFactory` which is used to create a new `Framework` instance with the specified Atomos runtime. The supplied framework configuration is used to create the new `Framework` instance. Additional configuration options maybe configured automatically in order to correctly configure the system packages for the `Framework` instance.

Parameters:
  `frameworkConfig` - The framework configuration options, or `null` if the defaults should be used
Returns:
  The new uninitialized Framework instance which uses this Atomos instance

#### main

    static void main​(String... args)
              throws BundleException

A main method that can be used by executable jars to initialize and start Atomos with an available OSGi `Framework` implementation. Each string in the arguments array may contain a key=value pair that will be used for the framework configuration.

Parameters:
  `args` - the args will be converted into a `Map<String, String>` to use as configuration parameters for the OSGi Framework.
Throws:
  `BundleException` - when an error occurs
See Also:
  `newAtomos(Map)`, `newFramework(Map)`

#### getConfiguration

    static Map<String,​String> getConfiguration​(String... args)

Converts a string array into a `Map<String,String>`

Parameters:
  `args` - the arguments where each element has key=string value, the key cannot contain an '=' (equals) character.
Returns:
  a map of the configuration specified by the args

#### newAtomos

    static Atomos newAtomos()

Creates a new Atomos that can be used to create a new OSGi framework instance. Same as calling `newAtomos(Map)` with an empty configuration.

Returns:
  a new Atomos.

#### newAtomos

    static Atomos newAtomos​(Atomos.HeaderProvider headerProvider)

Creates a new Atomos that can be used to create a new OSGi framework instance. Same as calling `newAtomos(Map,HeaderProvider)` with an empty configuration.

Parameters:
  `headerProvider` - the header provider function
Returns:
  a new Atomos.

#### newAtomos

    static Atomos newAtomos​(Map<String,​String> configuration)

Creates a new Atomos that can be used to create a new OSGi framework instance. Same as calling `newAtomos(Map,HeaderProvider)` with a no-op `headerProvider` function.

Parameters:
  `configuration` - the properties to configure the new Atomos
Returns:
  a new Atomos.

#### newAtomos

    static Atomos newAtomos​(Map<String,​String> configuration,
                            Atomos.HeaderProvider headerProvider)

Creates a new Atomos that can be used to create a new OSGi framework instance. If Atomos is running as a Java Module then this Atomos can be used to create additional layers by using the `AtomosLayer.addLayer(String, AtomosLayer.LoaderType, Path...)` method. If the additional layers are added before `ConnectFrameworkFactory.newFramework(Map, ModuleConnector)` creating} and `initializing` the framework then the Atomos contents found in the added layers will be automatically installed and started according to the `ATOMOS_CONTENT_INSTALL` and `ATOMOS_CONTENT_START` options.

Note that this `Atomos` must be used for creating a new framework instance with the method `ConnectFrameworkFactory.newFramework(Map, ModuleConnector)` to use the layers added to this `Atomos` or the `newFramework(Map)` method can be called on this `Atomos`.

The given headerProvider function maps each Atomos content `location` and existing headers of the content to a new optional map of headers. The resulting map will be used as the headers for the `ConnectContent.getHeaders()`. If the function returns an empty optional then the existing headers will be used.

Parameters:
  `configuration` - the properties to configure the new Atomos
  `headerProvider` - a function that will be called with the location and the existing headers for each Atomos content.
Returns:
  a new Atomos.