# Knopflerfish OSGi framework

This is the Knopflerfish framework. An OSGi Release 5 compliant framework. It supports all optional and deprecated framework services, Package Admin, Start Level, Conditional Permission Admin, Permission Admin, URL Handlers, Bundle Hook, Resolver Hook, Service Hook and Weaving Hook.

## Contents

1. Knopflerfish framework.jar startup
2. Initial start vs restart
3. Starting the framework
4. Starting the compact framework
5. Default selection of .xargs
6. Using a HTTP proxy
7. Framework and System Properties
8. OSGi Specified Framework Properties
9. Knopflerfish Specified System Properties
10. Knopflerfish Specified Framework Properties

## Knopflerfish framework.jar startup

This is a startup guide for the KF OSGi framework. Note that command-line startup of the framework is not specified by OSGi, and system integrators often need to create a wrapper script for FW startup.

The KF Main startup class is primarily intended to be used in scenarios where current working directory is same as the one containing framework.jar, the framework storage directory and configuration files. In these cases

    java -jar framework.jar

...is often enough.

To use features that requires JVM restart, e.g. extension bundles, you can use our example shell start script "kf2". Open a terminal and type

    ./kf2

Note: the script requires a "sh" shell.

Other uses are possible, but require options and possibly some tweaking of the default startup files.

## Initial start vs restart

Two cases of framework startup should be noted:

1. Initial, bootstrap, startup
   An initial startup must contain enough options to install bundles allowing further management, using -install options. If no bundles are installed, an empty framework will be started but nothing can be done with it..
2. Restart of previously initialized framework
   Any OSGi framework can remember its state from previous startup.
   In this case, startup options should only contains system properties and a -launch option for restarting the bundles, but not any -install options.

NB! Framework properties (-Fx=y) supplied at initial startup are saved as part of the framework state, and need not to be supplied again at framework restart. System properties (-Da=b) are not included in the framework state. Since the two different startup cases probably will use separate startup files, care must be taken so system properties are set correctly in both files, when so required.

It is up to a system integrator to decide when to use initial startup or restart. The Main KF class can help somewhat in doing this (see below) but might not be enough. In those cases, wrapper scripts, or modifications to Main.java are recommended.

## Starting the framework

The framework can be started using the startup wrapper class

    org.knopflerfish.framework.Main

This class is also set a Main-Class in framework.jar's manifest, meaning framework.jar can be started using

     java -jar framework.jar [options] OR ./kf2 [options]

The Main class supports a number of options, which can be displayed using:

    java -jar framework.jar -help OR ./kf2 -help

Options can also be specified using the -xargs option, which specifies a .xargs text file containing lines of new options. Typically all options are specified in .xargs files. Combining .xargs files and command line options is possible. .xargs files can also use recursive .xargs files.

When the framework is started, it uses a file system directory for storing the state of all installed bundles, "fwdir". The default directory used for this is:

    fwdir

in the current directory. The "fwdir" directory can also be set specifically using the org.osgi.framework.storage property. Note that moving "fwdir" also changes the location for searching for default .xargs files.

If no options are specified (any "-Fx=y", "-Da=b" or "-init" does not count as options in this case) an implicit

    -xargs "default"

is added to the options. "default" means that the default .xargs (see below) is selected.

## Starting the compact framework

There is a compact version of the framework available for system that has limited amount of resources (memory and storage). This version doesn't contain any support for security and certificates. The internal classes has also been name mangled to save resources.

The compact framework is started and controlled in the same way as the full version. The only difference is that the jar file is called `framework_compact.jar`.

## Default selection of .xargs

If _no_ args are supplied (arguments of the form "-Fx=y", "-Da=b" or "-init" does not count in this case), or a name of "default" is given as -xargs argument, a default .xargs file will be searched for, by the following algorithm:

1. If there exists a previous "fwdir" AND previous options does not contain "-init", use a file in "fwdir" named:

       fwprops.xargs

