-
@Header(name="Main-Class", value="org.apache.felix.atomos.Atomos") @ProviderType public interface Atomos
Atomos can be used for creating new OSGiFramework
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 isinitialized
.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 standardConnectFrameworkFactory
: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();Constants.FRAMEWORK_SYSTEMPACKAGES
must be set to an empty value to prevent discovery of packages from theboot
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. SettingConstants.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 anAtomos content
for each module contained in theboot
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 thenewFramework(Map)
to create a new Framework theConstants.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. Ifatomos.content.install
is set tofalse
in the framework configuration then the boot contents will not be installed by default. In that case theAtomosContent.install(String)
method can be used to selectively install Atomos contents. Ifatomos.content.start
is set tofalse
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 Modifier and Type Interface Description static interface
Atomos.HeaderProvider
A function that maps eachAtomosContent
location
and its existing headers to a new optional map of headers to be used for theheaders
of theConnectContent
.
-
Field Summary
Fields Modifier and Type Field Description 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 Modifier and Type Method Description 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 pathsAtomosLayer
getBootLayer()
The initial Atomos boot layer.static Map<String,String>
getConfiguration(String... args)
Converts a string array into aMap<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 OSGiFramework
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 newFramework
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 byModuleLayer.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 aConnectFrameworkFactory
directly by calling theConnectFrameworkFactory.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 layername
- the name of the new layerloaderType
- the type of class loader to usemodulePaths
- the paths to load modules for the new layer- Returns:
- a newly created layer
- Throws:
UnsupportedOperationException
- if theboot
layerAtomosLayer.isAddLayerSupported()
returns false.
-
newFramework
Framework newFramework(Map<String,String> frameworkConfig)
Creates a newFramework
instance that uses this Atomos instance. TheServiceLoader
is used to load an implementation of aConnectFrameworkFactory
which is used to create a newFramework
instance with the specified Atomos runtime. The supplied framework configuration is used to create the newFramework
instance. Additional configuration options maybe configured automatically in order to correctly configure the system packages for theFramework
instance.- Parameters:
frameworkConfig
- The framework configuration options, ornull
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 OSGiFramework
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 aMap<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 aMap<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 callingnewAtomos(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 callingnewAtomos(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 callingnewAtomos(Map,HeaderProvider)
with a no-opheaderProvider
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 theAtomosLayer.addLayer(String, AtomosLayer.LoaderType, Path...)
method. If the additional layers are added beforeConnectFrameworkFactory.newFramework(Map, ModuleConnector)
creating} andinitializing
the framework then the Atomos contents found in the added layers will be automatically installed and started according to theATOMOS_CONTENT_INSTALL
andATOMOS_CONTENT_START
options.Note that this
Atomos
must be used for creating a new framework instance with the methodConnectFrameworkFactory.newFramework(Map, ModuleConnector)
to use the layers added to thisAtomos
or thenewFramework(Map)
method can be called on thisAtomos
.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 theConnectContent.getHeaders()
. If the function returns an empty optional then the existing headers will be used.- Parameters:
configuration
- the properties to configure the new AtomosheaderProvider
- a function that will be called with the location and the existing headers for each Atomos content.- Returns:
- a new Atomos.
-
-