Daisy documentation
 PreviousHomeNext 
4.16 Extending the repositoryBook Index4.16.3 Component configuration

4.16.2 Daisy Runtime

4.16.2.1 What is it?

The Daisy Runtime is the platform upon which the repository server runs. Basically, it consists of a set of isolated Spring bean containers, with some infrastructure for setting up classloaders and for sharing services between the Spring containers. It's really just a thin layer around Spring. You could think of it as a “Spring-OSGI-light”.

Some background on how we arrived at this can be found in this blog entry.

4.16.2.2 How it works

The Daisy Runtime takes two important parameters for booting up:

In this documentation, the words “artifact” and “jar” basically mean the same thing.

Each container jar contains a file describing the the required classpath, and one or more Spring container definitions. The Daisy Runtime will start a separate Spring container corresponding to each container jar.

The details of the classloader setup are described further on.

Each container can export and import services to/from a common service registry. How this is done is also explained further on.

So once more, summarized: the purpose of the Daisy Runtime is starting Spring containers, setting up classloaders for them, and allowing them to share selected services.

4.16.2.3 The Runtime CLI

There are few ways to start the runtime:

For both cases, we also have a small launcher jar which has the advantage that you only need to add this launcher jar to your classpath, and it will then set up the classloader to boot the Daisy Runtime. In case of the programmatic access, you will of course need the jars for any API's you want to use in the current classloader.

4.16.2.4 The runtime config file

The runtime config file is an XML file listing the container jars to be started as part of the runtime.

Container jars can be specified in multiple ways

The following sample shows how to specify each of them in the configuration:

<?xml version="1.0"?>
<runtime>
  <containers>

    <artifact id="cont1" groupId="foo" artifactId="bar" version="2.1"/>

    <file id="cont2" path="/path/to/file.jar"/>

    <directory id="foo" path="/foo/bar"/>    

  </containers>
</runtime>

The id attribute values need to be unique.

The containers are started in the order as listed here. The order can be important for export and import of services, as described further on.

In the file and directory paths, you can insert system property using ${...} notation. For example:

<directory id="something" path="${user.home}${file.separator}/containers"/>

4.16.2.5 The container jar

A container jar is normal jar file containing a DAISY-INF directory with metadata for the Daisy Runtime.

The structure is as follows:

DAISY-INF
 + classloader.xml
 + spring
    + applicationContext.xml
    + ...
4.16.2.5.1 The DAISY-INF/spring directory

The spring directory can contain Spring container definitions in the form of XML files. There needs to be at least one. The files can have any name as long as it ends on .xml. Often applicationContext.xml is used.

These are standard Spring XML files, though we have some extension namespaces for the import and export of services, and for the configuration system.

As a template, to have all these namespaces declared, you might use the following:

<?xml version="1.0"?>
<beans              xmlns = "http://www.springframework.org/schema/beans"
                xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
              xmlns:daisy = "http://outerx.org/daisy/1.0#runtime-springext"
               xmlns:conf = "http://outerx.org/daisy/1.0#config-springext"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
                             http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                             http://outerx.org/daisy/1.0#runtime-springext
                             http://daisycms.org/schemas/daisyruntime-springext.xsd
                             http://outerx.org/daisy/1.0#config-springext
                             http://daisycms.org/schemas/config-springext.xsd">

  <!-- Import and export sample syntax:
  <daisy:import-service id="" service="(interface FQN)"/>
  <daisy:export-service ref="" service="(interface FQN)"/>
  -->

  <!-- Insert bean definitions here -->
</beans>
4.16.2.5.2 The classloader.xml file

The classloader.xml file lists the artifacts that need to be in the classpath. The container jar itself is always automatically added as the first entry in the classpath. The classloader.xml file is optional.

As mentioned before, jars are referenced as Maven artifact references. The Daisy Runtime will search them in a Maven-style local repository specified at startup of the Runtime. The Runtime does not support automatic downloading of missing artifacts from remote repositories.

The syntax of the classloader.xml is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<classloader>
  <classpath>
    <artifact groupId="" artifactId="" version="" share="allowed|required|prohibited"/>
  </classpath>
</classloader>

This is pretty straightforward, except for the share attribute. Next to the classloader for each container, the Daisy Runtime also creates a common classloader that acts as the parent classloader for each of the container classloaders, as illustrated in the figure below.