2. If no fwdir exist, OR options contain an "-init", search for a file named:
   1. init_[osname].xargs
   2. init.xargs
   3. remote-init.xargs
   The search is performed in the following directories:
   1. fwdir
   2. The parent directory of fwdir (if any)
   3. The current working directory
   First match wins.
   The [osname]-part of the file name is the unified OS name as specified in Alias.java (see below). Case is important if the file system is case sensitive.
   OS aliases:
   - OS2
   - QNX
   - Windows95
   - Windows98
   - WindowsNT
   - WindowsCE
   - Windows2000
   - WindowsXP

The file fwdir/fwprops.xargs contains saved properties that is used when restarting a framework instance. It is written by the Knopflerfish framework on every startup (unless disabled by setting the property "org.knopflerfish.framework.write.restart.xargs" to false).

## Using a HTTP proxy

The standard JVM system properties

- http.proxyHost
- http.proxyPort
- http.nonProxyHosts

should be used to set proxy information. This will be global to all HTTP request from all bundles and the framework.

Additionally, the KF-specific system property

- http.proxyAuth

can be set to a value on the form user:password

If set to non-empty, this will add the Proxy-Authorization header to bundle install http/https requests made from the framework, However, bundles using the URL class internally must explicitly set this header themselves.

## Framework and System Properties

Both Framework and Java System properties are used to control the framework.

Framework properties are the standard properties listed in the OSGi specification (section 4.5.3 in r4.core) and proprietary properties for the Knopflerfish framework. Framework properties are also used for configuration of Knopflerfish bundles.

Framework properties are specified on the command line or in .xarg files using "-F". If you have more than one framework instance, each instance has its own set of Framework properties.

A framework property is accessed by using

    org.osgi.framework.BundleContext.getProperty(String)

.

Java System properties are specified on the command line or in .xargs files using "-D". System properties are accessed using

    java.lang.System.getProperty(String)

but

    BundleContext.getProperty

can also be used as it will look for a System property if there is no matching Framework property.

Because of the different handling of Framework and System properties when the framework is restarted, it is recommended to use only Framework properties in .xargs files. If you do, and use the default init.xargs/props.xargs files, initial starts and restarts become conveniently short on the command line:

    java -jar framework.jar -init

(initial start)

    java -jar framework.jar

(restart)

Unfortunately, it is not always possible to avoid using Java System properties. For example, a bundle may include a class library that uses System properties for configuration. Also, properties that are read during start-up, before the framework has been initialized, need to be System properties, see KF System Properties.

## OSGi Specified Framework Properties

OSGi Framework properties should be specified using "-F".

