60 Connect Specification - OSGi Core 8 (original) (raw)
60.1 Introduction
The Service Layer provides a dynamic, concise and consistent programming model for Java developers, simplifying the development and deployment of services by de-coupling the service's specification (Java interface) from its implementations. This model allows developers to bind to services only using their interface specifications. The selection of a specific implementation, optimized for a specific need or from a specific vendor, can thus be deferred to runtime.
In order to use this powerful tool, developers are required to build on top of the Life Cycle and Module Layer of the OSGi Framework. Anything built on top of the Service Layer must follow the rules of the Life Cycle and Module Layers as well as the Service Layer. The Module Layer has rules for sharing Java packages between bundles or hiding packages from other bundles. The Life Cycle Layer provides an API to manage bundles in the Module Layer.
The Module and Life Cycle Layers assume the Framework is in control of the actual deployment unit (bundle) which is deployed as a Java archive (JAR) file. The Module Layer then provides the access for reading content and meta-data from the bundle and loading classes from the bundle. This can make it difficult to use classes or services that are already present in the running environment, for example, from the class path or anything else whose class space is managed outside of the framework. Without the Connect specification, content that lives outside the control of the Framework cannot easily benefit from the rich Service Layer because there is no way to represent the outside content as bundles inside the Framework.
This specification defines a Connect Framework Factory to create and launch an OSGi Framework instance that can connect bundles in the Framework with content managed outside of the Framework itself. For example, to provide things like resource loading, class loading, bundle entry content and bundle manifest headers. Among other things, this allows for bundles to exist and be installed into the Framework from the flat class path, the module path (Java Platform Module System), a jlink image, or a native image. Such bundles may have some limitations with respect to class loading and isolation because they may not follow the rules of the OSGi Module Layer.
60.1.1 Essentials
- OSGi Service Registry - It must be possible to use the OSGi Service Registry in environments that do not have the full OSGi Module Layer.
- OSGi Dependency Model - It must be possible to use the requirements and capabilities model OSGi provides in environments that do not have the full OSGi Module Layer.
- OSGi Extender Pattern - It must be possible to support the OSGi Extender Pattern in environments that do not have the full OSGi Module Layer. For example, Declarative Services.
- OSGi Technologies - It must be possible to support other OSGi technologies and specifications such as Configuration Admin, Metatype Service, Log Service etc. in environments that do not have the full OSGi Module Layer.
60.1.2 Entities
- Connect Content - Provides a Framework access to content from outside the Framework that can be used to represent an installed bundle in the Framework. A connect content provides things like a class loader for the bundle, access to entries in a bundle, and the bundle manifest headers.
- Connect Module - Provides the current connect content available for a bundle installed in the Framework. If the connect content for a bundle is constant then the connect module may return the same connect content for the lifetime of the Framework.
- Module Connector - Hooks into the initialization of the Framework and connects bundles installed in the Framework with connect module instances.
- Connect Framework Factory - A factory, similar to the FrameworkFactory, that is used to create Framework instances that use a module connector.
- Connect Bundle - A bundle installed in the Framework that is connected to a connect module and has its content provided by a connect content.
Figure 60.1 Connect Class Diagram
A launcher is in control of discovering and loading the connect framework factory implementation and the module connector implementation. The launcher is then able to use the connect framework factory to create a Framework instance that uses the module connector instance. When a connect bundle is installed it will be connected to a single connect module. Each bundle revision for the connect bundle is furthermore connected with a single connect content.
60.2 Module Connector
This section outlines how a launcher can launch a Framework implementation with an implementation of a ModuleConnector, regardless of the implementation type of the framework. This allows a launcher to embed an OSGi framework without having to provide code that differs between different implementations.
60.2.1 Launching a Framework
A Framework implementation that supports the Connect specification must provide a_factory_ class. A factory class is an indirection to create a framework implementation object. The implementation factory class must implement the ConnectFrameworkFactory interface. The launcher can use the following ways to get this class name:
- Service Provider Configuration model, see Java Service Provider Configuration Support for Connect,
- Get it from some configuration and use
Class.forName
, or - Hardcode the name.
The ConnectFrameworkFactory interface has a single method: newFramework(Map,ModuleConnector). The map provides the sole configuration properties for the framework object. The ModuleConnector implementation provides the OSGi Framework with the support to connect bundles with ConnectModule instances. The result of this method is a_framework object_, this object implements the Framework interface. See Frameworks for details on the Framework interface.
The following code shows how a Framework can be launched with a module connector.
Framework launch(ModuleConnector moduleConnector)
throws Exception {
Map<String, String> p = new HashMap();
p.put( "org.osgi.framework.storage",
System.getProperty("user.home")
+ File.separator+"osgi");
ServiceLoader<ConnectFrameworkFactory> sl =
ServiceLoader.load(ConnectFrameworkFactory.class);
ConnectFrameworkFactory factory = sl.iterator().next();
Framework osgiFramework = factory.newFramework(p, moduleConnector);
osgiFramework.init();
osgiFramework.start();
return osgiFramework;
}
60.2.2 Initializing the Module Connector
Before a module connector can be used by a Framework
instance, theModuleConnector must be initialized. Initialization is caused by the Framework
calling the initialize(File,Map) method on the module connector. The module connector initialize
method must only be called once for the lifetime of the Framework
instance. If the Framework
is stopped as defined by Stopping a Framework and initialized again as defined byInitializing the Framework the module connector initialize
method must not be called again.
If the framework supports persistence then the framework determines the path used for the storage area according to the launch property [FRAMEWORK_STORAGE](framework.api.html#org.osgi.framework.Constants.FRAMEWORK%5FSTORAGE "10.1.15.68 public static final String FRAMEWORK_STORAGE = "org.osgi.framework.storage""). Once the framework instance has determined the storage area the ModuleConnector
methodinitialize(File,Map) must be called. The file is the storage area used by the Framework and may be null
if persistence is not supported. This file may be used by the module connector for persistent storage. The map is the unmodifiable map of the Framework configuration properties that were used to create the new Framework instance with the method newFramework(Map,ModuleConnector)
60.2.3 Module Connector Life Cycle
A module connector may hook into the Framework life cycle by providing a BundleActivator instance. The BundleActivator
interface defines methods that the Framework invokes when the Framework is initialized and shutdown.
60.2.3.1 Start
When the Framework is initialized the system bundle enters the STARTING state. At this point a valid BundleContext exists for the Framework. Before invoking extension bundle activators as defined byStart Extension Activators the Framework must call the ModuleConnector
method newBundleActivator(). If the module connector provides a bundle activator then the start(BundleContext) method must be called before returning from the Framework
init() method and before any extension bundle activator start
methods are called. Any exception thrown by a module connector activator start
method must be wrapped in a BundleException
and broadcast as an ERROR.
The bundle activator allows for the module connector to hook into the life cycle of the Framework itself. For example, this allows the module connector to register services, add listeners and install other bundles before anything else installed in the Framework can, including extension bundles. With the supplied system bundle context a module connector is able to influence the behavior of the Framework by registering various Framework hooks like the ResolverHook. A resolver hook is useful for cases where the wiring of a connect bundle must not be allowed to wire to capabilities provided by other bundles installed in the Framework.
60.2.3.2 Shutdown
When the Framework is stopped it will reach start level zero and the Framework checks if there are any framework extensions activators to call the stop
method on as defined byStop Extension Activators. After calling the stop
method on the framework extension activators, the framework must call stop(BundleContext) on the bundle activator provided by the module connector. Any exception thrown by a module connector activator stop
method must be wrapped in a BundleException
and broadcast as an ERROR.
The Framework must guarantee that if the start
method has executed successfully for module connector activator, that same BundleActivator
object must be called on itsstop
method when the Framework is shutdown. After calling the stop
method, that particular BundleActivator
object must never be used again. A module connector activator that threw an exception during start
must not be called on shutdown.
60.2.4 Java Service Provider Configuration Support for Connect
Similar to how a framework factory is obtained in Java Service Provider Configuration Support the connect framework factory implementation name is obtained by reading the content of the configuration resource with the path META-INF/services/org.osgi.framework.connect.ConnectFrameworkFactory
For example, if the com.acme.osgi
framework has a connect factory class com.acme.osgi.connect.Factory
, then it should have the following resource:
META-INF/services/org.osgi.framework.connect.ConnectFrameworkFactory
And the contents should be:
# ACME Impl. for OSGi connect framework factory
com.acme.osgi.connect.Factory
60.3 Connect Bundles
A connect bundle is a Bundle installed in the framework that is connected to aConnectModule by a ModuleConnector.
60.3.1 Installing Connect Bundles
When a bundle is installed, as defined by Installing Bundles, a bundle location and an optional input stream to the content is provided with the BundleContext
method installBundle(String,InputStream). If a content input stream is provided to the call to installBundle
then the Framework must use that input stream to read the content of the bundle being installed. In this case the Framework assumes that the management agent is not installing a connect bundle and wants the content from the provided input stream to be installed into the Framework.
When no input stream is provided to the installBundle
method the Framework must call the ModuleConnector
method connect(String). The connect
method is given the bundle location specified in the call to installBundle(String,InputStream). The connect
method must do one of the following:
- Throw a
BundleException
if the installation of the bundle is to be prevented. In this case theBundleException
must be thrown from theinstallBundle
method. Any other exception thrown by theconnect
method must propagate to the caller of theinstallBundle
method. - Return an empty
Optional
indicating that the Framework must create the input stream from which to read the bundle by interpreting, in an implementation dependent manner, the specified location. - Return a present
Optional
indicating that the ConnectModule present must be connected to the bundle and used to access content of the bundle.
If a ConnectModule is found for the specified bundle location, then the Framework must call the ConnectModule
methodgetContent() to access the current ConnectContent for the bundle. The ConnectContent
must be used by the Framework to access content for the bundle's currentBundleRevision. Any exception thrown by thegetContent
method must be wrapped in a BundleException
and result in the BundleException
being thrown by the installBundle
method.
60.3.2 Updating Connect Bundles
When a bundle is updated, as defined by Updating Bundles, an optional input stream to the content is provided with the Bundle
methodupdate(InputStream). If the content input stream is provided to the call to update
then the Framework must use that input stream to read the content of the bundle being updated. In this case the Framework assumes the management agent is not updating the bundle to a connect bundle and wants the content from the provided input stream to be used to update the bundle. This allows a management agent to update a connect bundle to a non-connect bundle.
When no input stream is provided to the update
method the Framework must call the ModuleConnector
method connect(String). The connect
method is given the location of the bundle being updated. The connect
method must do one of the following:
- Throw a
BundleException
if the update of the bundle is to be prevented. In this case theBundleException
must be thrown from theupdate
method. Any other exception thrown by theconnect
method must propagate to the caller of theupdate
method. - Return an empty
Optional
indicating that the Framework must create the input stream from which to read the updated bundle by interpreting, in an implementation dependent manner, this bundle'sBundle-UpdateLocation
Manifest header, if present, or this bundle's original location. - Return a present
Optional
indicating that theConnectModule present must be connected to the bundle and used to access content of the updated bundle.
If a ConnectModule is found for the specified bundle location, then the Framework must call the ConnectModule
methodgetContent() to access the current ConnectContent for the updated bundle. The ConnectContent
must be used by the Framework to access content for the bundle's currentBundleRevision. Any exception thrown by thegetContent
method must be wrapped in a BundleException
and result in the BundleException
being thrown by the update
method.
When no input stream is provided to the call to update
it is possible to update a non-connect bundle to a connect bundle. Depending on the dynamic nature of the module connector, updating a connect bundle may result in the exact sameConnectContent being used for each updated revision for the bundle. This implies that the same class loader and content entries could be used for each updated revision.
60.3.3 Connect Content
The ConnectContent provides the Framework with all the information and resources necessary to represent aBundleRevision for the connect bundle installed the Framework.
60.3.3.1 Opening Connect Content
Before accessing the ConnectContent a Framework must first open the ConnectContent
with the methodopen(). A Framework may open and close the content many times while the content is being used by the Framework. For example, to limit the number of resources kept open concurrently by the Framework. The Framework must always ensure that the content is open before calling other methods on theConnectContent
. If any exception is thrown by the open
method as a result of installing or updating a connect bundle then the exception must be wrapped in a BundleException
and result in the BundleException
being thrown by the bundle install
or update
method.
60.3.3.2 Bundle Manifest Headers
As defined by Bundle Manifest Headers the bundle manifest headers can carry descriptive information about the bundle. A connect content may provide the bundle manifest headers to be used by the current revision of a bundle. When the framework needs to access a connect bundle's headers it must call the ConnectContent
methodgetHeaders(). If an empty Optional
is returned then the Framework must lookup the content entry named META-INF/MANIFEST.MF
and parse the bundle manifest itself as defined byBundle Manifest Headers.
If the Optional
returned has a map present then the map must be used to provide the raw, unlocalized, headers for the bundle. The headers must be used the same way the raw header values would have been used from a parsed META-INF/MANIFEST.MF
entry. That is the header keys and values that have semantic meaning must be used by the framework for the bundle and the key/value pairs must be used for the Dictionary
returned by the bundlegetHeaders() methods. The BundleRevision associated with the connect content must also have its capabilities and requirements defined by the contents of the Map.
60.3.3.3 Bundle Class Loader
Connect content is typically managed and loaded by an entity outside of the Framework itself. This may also influence the way classes are defined and loaded for content outside of the Framework's control. For bundle revisions that are connected to a ConnectContent the framework must call the connect content methodgetClassLoader() before creating a Framework managed class loader for the connected bundle.
If an empty Optional
is returned by the connect content getClassLoader
method then the Framework must create a class loader for the current bundle revision. The class loader created by the Framework must follow all the delegation rules defined by Class Loading Architecture for a bundle class loader and it must implement the BundleReference interface. All resources found and classes defined by this class loader must have their content read using the connect content entries. This is similar to how a bundle class loader works when the Framework is responsible for accessing and reading the bundle content JAR files directly. This framework implementation class loader must be returned by the the BundleWiring
method getClassLoader().
If the Optional
returned by the connect content getClassLoader
method has a class loader present then that ClassLoader
must be used for the class loader of theBundleWiring that is connected to the connect content. The ClassLoader
provided is not required to implement the BundleReference interface and is not required to follow the delegation rules defined by Class Loading Architecture. If the ClassLoader
does not implement BundleReference
then the Framework must wrap the ClassLoader
with another ClassLoader
that does implement BundleReference
. ThegetBundle() must return the bundle associated with the BundleWiring
. This wrapper loader simply delegates all loading to the ClassLoader
provided connect content. A Framework is free to always return a wrapper loader for the BundleWiring
method getClassLoader() even when the connect content loader does implement the BundleReference
interface.
A module connector is not required to provide a unique class loader for each ConnectContent
instance. That is the same class loader can be used as the class loader for multiple ConnectContent
instances and therefore get used by multiple bundles installed in the framework. If the connect bundle exports packages then theConnectContent
class loader will be delegated to by other class loaders managed by the framework. In other words, a bundle installed that is not connected with a ConnectModule may import packages exported by connect bundles and the OSGi Module Layer will do the correct delegation of class loads to the connect class loader as definedClass Loading Architecture for exported packages.
When a module connector implementation provides class loader implementations that are not the framework managed class loader there are limitations with respect to the behavior defined by the sectionsWeaving Hook Service Specification and Lazy Activation Policy. Weaving hooks as defined by Weaving Hook Service Specification will not be notified of the classes defined by the module connect class loaders. This implies that the WeavingHook and WovenClassListener implementations will not be called for and will not be able to weave these classes. The activation policy as defined by Lazy Activation Policy also cannot be supported because The Framework will not have the necessary hooks into the module connector class loader implementation to cause bundle activation on class load.
60.3.3.4 Connect Content Entries
A ConnectContent instance provides access to content entries for a revision of a connect bundle. The connect content entries are used by the Framework for the following:
- To provide content for the introspective methods on Bundle and BundleWiring. For example, thegetEntry(String),getEntryPaths(String) andfindEntries(String,String,int) method.
- To provide content for loading classes and resources from the framework managed class loader. This is used when the
ConnectContent
methodgetClassLoader() returns an emptyOptional
.
To introspect all entry path names provided by a ConnectContent
instance the methodgetEntries() is used by the Framework. The result of the getEntries
method is used by the Framework to provide results from the Bundle
getEntryPaths(String) method and the BundleWiring
findEntries(String,String,int) method.
To introspect a connect content entry the interfaceConnectContent.ConnectEntry is used. A ConnectEntry
can be looked up by its path name using theConnectContent
methodgetEntry(String). If the entry does not exist then an empty Optional
is returned. A presentConnectContent.ConnectEntry can be used by the Framework to provide URL
objects that use a Framework specific protocol for bundle entries. For example, for the URL
instances returned byBundle
method getEntry(String) and the BundleWiring
methodfindEntries(String,String,int).
The Framework must ensure that the path value used for calls to ConnectContent
method getEntry(String) do not start with slash ('/'). That is any paths used for calls to Bundle
methodgetEntry(String) or BundleWiring
methodfindEntries(String,String,int) must have the beginning slash ('/') removed before calling the ConnectContent
methodgetEntry(String).
60.3.3.5 Closing Connect Content
When a BundleRevision connected to a ConnectContent no longer isInUse() then the Framework must call the ConnectContent
methodclose() in order to close the connect content. The Framework is free to close
the ConnectContent
at any other time during the life time of the Framework, but the Framework must always ensure ConnectContent
is opened before calling other methods on the ConnectContent
.
60.3.4 Identify Connect Bundles
A bundle installed in the framework can be identified as a connect bundle by introspection of the [tags](framework.api.html#org.osgi.framework.namespace.IdentityNamespace.CAPABILITY%5FTAGS%5FATTRIBUTE "10.6.6.6 public static final String CAPABILITY_TAGS_ATTRIBUTE = "tags"") attribute on the [osgi.identity](framework.api.html#org.osgi.framework.namespace.IdentityNamespace.IDENTITY%5FNAMESPACE "10.6.6.11 public static final String IDENTITY_NAMESPACE = "osgi.identity"") capability for the current bundle revision. All connect bundle revisions must have a tags
attribute value that contains the string value [osgi.connect](framework.connect.html#org.osgi.framework.connect.ConnectContent.TAG%5FOSGI%5FCONNECT "60.7.2.1 public static final String TAG_OSGI_CONNECT = "osgi.connect""). For example, the following method determines if a BundleRevision
is for a connect bundle:
boolean isConnect(BundleRevision revision) {
return revision.getCapabilities("osgi.identity").stream().findFirst().map(c->{
List<String> tags = (List<String>) c.getAttributes().get("tags");
if (tags == null) {
return false;
}
return tags.contains("osgi.connect");
}).orElse(false);
}
For resources with the [osgi.identity ](framework.api.html#org.osgi.framework.namespace.IdentityNamespace.IDENTITY%5FNAMESPACE "10.6.6.11 public static final String IDENTITY_NAMESPACE = "osgi.identity"")capability and the attribute [type](framework.api.html#org.osgi.framework.namespace.IdentityNamespace.CAPABILITY%5FTYPE%5FATTRIBUTE "10.6.6.7 public static final String CAPABILITY_TYPE_ATTRIBUTE = "type"") value of [osgi.bundle](framework.api.html#org.osgi.framework.namespace.IdentityNamespace.TYPE%5FBUNDLE "10.6.6.13 public static final String TYPE_BUNDLE = "osgi.bundle""), the tags
attribute must be the same for the [osgi.wiring.bundle](framework.api.html#org.osgi.framework.namespace.BundleNamespace.BUNDLE%5FNAMESPACE "10.6.3.1 public static final String BUNDLE_NAMESPACE = "osgi.wiring.bundle"") and the [osgi.wiring.host](framework.api.html#org.osgi.framework.namespace.HostNamespace.HOST%5FNAMESPACE "10.6.5.8 public static final String HOST_NAMESPACE = "osgi.wiring.host"") capabilities. The Framework must include the osgi.connect
value in the tags
attribute for all three capabilities.
60.3.5 Launching from Persistent Storage
The Framework must make a record of which bundles are connected to a ConnectModule. When the Framework is stopped it must persist the state of all the installed bundles, including the ones connected to a ConnectModule
. When a new Framework instance is created using the persistent storage which recorded the connection to aConnectModule
, the Framework must verify that aModuleConnector is available that can connect the bundle location.
If there is no ConnectModule
present then the bundle installed must be discarded by the Framework as if it is not installed and a warning FrameworkEvent
should be published or a warning should be logged.
60.3.6 Extension Bundles
Extension bundles as defined by the section Extension Bundles can deliver parts, or fragments, of the Framework implementation. A Framework that supports extension bundles will modify its own class loader to append the content of the framework extension as defined by Class Path Treatment. If an extension bundle is also a connect bundle then the framework must not attempt to perform the class path modifications of the Framework itself with the extension bundle. It is assumed that the ModuleConnector
is managing that outside of the Framework.
60.4 Framework Utility Helpers
The FrameworkUtil class contains utility methods which may be useful to bundles. For module connector implementations the FrameworkUtil
method getBundle(Class) needs additional help from the module connector to figure out the Bundle
for a specified Class
.
60.4.1 Helper Implementations
A module connector implementation can hook into the FrameworkUtil
class by providing an implementation of the FrameworkUtilHelper interface. Implementations of the FrameworkUtilHelper
interface provide alternative implementations of the methods contained in the FrameworkUtil
class. The FrameworkUtil
method getBundle(Class) method will fall back to calling the available FrameworkUtilHelper
getBundle(Class) methods if the default implementation of the FrameworkUtil
getBundle(Class) method cannot figure out the Bundle
for the specified Class
. This allows a module connector implementation to return the Bundle
object for classes that a module connector class loader defines.
60.4.2 Java Service Provider Configuration Support for Helpers
Similar to how a connect framework factory is obtained in Java Service Provider Configuration Support for Connect the FrameworkUtil
class discovers helper names by reading the content of the configuration resources with the path META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper
For example, if the module connector implementation com.acme.osgi.connect.classpath
has a helper class com.acme.osgi.connect.classpath.AcmeFrameworkUtilHelpler
, then it should have the following resource:
META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper
And the contents should be:
# ACME Impl. for FrameworkUtilHelper
com.acme.osgi.connect.classpath.AcmeFrameworkUtilHelpler
When the FrameworkUtil class is initialized it will discover the available FrameworkUtilHelper
implementations as described in [13] Java Service Provider Configuration to obtain an immutable list ofFrameworkUtilHelper implementations. The list of helpers cannot change during the lifetime of theFrameworkUtil
class.
60.5 Example Class Path Connector
To illustrate how the Connect specification can be used the following is an example connector that discovers the JAR files contained on the Java class path and represents them as connect content. This example assumes the module connector implementation exists on the class path along with other bundle JARs that it can discover. This example does not show how the JAR files are discovered on the running Java class path.
public class ClassPathConnector implements ModuleConnector {
@Override
public Optional<ConnectModule> connect(String location)
throws BundleException {
return getJarFile(location).map((j) -> () -> new ClassPathContent(j));
}
private Optional<JarFile> getJarFile(String location) {
// find a jar file for the specified location from the running class path
return ...
}
static class ClassPathContent implements ConnectContent {
private final JarFile jar;
public ClassPathContent(JarFile jar) {
this.jar = jar;
}
@Override
public Optional<ClassLoader> getClassLoader() {
// assume this classes class loader can be used by all JARs found
// on the class path
return Optional.of(getClass().getClassLoader());
}
@Override
public Iterable<String> getEntries() throws IOException {
return jar.stream().map((e) -> e.getName()).
collect(Collectors.toList());
}
@Override
public Optional<ConnectEntry> getEntry(String path) {
return Optional.ofNullable(getConnectEntry(path));
}
ConnectEntry getConnectEntry(final String path) {
final ZipEntry entry = jar.getEntry(path);
return entry == null ? null : new ConnectEntry() {
@Override
public String getName() {
return path;
}
@Override
public long getContentLength() {
return entry.getSize();
}
@Override
public long getLastModified() {
return entry.getTime();
}
@Override
public InputStream getInputStream() throws IOException {
return jar.getInputStream(entry);
}
};
}
@Override
public Optional<Map<String, String>> getHeaders() {
return Optional.empty();
}
@Override
public void open() throws IOException {}
@Override
public void close() throws IOException {}
}
@Override
public void initialize(File storage, Map<String, String> configuration) {}
@Override
public Optional<BundleActivator> newBundleActivator() {
return Optional.empty();
}
}
60.6 Security
A ModuleConnector implementation should be considered part of the Framework implementation when it is used to launch a new Framework. Just like Framework implementations can assume to have AllPermission
granted, a module connector should have AllPermission
granted. A module connector will have access to the bundle locations. A bundle location can be considered sensitive data that should be protected. Module connector implementations should not expose the bundle location strings they obtain without a necessary permission check, seegetLocation().
60.7 org.osgi.framework.connect
Version 1.0
Framework Connect Package Version 1.0.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest.
Example import for consumers using the API in this package:
Import-Package: org.osgi.framework.connect; version="[1.0,2.0)"
60.7.1 Summary
- ConnectContent - A
ConnectContent
provides a Framework instance access to the content of a ConnectModule. - ConnectContent.ConnectEntry - Represents the entry of a
ConnectContent
. - ConnectFrameworkFactory - A factory for creating Framework instances.
- ConnectModule - A
ConnectModule
is used by a Framework instance to access the content of the connected bundle. - FrameworkUtilHelper - A helper for the FrameworkUtil class.
- ModuleConnector - A
ModuleConnector
provides connections to instances ofConnectModule that are used by a Framework instance to connect installed bundles locations with content provided by theModuleConnector
.
60.7.2 public interface ConnectContent
A ConnectContent
provides a Framework instance access to the content of a ConnectModule.
A framework may open and close the content for a ConnectModule multiple times while the ConnectContent
is in use by the framework. The framework must close theConnectContent
once the ConnectContent
is no longer used as the content of a current bundle revision or an in use bundle revision.
An entry in a ConnectContent
is identified by a path name that is a solidus ('/' /
) separated path. A ConnectContent
may treat directories as entries. A directory entry path name will end with a solidus. A directory entry may be located using a path name that omits the trailing solidus.
See Also BundleRevisions
ConcurrencyThread-safe
60.7.2.1 public static final String TAG_OSGI_CONNECT = "osgi.connect"
The osgi.identity
[tags](framework.api.html#org.osgi.framework.namespace.IdentityNamespace.CAPABILITY%5FTAGS%5FATTRIBUTE "10.6.6.6 public static final String CAPABILITY_TAGS_ATTRIBUTE = "tags"") attribute value used by the framework to tag connect bundle revisions.
60.7.2.2 public void close() throws IOException
□ Closes this ConnectContent
.
Throws IOException
– If an error occurred closing thisConnectContent
.
60.7.2.3 public Optional getClassLoader()
□ Returns a class loader for this ConnectContent
.
This method is called by the framework for resolved bundles only and will be called at most once while a bundle is resolved. If a bundle associated with a ConnectModule is refreshed and resolved again, the framework will ask theConnectContent
for the class loader again. This allows for aConnectContent
to reuse or create a new class loader each time the bundle revision is resolved.
ReturnsAn Optional
containing the class loader for thisConnectContent
, or an empty Optional
if framework should handle creating a class loader for the bundle revision associated with this ConnectContent
.
Throws IllegalStateException
– If this ConnectContent
has been closed.
60.7.2.4 public Iterable getEntries() throws IOException
□ Returns the entry names available in this ConnectContent
.
ReturnsAn Iterable
which can supply the available entry names.
Throws IOException
– If an error occurs reading thisConnectContent
.
IllegalStateException
– If this ConnectContent
has been closed.
60.7.2.5 public Optional<ConnectContent.ConnectEntry> getEntry(String path)
pathThe path name of the entry.
□ Returns the ConnectEntry for the specified path name in this content.
The empty value is returned if an entry with the specified path name does not exist. The path must not start with a "/" and is relative to the root of this content. A connect entry for a directory will have a path name that ends with a slash ('/').
ReturnsAn Optional
containing the ConnectEntry for the specified path, or an empty Optional
if no entry for specified path can be found.
Throws IllegalStateException
– If this ConnectContent
has been closed.
60.7.2.6 public Optional<Map<String, String>> getHeaders()
□ Returns the Manifest headers and values of this ConnectContent
.
ReturnsAn Optional
containing the Manifest headers and values for this ConnectContent
, or an empty Optional
if the framework should handle parsing the Manifest of the content itself.
Throws IllegalStateException
– If this ConnectContent
has been closed.
60.7.2.7 public void open() throws IOException
□ Opens this ConnectContent
.
The framework will open the content when it needs to access the content for a bundle revision associated with this ConnectContent
. The framework may defer calling this method until requests to access the bundle revision content are made.
Throws IOException
– If an error occurred opening thisConnectContent
.
60.7.3 public static interface ConnectContent.ConnectEntry
Represents the entry of a ConnectContent
.
60.7.3.1 public byte[] getBytes() throws IOException
□ Returns the content of this entry.
ReturnsThe content of this entry.
Throws IOException
– If an error occurs reading the content.
60.7.3.2 public long getContentLength()
□ Returns the content length of this entry.
ReturnsThe content length of the entry, or -1
if the content length is not known.
60.7.3.3 public InputStream getInputStream() throws IOException
□ Returns an input stream for the content of this entry.
ReturnsAn input stream for the content of this entry.
Throws IOException
– If an error occurs reading the content.
60.7.3.4 public long getLastModified()
□ Returns the last modification time of this entry.
ReturnsThe last modification time of this entry measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970).
60.7.3.5 public String getName()
□ Returns the path name of this entry.
ReturnsThe path name of this entry.
60.7.4 public interface ConnectFrameworkFactory
A factory for creating Framework instances.
If a framework supports ModuleConnector, then the implementation jar must contain the following resource:
/META-INF/services/org.osgi.framework.connect.ConnectFrameworkFactory
This UTF-8 encoded resource must contain the name of the framework implementation's ConnectFrameworkFactory implementation class. Space and tab characters, including blank lines, in the resource must be ignored. The number sign ('#'
\u0023) and all characters following it on each line are a comment and must be ignored.
Launchers can find the name of the ConnectFrameworkFactory implementation class in the resource and then load and construct a ConnectFrameworkFactory object for the framework implementation. The ConnectFrameworkFactory implementation class must have a public, no-argument constructor. Java™ SE 6 introduced the ServiceLoader
class which can create a ConnectFrameworkFactory instance from the resource.
ConcurrencyThread-safe
Provider TypeConsumers of this API must not implement this type
60.7.4.1 public Framework newFramework(Map<String, String> configuration, ModuleConnector moduleConnector)
configurationThe framework properties to configure the new framework instance. If framework properties are not provided by the configuration argument, the created framework instance must use some reasonable default configuration appropriate for the current VM. For example, the system packages for the current execution environment should be properly exported. The specified configuration argument may be null
. The created framework instance must copy any information needed from the specified configuration argument since the configuration argument can be changed after the framework instance has been created.
moduleConnectorThe module connector that the new framework instance will use. The specified module connector argument may be null
.
□ Create a new Framework instance using the specifiedmodule connector.
ReturnsA new, configured Framework instance. The framework instance must be in the Bundle.INSTALLED state.
Throws SecurityException
– If the caller does not haveAllPermission
, and the Java Runtime Environment supports permissions.
See Also ModuleConnector
60.7.5 public interface ConnectModule
A ConnectModule
is used by a Framework instance to access the content of the connected bundle.
ConcurrencyThread-safe
60.7.5.1 public ConnectContent getContent() throws IOException
□ Returns the current content of this connect module.
The framework must call this method when it needs to access the content for the current bundle revision of thisConnectModule
. The framework may defer opening the returnedConnectContent until requests to access the bundle revision content are made.
ReturnsThe current ConnectContent of this ConnectModule
.
Throws IOException
– If an error occurred getting the content.
See Also ModuleConnector.connect(String)
60.7.6 public interface FrameworkUtilHelper
A helper for the FrameworkUtil class.
This helper provides alternative implementations for methods onFrameworkUtil.
60.7.6.1 public Optional getBundle(Class<?> classFromBundle)
classFromBundleA class associated with a bundle.
□ Returns the Bundle associated with the specified class.
This helper method is called by FrameworkUtil.getBundle(Class) if the standard implementation of FrameworkUtil is unable to find the bundle.
ReturnsAn Optional
containing the Bundle for the specified class, or an empty Optional
if the specified class is not from a bundle.
60.7.7 public interface ModuleConnector
A ModuleConnector
provides connections to instances ofConnectModule that are used by a Framework instance to connect installed bundles locations with content provided by theModuleConnector
.
This allows a ModuleConnector
to provide content and classes for a connected bundle installed in the Framework
. AModuleConnector
is provided whencreating a framework instance. Because a ModuleConnector
instance can participate in the initialization of the Framework
and the life cycle of a Framework
instance the ModuleConnector
instance should only be used with a single Framework
instance at a time.
ConcurrencyThread-safe
60.7.7.1 public Optional connect(String location) throws BundleException
locationThe bundle location used to install a bundle.
□ Connects a bundle location with a ConnectModule.
When the result is empty, then the framework must handle reading the content of the bundle itself. Otherwise, the returnedConnectModule must be used by the framework to access the content of the bundle.
ReturnsAn Optional
containing the ConnectModule for the specified bundle location, or an empty Optional
if the framework must handle reading the content of the bundle itself.
Throws BundleException
– If the location cannot be handled.
60.7.7.2 public void initialize(File storage, Map<String, String> configuration)
storageThe persistent storage area used by the Framework or null
if the platform does not have file system support.
configurationAn unmodifiable map of framework configuration properties that were used to configure the new framework instance.
□ Initializes this ModuleConnector
with the[framework persistent storage](framework.api.html#org.osgi.framework.Constants.FRAMEWORK%5FSTORAGE "10.1.15.68 public static final String FRAMEWORK_STORAGE = "org.osgi.framework.storage"") file and framework properties configured for a Framework instance.
This method is called once by a Framework instance and is called before any other methods on this module connector are called.
60.7.7.3 public Optional newBundleActivator()
□ Creates a new activator for this ModuleConnector
.
This method is called by the framework during frameworkinitialization. Returning an activator allows this ModuleConnector
to participate in the framework life cycle. If an activator is returned:
- The framework will call the activator'sstart method prior to activating any extension bundles.
- The framework will call the activator'sstop method after deactivating any extension bundles.
ReturnsAn Optional
containing a new BundleActivator for this ModuleConnector
, or an empty Optional
if noBundleActivator is necessary.