By means of the share attribute, you can specify if an artifact can, should or should not be added to the common classloader. This is done using the following attribute values:

When starting up, the Daisy Runtime will first read the classloader configurations of all containers in order to determine what artifacts should be part to the common classloader and what artifacts should be in container-specific classloaders. When using the Runtime CLI, you can specify the command line option --classloader-log to see a report of this.

4.16.2.5.2.1 Enforcement of share=”prohibited”

Currently share=”prohibited” is not enforced. For example if one container has artifact A as share-allowed and another one has artifact A as share-prohibited, then artifact A will be added to the common classloader, and the Daisy Runtime will only print a warning.

4.16.2.5.2.2 Disabling artifact sharing

Since the share=”allowed” mode only indicates optional sharing, things should work just as well when these artifacts are not shared. The Daisy Runtime CLI supports the command line option to do this, --disable-class-sharing.

This can be useful to check that the classpaths of all containers list their required dependencies, and that things which should be common use the share=”required” mode.

4.16.2.5.2.3 Sharing/publishing classes requires to put them in a different jar

As a consequence of the how our system works, if you want to add classes to the common classloader they have to be in a separate jar. It is good practice to put APIs and implementation in separate jars, so often this is no problem. This is different from e.g. OSGI where exporting is done using Java packages rather than jars.

4.16.2.5.2.4 Dependencies between artifacts

If the system decides to put one shareable jar (jar A) in the shared classloader, and another shareable jar (jar B) not, and jar A is dependent on jar B, there might be problems since the classes in jar A won't find the classes in jar B. However, this is an unlikely situation to occur since then all containers should have both jar A and B as shareable jars.

4.16.2.5.2.5 The order of the entries in the common classloader

There is currently no control over the order of the entries in the common classloader.

4.16.2.5.2.6 Knowing more about classloaders

For using the Daisy Runtime, it suffices to have a very basic understanding of classloaders. If you are interested on learning everything about classloading, a good book is Component Development for the Java Platform.

4.16.2.6 Exporting and importing services

By default one container cannot access the “beans” in another container. The Daisy Runtime provides the ability to export specific beans as “services” and to import services exported by other containers.

This importing and exporting is done by custom elements in the Spring XML container definition.

4.16.2.6.1 Exporting a bean / service

When exporting a service, you need to specify the ID of the bean and the interface which you want to make available:

<daisy:export-service ref="mybeanid" service="org.mydomain.MyInterface"/>

If a bean implements multiple interfaces, and you want to make this all available as services, you need multiple exports for the same bean:

<daisy:export-service ref="mybeanid" service="org.mydomain.InterfaceA"/>
<daisy:export-service ref="mybeanid" service="org.mydomain.InterfaceB"/>

Note that the service must be an interface, it is not possible to export services using concrete classes.

4.16.2.6.1.1 Only one service of a certain type can be shared

The shared service registry is basically a map using the service interface as key. This means there can be only service per interface. An exception will be thrown if a second export for the same service interface is done.

4.16.2.6.2 Importing a service

To import a service, use the following syntax:

<daisy:import-service id="datasource" service="javax.sql.DataSource"/>

The id is the id for the bean in the local container. You will hence be able to pass the service to other beans using this id (as you would do for any other bean).

4.16.2.6.2.1 Order in which the containers are loaded

The order in which the container jars are specified to the Daisy Runtime is important, it needs to be such that the imports of a container are satisfied by exports done by earlier started containers.

4.16.2.6.2.2 Shielding of exported services

Daisy will not provide a direct pointer to the corresponding bean when importing a service. Rather, it creates a dynamic proxy implementing the service interface. This is to:

4.16.2.7 Daisy Runtime shutdown

When shutting down the Daisy Runtime, all Spring containers are destroyed in the reverse order that they were started.

4.16.2.8 Starting the Daisy Runtime using the CLI

The Daisy Runtime CLI provides a couple of useful options, use the -h (help) argument to see them.

For example, in the binary distribution the Daisy Runtime is started by the daisy-repository-server script:

cd $DAISY_HOME/repository-server/bin
daisy-repository-server -h

In development setup, this is

cd <source tree root>/repository/server
start-repository -h
 PreviousHomeNext 
4.16 Extending the repository4.16.3 Component configuration