Name | Description | Value type | Default value
--- | --- | --- | ---
org.osgi.framework.bootdelegation | Set the boot delegation mask. A list of packages delegated from the framework to the parent classloader. The package specified can contain a wildcard at the end, which matches any sub-packages. | String , ... |
org.osgi.framework.bsnversion | Allow installation of multiple bundles with the same bundle symbolic name or restrict this. The property can have the following values:
single | A combination of equal bundle symbolic name and equal version is unique in the framework. Installing a second bundle with the same bundle symbolic name and version is an error.
multiple | The combination of bundle symbolic name and version is not unique in the framework.
managed | Using a Bundle Collision Hook to filter any non-colliding bundles.
| String | managed
org.osgi.framework.bundle.parent | This property is used to specify what class loader is used for boot delegation. That is, java.* and the packages specified on the org.osgi.framework.bootdelegation. This property can have the following values: boot, app, ext or framework. | String | boot
org.osgi.framework.command.execpermission | Specifies an optional OS specific command to set file permissions on a bundle's native code. This is required on some operating systems to use native libraries. For example, on a UNIX style OS you could have the following value: org.osgi.framework.command.execpermission="chmod +rx ${abspath}" The ${abspath} macro will be substituted for the actual file path. | String | -
org.osgi.framework.executionenvironment | The current execution environment. There are no restriction on the execution environment if this property isn't set. | String |
org.osgi.framework.language | The language used by the framework for the selection of native code. | String | Set based on default locale
org.osgi.framework.library.extensions | A comma separated list of additional library file extensions that must be used when searching for native code. If not set, then only the library name returned by System.mapLibraryName(String) will be used. This list of extensions is needed for certain operating systems which allow more than one extension for native libraries. For example, the AIX operating system allows library extensions of .a and .so, but System.mapLibraryName(String) will only return names with the .a extension. | String , ... | -
org.osgi.framework.os.name | The name of the operating system as used in the native code clause. | String | Set based on system property os.name
org.osgi.framework.os.version | The version of the operating system as used in the native code clause. | String | Set based on system property os.version
org.osgi.framework.os.processor | The name of the processor as used in the native code clause. |  | Set based on system property os.arch
org.osgi.framework.security | Specifies the type of security manager the framework must use. If not specified then the framework will not set the VM security manager. The following type is architected: `osgi` Enables a security manager that supports all security aspects of the OSGi Release 4 specifications (including postponed conditions). If specified, and there is a security manager that doesn't match already installed, then a SecurityException is thrown when the Framework is initialized. | String | -
org.osgi.framework.startlevel.beginning | Specifies the beginning start level of the framework. | Integer | 1
org.osgi.framework.storage | Where we store persistent data. On systems not supporting a current working directory, as Pocket PC, this path should be set to an explicit full path. Note: Knopflerfish 1.x and 2.x used the name "org.osgi.framework.dir" for this property. | String | ${currentWorkingDirectory}/fwdir
org.osgi.framework.storage.clean | Specifies if and when the storage area for the framework should be cleaned. If no value is specified, the framework storage area will not be cleaned. The possible values is: `onFirstInit` - The framework storage area will be cleaned before the Framework bundle is initialized for the first time. Subsequent inits, starts or updates of the Framework bundle will not result in cleaning the framework storage area. | String | -
org.osgi.framework.system.packages | Complete list of packages exported by the system bundle. If not set the framework will export all OSGi packages and all standard Java packages according to the version of the running JRE. See also "org.knopflerfish.framework.system.packages.base" and "org.osgi.framework.system.packages.extra" | String , ... | Default is based on other properties
org.osgi.framework.system.packages.extra | Packages to add to the default list of packages exported by the system bundle. | String , ... | -
org.osgi.framework.trust.repositories | This property is used to configure trust repositories for the framework. The value is path of files.The file paths are separated by the pathSeparator defined in the File class. Each file path should point to a JKS key store. The framework will use the key stores as trust repositories to authenticate certificates of trusted signers. The key stores must only be used as read-only trust repositories to access public keys. The keystore must not have a password. | String : ... | -
org.osgi.framework.windowsystem | Provide the name of the current window system. This can be used by the native code clause. | String | -

## Knopflerfish Specified System Properties

Knopflerfish System properties should be specified using "-D".

Name | Description | Value type | Default value
--- | --- | --- | ---
org.knopflerfish.framework.main.verbosity | Verbosity level of the Main class starting the framework. 0 means few messages. Specify on the command line in order to see messages from the very beginning. | Integer | 0

## Knopflerfish Specified Framework Properties

The recommendation is to use "-F" for Knopflerfish Framework properties but "-D" should also work.

