Plans are similar to PARs in that they encapsulate the artifacts of an application as a single unit. As a consequence, they have similar benefits; for details of the benefits common to PARs and plans, see PARs.
Plans have the following additional benefits, which is why SpringSource recommends that you use plans rather than PARs when defining an application:
Plans always get their dependencies from the dm Server repository. This means, for example, that if you drop one of the plan’s dependencies in the pickup
directory rather than adding it to the repository, the plan will fail to deploy because it will not find the dependency.
Plans are XML files that have a .plan
file extension, such as multi-artifact.plan
.
The structure of the XML file is simple:
the root element is <plan>
with attributes specifying the name of the plan, the version, atomicity, and scoping.
Then, for each artifact that makes up your application,
you add a <artifact>
element, using its attributes to specify the type of artifact and its name and version.
The following is a simple example of a plan’s XML file:
<?xml version="1.0" encoding="UTF-8"?> <plan name="multi-artifact.plan" version="1.0.0" scoped="true" atomic="true" xmlns="http://www.springsource.org/schema/dm-server/plan" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springsource.org/schema/dm-server/plan http://www.springsource.org/schema/dm-server/plan/springsource-dm-server-plan.xsd"> <artifact type="configuration" name="app-properties" version="1.0.0"/> <artifact type="bundle" name="com.springsource.exciting.app" version="[2.0.0, 3.1.0)"/> </plan>
In the preceding example, the name of the plan is multi-artifact.plan
and its version is 1.0.0
.
The plan is both scoped and atomic. The plan contains two artifacts: one is a bundle called com.springsource.exciting.app
and the other is a configuration file called app-properties
.
The following table describes the attributes of the <plan>
element.
Table 4.2. Attributes of the <plan> Element
Attribute | Description | Required? |
---|---|---|
name | Specifies the name of this plan. SpringSource dm Server uses the name as one component of the unique identifier of this plan. | Yes. |
version | Specifies the version of this plan. You must use OSGi version specification syntax, such as 2.1.0 . SpringSource dm Server uses the version as one component of the unique identifier of this plan. | Yes. |
scoped | Specifies whether SpringSource dm Server should install the artifacts into plan-specific scope so that only the application described by this plan has access to the artifacts. If you disable scoping, then SpringSource dm Server installs the artifacts into the global scope, which means they are then available for access by all other deployed artifacts. Set the attribute to true to enable scoping or false to disable it. | Yes. |
atomic | Specifies whether you want to tie together the lifecycle of the artifacts in this plan. Making a plan atomic means that if you install, start, stop, or uninstall a single artifact in the plan, SpringSource dm Server escalates the event to all artifacts in the plan. Also, in an atomic plan, SpringSource dm Server prevents artifacts from being in inconsistent states. For example, if one artifact should fail to start, then SpringSource dm Server stops all artifacts in the plan. Set this attribute to true to enable atomicity or false to disable it. | Yes. |
The following table describes the attributes of the <artifact>
element.
Table 4.3. Attributes of the <artifact> Element
Attribute | Description | Required? |
---|---|---|
type | Specifies the type of the artifact. Valid values are:
| Yes. |
name | Specifies the name of the artifact.
See Artifact Names for guidelines for determining the name of an artifact. | Yes. |
version | Specifies the version or range of versions of this artifact that dm Server should look up in its repositories and then install and deploy. You must use OSGi version specification syntax, such as [1.0.0, 2.0.0) . | No. If not specified, defaults to 0 , which in OSGi means 0 to infinity, or any version. |
When you create a plan, you use the name
attribute of the <artifact>
element to specify the name of all the plan’s dependencies. This section describes how to determine the name of an artifact, which is not always obvious.
Use the following guidelines to determine the name of an artifact:
Bundle: In this context, a bundle refers to a standard OSGi bundle as well as a Web application WAR file. The name of a bundle is the value of the Bundle-SymbolicName
header in the META-INF/MANIFEST.MF
file of the *.jar
or *.war
file. The following MANIFEST.MF
snippet shows a bundle with name com.springsource.exciting.app
:
Bundle-SymbolicName: com.springsource.exciting.app
If the bundle does not contain a META-INF/MANIFEST.MF
file, then the name of the bundle is its filename minus the .jar
or .war
extension.
Configuration File: The name of a configuration file is its filename minus the .properties
extension.
Plan: The name of a plan is the value of the required name
attribute of the <plan>
element in the plan’s XML file. In the following XML snippet, the plan name is multi-artifact.plan
:
<?xml version="1.0" encoding="UTF-8"?>
<plan name="multi-artifact.plan" version="1.0.0" scoped="true" atomic="true"
xmlns="http://www.springsource.org/schema/dm-server/plan"
...
PAR: The name of a PAR is the value of the Application-SymbolicName
header in the META-INF/MANIFEST.MF
file of the *.par
file. The following MANIFEST.MF
snippet shows a PAR with name com.springsource.my.par
:
Application-SymbolicName: com.springsource.my.par
If the PAR does not contain a META-INF/MANIFEST.MF
file, then the name of the PAR is its filename minus the .par
extension.
Because a plan is a list of artifacts, rather than a physical file that contains the artifacts, there are a few additional steps you must perform before you deploy it to dm Server.
Copy the artifacts that make up the plan to the usr
repository, which by default is the $DMS_HOME/repository/usr
directory, where $DMS_HOME
refers to the top-level installation directory of dm Server. Note that you might have configured the server differently; in which case, copy the artifacts to your custom repository directory.
Restart dm Server.
After the server has started, either use the Admin Console to deploy the plan, or manually deploy it by copying the plan’s XML file into the $DMS_HOME/pickup
directory.
This results in dm Server deploying the plan with the same semantics as a PAR file.
To undeploy the plan, use the Admin Console, or simply delete it from the $DMS_HOME/pickup
directory.
As described in previous sections, you can specify that a plan be scoped. This means that SpringSource dm Server installs the artifacts that make up the plan into a plan-specific scope so that only the application described by the plan has access to the artifacts. If you disable scoping, then SpringSource dm Server installs the artifacts into the global scope, which means they are available for access by all other deployed artifacts. This section describes scoping in a bit more detail. It also describes how you can change the default behavior of scoping, with respect to services, so that a service that is in a scope can be made globally available.
If a bundle in a given scope imports a package and a bundle in the same scope exports the package, then the import may only be satisfied by the bundle in the scope, and not by any bundles outside the scope, including the global scope. Similarly, package exports from bundles in a scope are not visible to bundles in the global scope.
If a bundle in a scope uses Spring DM (or the blueprint service) to obtain a service reference and a bundle in the same scope uses Spring DM (or the blueprint service) to publish a matching service, then the service reference may only bind to the service published in the scope (and not to any services outside the scope). Services published by bundles in a scope are not visible to bundles in the global scope.
However, sometimes it is useful to make a service in a scope globally available to artifacts outside the scope. To do this, publish the service with the com.springsource.service.scope
service property set to global
. Use the <service-properties>
child element of <service>
, as shown in the following example:
<service id="publishIntoGlobal" interface="java.lang.CharSequence">
<service-properties>
<beans:entry key="com.springsource.service.scope" value="global" />
</service-properties>
<beans:bean class="java.lang.String">
<beans:constructor-arg value="foo"/>
</beans:bean>
</service>