Name | Description | Value type | Default value
--- | --- | --- | ---
org.knopflerfish.framework.all_signed | If set to true, we require that all bundles that are installed are signed. | Boolean | True
org.knopflerfish.framework.automanifest | Flag to enable automatic manifest generation. If true, bundle manifest can be modified by a special configuration file. See javadoc for org.knopflerfish.framework.AutoManifest class for details. | Boolean | False
org.knopflerfish.framework.automanifest.config | Configuration URL for automatic manifest generation. Only valid if org.knopflerfish.framework.automanifest=true. An URL starting with "!!" followed by path is refer to a resource on the classloader that have loaded the framework. | String | !!/automanifest.props
org.knopflerfish.framework.bundlestorage | Storage implementation for bundles [dex, file, memory] | String | file (dex for Android systems)
org.knopflerfish.framework.bundlestorage.dex.always_unpack | When using dex file bundle storage, bundle jars can be unpacked or copied as-is. Unpacking leads to faster restart and class loading but takes longer for initial startup. If set to true, unpack all bundle jars. | Boolean | False
org.knopflerfish.framework.bundlestorage.dex.reference | When using dex file bundle storage, file: URLs can optionally be referenced only, not copied to the persistent area. If set to true, file: URLs are referenced only. Note: Individual bundles can be reference installed by using URLs of the syntax: reference:file:<path> This works even if the global reference flag is not enabled. | Boolean | False
org.knopflerfish.framework.bundlestorage.dex.trusted | Are the bundles stored in the dex file bundle storage to be trusted, if not signed bundles will be checked every time they are read. Untrusted storage leads to slower restart and class loading. If set to true, trust bundles in bundle storage. | Boolean | True
org.knopflerfish.framework.bundlestorage.file.always_unpack | When using file bundle storage, bundle jars can be unpacked or copied as-is. Unpacking leads to faster restart and class loading but takes longer for initial startup. If set to true, unpack all bundle jars. | Boolean | False
org.knopflerfish.framework.bundlestorage.file.jar_verifier_bug | There is a bug when using file bundle storage, certificate and Oracle JRE (Java 6). This bug causes the JarInputStream to miss picking up certificates for files under the "META-INF" directory if they directly follow the META-INF signature related files. This causes KF to mark the bundle as not completly signed. To ignore problem set property to true. | Boolean | False
org.knopflerfish.framework.bundlestorage.file.reference | When using file bundle storage, file: URLs can optionally be referenced only, not copied to the persistent area. If set to true, file: URLs are referenced only. Note: Individual bundles can be reference installed by using URLs of the syntax: reference:file:<path> This works even if the global reference flag is not enabled. | Boolean | False
org.knopflerfish.framework.bundlestorage.file.trusted | Are the bundles stored in the file bundle storage to be trusted, if not signed bundles will be checked every time they are read. Untrusted storage leads to slower restart and class loading. If set to true, trust bundles in bundle storage. | Boolean | True
org.knopflerfish.framework.bundlestorage.file.unpack | Most JVM requires that we unpack the bundle to access internal jars and native code. Setting this to true will unpack the jar if it contains internal jars or native code. If set to true, unpack needed bundle jars. | Boolean | True
org.knopflerfish.framework.bundlethread.timeout | Use this proprty to set a limit on how long the framework will wait for a bundle's activator to complete and return from the start and stop methods. If the time-out occurs, the framework will interrupt the BundleThread that is executing the start or stop method and then optionally stop it or lower its priority, see property org.knopflerfish.framework.bundlethread.abort. A BundleException is thrown to indicate that start/stop of the bundle failed. If set to a positive integer, the value is used as time-out in seconds. If set to 0, no time out is used and the framework will wait indefinitely for the activator's start and stop methods to complete. | Integer | 0
org.knopflerfish.framework.bundlethread.abort | If a bundle's start or stop method time-out (see property org.knopflerfish.framework.bundlethread.timeout) or if the bundle gets uninstalled before the method has returned, this property defines how to manage the bundle's start/stop thread. Possible values are:
"stop" | Calls the stop() method of the bundle's thread
"minprio" | Sets a minium priority of the bundle's thred
"ignore" | Do nothing
| String | ignore
org.knopflerfish.framework.debug.automanifest | Print debug output for automatic manifest actions. | Boolean | False
org.knopflerfish.framework.debug.bundle_resource | When security is enabled, print information about resource lookups that are rejected due to missing permissions for the calling bundle. | Boolean | False
org.knopflerfish.framework.debug.certficates | Print debug information about certificate handling. | Boolean | False
org.knopflerfish.framework.debug.classloader | Print debug information from classloader | Boolean | False
org.knopflerfish.framework.debug.errors | Print all FrameworkEvents of type ERROR | Boolean | False
org.knopflerfish.framework.debug.framework | Print debug information about life-cycle events for the current framework instance. | Boolean | False
org.knopflerfish.framework.debug.hooks | Print debug information about when service hooks are used current framework instance. | Boolean | False
org.knopflerfish.framework.debug.ldap | Print debug information about LDAP filters | Boolean | False
org.knopflerfish.framework.debug.resolver | Print debug information about resolver operation. | Boolean | False
org.knopflerfish.framework.debug.patch | Print debug information about class patching | Boolean | False
org.knopflerfish.framework.debug.permissions | Print debug information about permission evaluation. | Boolean | False
org.knopflerfish.framework.debug.print_with_do_privileged | Surround all debug print-operations originating from setting org.knopflerfish.debug.* properties with a doPrivileged() wrapper. | Boolean | True
org.knopflerfish.framework.debug.startlevel | Print debug information about startlevel service | Boolean | False
org.knopflerfish.framework.debug.service_reference | When security is enabled, print information about service reference lookups that are rejected due to missing permissions for calling bundle. | Boolean | False
org.knopflerfish.framework.debug.url | Print debug information about URL services | Boolean | False
org.knopflerfish.framework.is_doublechecked_locking_safe | Is it safe to use double-checked locking or not. It is safe if JSR 133 is included in the running JRE. I.e., for Java SE if version is 1.5 or higher. | Boolean | True
org.knopflerfish.framework.ldap.nocache | Disable LDAP caching for simple filters. LDAP caching speeds up framework filters considerably, but uses more memory. | Boolean | False
org.knopflerfish.framework.main.class.activation | A comma-separated list of locations of bundles whose Main-Class (set in manifest) should be used as activator if no BundleActivator is specified. The Main-Class will be used as activator if and only if the jar file does not specify a Bundle-Activator header and the bundle's location(see Bundle.getLocation) is found in the comma-separated list (case-sensitive).
    > java -jar framework.jar
        -Forg.knopflerfish.framework.main.class.activation=\
        file:/foo/bar.jar,http://foo.com/bar.jar ...
| String | -
org.knopflerfish.framework.main.verbosity | Verbosity level of the Main class starting the framework. 0 means few messages. Specify as a System property on the command line in order to see messages from the very beginning. | Integer | 0
org.knopflerfish.framework.main.xargs.writesysprops | Properties defined using -Fname=value in xargs-files are available for bundles using BundleContext.getProperty(name). This property controls weather such properties shall also be exported as system properties or not. | Boolean | False
org.knopflerfish.framework.listener.n_threads | Number of threads used to deliver events to asynchronous listeners. If the value is 0 then we will revert to the old behaviour and call all listeners synchronously. | Integer | 1
org.knopflerfish.framework.patch | If true AND once the classpatcher_all-N.N.N.jar bundle is installed and started, run time class patching will be enabled for all classes loaded afterwards. | Boolean | False
org.knopflerfish.framework.patch.configurl | URL to class patch config file. Only used when class patching is enabled. This is used as a fallback if a bundle does not specify a Bundle-ClassPatcher-Config manifest header. "!!" is used to read resources from the system class path "!" can be used to read bundle resources. | String | !!/patches.props
org.knopflerfish.framework.patch.dumpclasses | If true and class patching is enabled, dump all modified classes to a directory. | Boolean | False
org.knopflerfish.framework.patch.dumpclasses.dir | If dumpclasses is enabled, specifies a directory where to dump modified classes | String | patchedclasses
org.knopflerfish.framework.readonly | Controls if the framework should skip saving state changes permantly under framework directory. This means that if we are running with the default "file" bundle storage then new bundles must be installed as a referenced file URL (see property org.knopflerfish.framework.bundlestorage.file.reference). This also implies that no data storage will be available to bundles. | Boolean | False
org.knopflerfish.framework.resolver.implicituses | Set to true if resolver should in case that no uses directive is specified implicitly check all imported packages for class conflicts. | Boolean | False
org.knopflerfish.framework.resolver.prefersystembundle | Set to true if resolver should actively provide system bundle packages from the start. This will cause the resolver to prefer these packages if possible. | Boolean | False
org.knopflerfish.framework.service.conditionalpermissionadmin | Controls if the framework should register the Conditional Permission Admin service. | Boolean | True
org.knopflerfish.framework.service.permissionadmin | Controls if the framework should register the Permission Admin service. | Boolean | True
org.knopflerfish.framework.strictbootclassloading | If set to true, use strict rules for loading classes from the boot class loader. If false, accept class loading from the boot class path from classes themselves on the boot class, but which incorrectly assumes they may access all of the boot classes on any class loader (such as the bundle class loader). Setting this to true will, for example, result in broken serialization on the Sun JVM if bootdelegation does not exposes sun.* classes | Boolean | False
org.knopflerfish.framework.system.packages.base | An alternative to setting org.osgi.framework.system.packages. When this property is used the list of packages given will be appended with the default set of osgi-packages for the current framework and then used as the exports of the system bundle. | String , ... | -
org.knopflerfish.framework.system.packages.file | File containing list of packages exported by the system bundle. If not specified the framework will use default values based on java version. | String | -
org.knopflerfish.framework.system.packages.version | Name for selected exporting profile of system packages. | String | MAJOR.MINOR from system property "java.version"
org.knopflerfish.framework.usingwrapperscript | If set to "true", KF will assume that it has been started with the "kf2" shell script, and that it will be restarted if KF exits with exit code = 200. Required to be able to use new KF2 features such as extension bundles. This flag is set to "true" by the "kf2" shell script. | Boolean | False
org.knopflerfish.framework.validator | A list of which certificate validators to use. Currently available are JKSValidator and SelfSignedValidator. If no validator is to be used, set to "null" or "none". | String | JKSValidator if org.osgi.framework.trust.repositories Is set, otherwise none
org.knopflerfish.framework.validator.date | Date to use when validating certificates. The date is specifed in the current locales short date format. If no date is specified use the current date and time. | String | -
org.knopflerfish.framework.validator.jks.ca_certs | File name of java keystore used by JKSValidator. Used if org.osgi.framework.trust.repositories isn't set. | String | $JAVA_HOME/lib/security/cacerts
org.knopflerfish.framework.validator.jks.ca_certs_password | Password to java keystore used by JKSValidator. | String | changeit
org.knopflerfish.framework.validator.jks.cert_provider | Provider for CertificateFactory to use. | String | -
org.knopflerfish.framework.main.write.fwprops.xargs | Property that tells the Knopflerfish Main if it shall write a fwprops.xargs file with all framework properties inside the framework directory on startup or not. | Boolean | True
org.knopflerfish.gosg.jars | Semicolon separated list of base URLs for relative install commands | URL;... | URLs to the "jars" folder and all its sub-folders and fwresource:jars/
org.knopflerfish.startlevel.compat | Set to true indicates startlevel compatibility mode. All bundles and current start level will be 1. | Boolean | True
org.knopflerfish.startlevel.use | Use the Start Level service. If start level is not used then we do not create a non daemon thread that will keep a JVM with only daemon threads alive. | Boolean | True
org.knopflerfish.osgi.setcontextclassloader | If set to "true", set the bundle startup thread's context class loader to the bundle's class loader. This is useful for checking if an external lib will work better with a wrapped startup. It doesn't set the context classloader for event callbacks. Note that setting the context classloader is not mandated by OSGi, and might introduce dependencies on the KF framework, so this flag should only be enabled for testing purposes. | Boolean | False
org.knopflerfish.servicereference.valid.during.unregistering | If set to false, then the service reference can not be used to fetch an instance of the service during delivery and handling of the UNREGISTERING service event. The behaviour specified in the OSGi R4 v4.0.1 specification (and later), according to a clarification done by CPEG February 2008, is that it shall be possible to obtain a service instance during delivery of UNREGISTERING events thus this property now defaults to true. Note that independent of this setting the service reference of an UNREGISTERING service will not be returned by any of the methods searching for service references provided by the BundleContext interface. | Boolean | True
org.knopflerfish.osgi.registerserviceurlhandler | Flag for installing OSGi service based URL handlers. Since the URL handler can only be installed once, there might be cased where some external entity (not OSGi) sets this. In this case, the OSGi handler can be disabled by setting | Boolean | True