blob: b0a80681f627a89331d034036874d3a08d7235ef [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>4.3&nbsp;Creating Plans</title><link rel="stylesheet" href="css/stylesheet.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"><link rel="home" href="index.html" title="Virgo Programmer Guide"><link rel="up" href="ch04.html" title="4.&nbsp;Developing Applications"><link rel="prev" href="ch04s02.html" title="4.2&nbsp;Creating PARs and Web Applications"><link rel="next" href="ch04s04.html" title="4.4&nbsp;Creating and Using Configuration Artifacts"><!--Begin Google Analytics code--><script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script><script type="text/javascript">
var pageTracker = _gat._getTracker("UA-2728886-3");
pageTracker._setDomainName("none");
pageTracker._setAllowLinker(true);
pageTracker._trackPageview();
</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">4.3&nbsp;Creating Plans</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch04s02.html">Prev</a>&nbsp;</td><th width="60%" align="center">4.&nbsp;Developing Applications</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="ch04s04.html">Next</a></td></tr></table><hr></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="developing-applications-plans"></a>4.3&nbsp;Creating Plans</h2></div></div></div><p>
Plans are similar to PARs in that they encapsulate the artifacts of an application as a single unit.
However plans are XML files that refer to their artifacts, whereas PARs are JAR files that physically contain their artifacts.
Plans, known as <span class="emphasis"><em>parent</em></span> plans may refer to other plans, known as <span class="emphasis"><em>child</em></span> plans.
</p><p>
Plans share several benefits with PARs:
</p><div class="itemizedlist"><ul type="disc"><li>A plan has a (symbolic) name and a version.</li><li>A plan may be scoped, although this is optional.
See <a class="link" href="ch04s03.html#developing-applications-plans-scoping" title="Plans and Scoping">Plans and Scoping</a> for more on scoping.
</li><li>A plan is visible to management interfaces.</li><li>A plan can be undeployed and redeployed as a unit.</li><li>A plan may be atomic, although this is optional.</li></ul></div><p>
</p><p>
Plans have the following additional benefits compared to PARs:
</p><div class="itemizedlist"><ul type="disc"><li>
Virgo deploys the artifacts in the plan in the order in which they are listed in the XML file, which gives you
complete control over deployment order.
With a PAR, the order of deployment of the included artifacts is not guaranteed.
</li><li>Since plans refer to their artifacts, it is easier to share content between plans as well as update individual
parts of a plan without having to physically repackage (re-JAR) it.
</li><li>
Plans may contain child plans, but PARs cannot contain other PARs.
</li><li>
You can make certain plans deploy faster by disabling the provisioning of bundles to satisfy missing dependencies,
but you cannot disable provisioning for PARs.
</li><li>
You can specify whether a plan is scoped or unscoped and atomic or non-atomic; PARs are always scoped and atomic.
</li></ul></div><p>
</p><p>
The artifacts of a plan are usually stored in Virgo's repository. This means, for example, that if you drop one of the plan&#8217;s artifacts in the <code class="code">pickup</code> directory rather than adding it to the repository, the plan will fail to deploy because it will not find the artifact.
</p><p>
The artifacts of a plan may also be stored outside Virgo's repository, somewhere else on the file system and referenced from the plan using URIs.
Such artifacts must be available on the file system when the plan is deployed and when Virgo restarts while the plan is deployed.
If you delete any of these artifacts, deployment of the plan may fail, either when it is initially deployed or when Virgo restarts.
</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="developing-applications-plans-create"></a>Creating the Plan XML File</h3></div></div></div><p>
Plans are XML files that have a <code class="code">.plan</code> file extension, such as <code class="code">multi-artifact.plan</code>.
The structure of the XML file is simple:
the root element is <code class="code">&lt;plan&gt;</code> 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 <code class="code">&lt;artifact&gt;</code> element, using its attributes to specify the type of artifact and its name and version.
The following is a simple example of a plan&#8217;s XML file:
</p><pre class="programlisting">&lt;<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>&gt;
&lt;<span class="hl-tag">plan</span> <span class="hl-attribute">name</span>=<span class="hl-value">"multi-artifact.plan"</span> <span class="hl-attribute">version</span>=<span class="hl-value">"1.0.0"</span> <span class="hl-attribute">scoped</span>=<span class="hl-value">"true"</span> <span class="hl-attribute">atomic</span>=<span class="hl-value">"true"</span>
<span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.eclipse.org/virgo/schema/plan"</span>
<span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"
http://www.eclipse.org/virgo/schema/plan
http://www.eclipse.org/virgo/schema/plan/eclipse-virgo-plan.xsd"</span>&gt;
&lt;<span class="hl-tag">artifact</span> <span class="hl-attribute">type</span>=<span class="hl-value">"configuration"</span> <span class="hl-attribute">name</span>=<span class="hl-value">"app-properties"</span> <span class="hl-attribute">version</span>=<span class="hl-value">"1.0.0"</span>/&gt;
&lt;<span class="hl-tag">artifact</span> <span class="hl-attribute">type</span>=<span class="hl-value">"bundle"</span> <span class="hl-attribute">name</span>=<span class="hl-value">"com.springsource.exciting.app"</span> <span class="hl-attribute">version</span>=<span class="hl-value">"[2.0.0, 3.1.0)"</span>/&gt;
&lt;<span class="hl-tag">/plan</span>&gt;</pre><p>
In the preceding example, the name of the plan is <code class="code">multi-artifact.plan</code> and its version is <code class="code">1.0.0</code>.
The plan is both scoped and atomic. The plan contains two artifacts: one is a bundle called <code class="code">com.springsource.exciting.app</code> and the other is a configuration file called <code class="code">app-properties</code>.
</p><p>
The following table describes the attributes of the <code class="code">&lt;plan&gt;</code> element.
</p><div class="table"><a name="developing-applications-plans-create-plan-attributes"></a><p class="title"><b>Table&nbsp;4.2.&nbsp;Attributes of the &lt;plan&gt; Element</b></p><div class="table-contents"><table summary="Attributes of the <plan&gt; Element" style="border-collapse: collapse;border-top: 1.0pt solid ; border-bottom: 1.0pt solid ; border-left: 1.0pt solid ; border-right: 1.0pt solid ; "><colgroup><col><col><col></colgroup><thead><tr><th style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Attribute</th><th style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Description</th><th style="border-bottom: 1.0pt solid ; ">Required?</th></tr></thead><tbody><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; "><code class="literal">name</code></td><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Specifies the name of this plan. Virgo uses the name as one component of the unique identifier of this plan. </td><td style="border-bottom: 1.0pt solid ; ">Yes.</td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; "><code class="literal">version</code></td><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Specifies the version of this plan. You must use OSGi version specification syntax, such as <code class="code">2.1.0</code>. Virgo uses the version as one component of the unique identifier of this plan. </td><td style="border-bottom: 1.0pt solid ; ">Yes.</td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; "><code class="literal">scoped</code></td><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Specifies whether Virgo 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 Virgo installs the artifacts into the global scope, which means they are then available for access by all other deployed artifacts. Set the attribute to <code class="code">true</code> to enable scoping or <code class="code">false</code> to disable it.</td><td style="border-bottom: 1.0pt solid ; ">Yes.</td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; "><code class="literal">atomic</code></td><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Specifies whether you want to tie together the lifecycle of the artifacts in this plan.
Making a plan atomic means that if you start, stop, or uninstall a single artifact in the plan, Virgo escalates the operation to
the whole plan. Also Virgo prevents artifacts of an atomic plan from being in inconsistent states.
For example, if one artifact should fail to start, then Virgo stops all artifacts in the plan.
Set this attribute to <code class="code">true</code> to enable atomicity or <code class="code">false</code> to disable it. </td><td style="border-bottom: 1.0pt solid ; ">Yes.</td></tr><tr><td style="border-right: 1.0pt solid ; "><code class="literal">provisioning</code></td><td style="border-right: 1.0pt solid ; ">
<p>
Specifies whether Virgo installs bundles from the repository to attempt to satisfy any missing dependencies in the plan.
Missing dependencies prevent one or more bundles in the plan from resolving.
For example, a bundle which imports a package cannot resolve if the package is missing, that is, not exported by another bundle.
</p>
<p>
A value of <code class="code">auto</code> instructs Virgo to install bundles from the repository
to attempt to satisfy any missing dependencies in the plan. This is known as <span class="emphasis"><em>auto-provisioning</em></span>.
</p>
<p>
A value of <code class="code">disabled</code> prevents Virgo from installing bundles from the repository to attempt to
satisfy any missing dependencies in the plan.
This value can make the plan deploy faster, although if there are missing dependencies, deployment will fail.
</p>
<p>
A value of <code class="code">inherit</code>, which is the default if no value is specified, inherits the parent plan's provisioning behaviour.
If the plan does not have a parent, it inherits Virgo's auto-provisioning behaviour.
</p>
</td><td style="">No. If not specified, defaults to <code class="code">inherit</code>.</td></tr></tbody></table></div></div><br class="table-break"><p>
The following table describes the attributes of the <code class="code">&lt;artifact&gt;</code> element. Note that you must either specify <code class="literal">type</code>, <code class="literal">name</code>, and (optionally) <code class="literal">version</code>,
in which case Virgo's repository is searched for the artifact, or <code class="literal">uri</code> in which case the artifact is obtained directly from the file system.
If you specify <code class="literal">uri</code>, you must not specify <code class="literal">type</code>, <code class="literal">name</code>, or <code class="literal">version</code>.
</p><div class="table"><a name="developing-applications-plans-create-artifact-attributes"></a><p class="title"><b>Table&nbsp;4.3.&nbsp;Attributes of the &lt;artifact&gt; Element</b></p><div class="table-contents"><table summary="Attributes of the <artifact&gt; Element" style="border-collapse: collapse;border-top: 1.0pt solid ; border-bottom: 1.0pt solid ; border-left: 1.0pt solid ; border-right: 1.0pt solid ; "><colgroup><col><col><col></colgroup><thead><tr><th style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Attribute</th><th style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Description</th><th style="border-bottom: 1.0pt solid ; ">Required?</th></tr></thead><tbody><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; "><code class="literal">type</code></td><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Specifies the type of the artifact. Valid values are:
<div class="itemizedlist"><ul type="disc"><li><code class="code">bundle</code>: Specifies an OSGi bundle. Use this artifact type for WAR files and Web application bundles. </li><li><code class="code">configuration</code>: Specifies that the artifact is a configuration file. Configuration files contain name/value pairs that set initial values for configuration properties of a bundle. </li><li><code class="code">plan</code>: Specifies that the artifact is a plan. </li><li><code class="code">par</code>: Specifies that the artifact is a PAR. </li></ul></div>
</td><td style="border-bottom: 1.0pt solid ; ">Yes, unless <code class="literal">uri</code> is specified in which case <code class="literal">type</code> must not be specified and is automatically determined from the artifact.</td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; "><code class="literal">name</code></td><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Specifies the name of the artifact.
<p>See <a class="link" href="">Artifact Names</a> for guidelines for determining the name of an artifact.</p>
</td><td style="border-bottom: 1.0pt solid ; ">Yes, unless <code class="literal">uri</code> is specified in which case <code class="literal">name</code> must not be specified and is automatically determined from the artifact.</td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; "><code class="literal">version</code></td><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">Specifies the range of versions of this artifact that Virgo should look up in its repositories and then install and deploy.
You must use OSGi version specification syntax, such as <code class="code">[1.0.0, 2.0.0)</code>.
Note that a single version number represents the range from that version number upwards.
For example, <code class="code">1.3</code> represents the range of versions greater than or equal to <code class="code">1.3</code>.
</td><td style="border-bottom: 1.0pt solid ; ">No. If <code class="literal">uri</code> is specified, <code class="literal">version</code> must not be specified.
If neither <code class="literal">uri</code> nor <code class="literal">version</code> are specified, <code class="literal">version</code> defaults to <code class="code">0</code>, which in OSGi means 0 to infinity, or any version.</td></tr><tr><td style="border-right: 1.0pt solid ; "><code class="literal">uri</code></td><td style="border-right: 1.0pt solid ; ">
Specifies an optional, absolute URI string beginning with <code class="code">file:</code> that refers to the artifact on the file system.
Such an artifact must be available on the file system when the plan is deployed and when Virgo restarts while the plan is deployed.
If you delete such an artifact, deployment of the plan may fail, either when it is initially deployed or when Virgo restarts.
This attribute is normally omitted so that the artifact is searched for in Virgo's repository.
</td><td style="">No. If not specified, Virgo searches for the artifact in its repository.</td></tr></tbody></table></div></div><br class="table-break"></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="names-of-artifacts"></a>Artifact Names</h3></div></div></div><p>When you create a plan, you use the <code class="code">name</code> attribute of the <code class="code">&lt;artifact&gt;</code> element to specify the name of all the plan&#8217;s dependencies. This section describes how to determine the name of an artifact, which is not always obvious.</p><p>Use the following guidelines to determine the name of an artifact:</p><div class="itemizedlist"><ul type="disc"><li><p><span class="bold"><strong>Bundle</strong></span>: In this context, a <span class="emphasis"><em>bundle</em></span> refers to a standard OSGi bundle as well as a Web Application Bundle and a WAR file. The name of a bundle is the value of the <code class="code">Bundle-SymbolicName</code> header in the <code class="code">META-INF/MANIFEST.MF</code> file of the <code class="code">*.jar</code>.
If a WAR file has <code class="code">Bundle-SymbolicName</code> header then it will be treated as a Web Application Bundle. The following <code class="code">MANIFEST.MF</code> snippet shows a bundle with name <code class="code">com.springsource.exciting.app</code>:</p><pre class="screen">Bundle-SymbolicName: org.eclispe.virgo.exciting.app</pre><p>If the bundle does not contain a <code class="code">META-INF/MANIFEST.MF</code> file or the <code class="literal">MANIFEST.MF</code> doesn't contain a <code class="code">Bundle-SymbolicName</code> header, then the name of the bundle is its filename minus the <code class="code">.jar</code> or <code class="code">.war</code> extension.</p></li><li><p><span class="bold"><strong>Configuration File</strong></span>: The name of a configuration or PID (Persistent Identity) is its filename minus the <code class="code">.properties</code> extension. The PID can also be specified within the properties file with the
<span class="emphasis"><em>service.pid</em></span> property.
</p></li><li><p><span class="bold"><strong>Plan</strong></span>: The name of a plan is the value of the required <code class="code">name</code> attribute of the <code class="code">&lt;plan&gt;</code> element in the plan&#8217;s XML file. In the following XML snippet, the plan name is <code class="code">multi-artifact.plan</code>:</p><pre class="screen">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;plan name="<span class="bold"><strong>multi-artifact.plan</strong></span>" version="1.0.0" scoped="true" atomic="true"
xmlns="http://www.eclipse.org/virgo/schema/plan"
...</pre></li><li><p><span class="bold"><strong>PAR</strong></span>: The name of a PAR is the value of the <code class="code">Application-SymbolicName</code> header in the <code class="code">META-INF/MANIFEST.MF</code> file of the <code class="code">*.par</code> file. The following <code class="code">MANIFEST.MF</code> snippet shows a PAR with name <code class="code">com.springsource.my.par</code>:</p><pre class="screen">Application-SymbolicName: org.eclipse.virgo.my.par</pre><p>If the PAR does not contain a <code class="code">META-INF/MANIFEST.MF</code> file, then the name of the PAR is its filename minus the <code class="code">.par</code> extension.</p></li></ul></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="passing-properties"></a>Supplying Properties to Artifacts</h3></div></div></div><p>
It is possible to pass properties to an artifact specified in a plan. An example of this can be seen in the Admin Console plan where the context path to be used in the Admin console is passed from the plan.
</p><pre class="programlisting">
&lt;artifact type="bundle" name="org.eclipse.virgo.apps.admin.web" version="[3.0, 4.0)"&gt;
&lt;property name="header:Web-ContextPath" value="/admin" /&gt;
&lt;/artifact&gt;
</pre><p>
The only supported property is <code class="literal">header</code> which will overwrite the given manifest header with the supplied value. This should be used with care!
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="developing-applications-plans-use"></a>Using the Plan</h3></div></div></div><p>
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 Virgo.
</p><div class="orderedlist"><ol type="1"><li><p>Copy the artifacts that make up the plan to the <code class="code">usr</code> repository, which by default is the <code class="code">$SERVER_HOME/repository/usr</code> directory, where <code class="code">$SERVER_HOME</code> refers to the top-level installation directory of Virgo. Note that you might have configured the server differently; in which case, copy the artifacts to your custom repository directory.</p></li><li><p>Restart Virgo if the repository used is not a <span class="emphasis"><em>watched</em></span> repository.</p></li><li><p>After the server has started, either use the Admin Console to deploy the plan, or manually deploy it by copying the plan&#8217;s XML file into the <code class="code">$SERVER_HOME/pickup</code> directory. </p><p>This results in Virgo deploying the plan.</p></li><li><p>To undeploy the plan, use the Admin Console, or simply delete it from the <code class="code">$SERVER_HOME/pickup</code> directory.</p></li></ol></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="developing-applications-plans-scoping"></a>Plans and Scoping</h3></div></div></div><p>As described in previous sections, you can specify that a plan be <span class="emphasis"><em>scoped</em></span>. This means that Virgo 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 Virgo 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. </p><p>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.</p><p>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. </p><p>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 <code class="literal">org.eclipse.virgo.service.scope</code> service property set to <code class="literal">global</code>. Use the <code class="literal">&lt;service-properties&gt;</code> child element of <code class="literal">&lt;service&gt;</code>, as shown in the following example: </p><pre class="programlisting">&lt;service id="publishIntoGlobal" interface="java.lang.CharSequence"&gt;
<span class="bold"><strong>&lt;service-properties&gt;
&lt;beans:entry key="org.eclipse.virgo.service.scope" value="global" /&gt;
&lt;/service-properties&gt;</strong></span>
&lt;beans:bean class="java.lang.String"&gt;
&lt;beans:constructor-arg value="foo"/&gt;
&lt;/beans:bean&gt;
&lt;/service&gt;</pre><p>
A scope forms a boundary for automatic propagation of load time weaving and bundle refresh.
Additionally, a synthetic context bundle is generated for each scope. This bundle imports all the packages exported by other bundles in the scope.
The class loader of the synthetic context bundle is used for thread context class loading. So,
for example, hibernate will be able to load classes of any of the exported
packages of the bundles in a scope using the thread context class loader.
</p><p>
To ensure predictable class loading behaviour and avoid other issues associated with <span class="emphasis"><em>split packages</em></span> (packages whose classes
are split across more than one bundle), the synthetic context bundle has a restriction:
<span class="bold"><strong>no package may be exported by more than one
bundle in the scope</strong></span>.
If this restriction is broken, the scoped application will fail to deploy.
This restriction can cause problems for <a class="link" href="ch08s07.html" title="8.7&nbsp;Scoping and Substitutable Exports">substitutable exports</a>.
</p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="developing-applications-plans-scoping-webapps"></a>Web Applications and Scoping</h4></div></div></div><p>
A Web Application Bundle (WAB) or WAR has its bundle class loader set as the TCCL, even when the WAB or WAR belongs to
a PAR or scoped plan.
To enable the TCCL to load classes of other bundles in the same scope as a WAB or WAR, use a WAB which imports the necessary packages.
</p><p>
Also a WAB or WAR has its own per-application trace, independent of the per-application trace of any PAR or scoped plan to which the
WAB or WAR belongs.
</p></div></div></div><!--Begin LoopFuse code--><script src="http://loopfuse.net/webrecorder/js/listen.js" type="text/javascript"></script><script type="text/javascript">
_lf_cid = "LF_48be82fa";
_lf_remora();
</script><!--End LoopFuse code--><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch04s02.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="ch04.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="ch04s04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4.2&nbsp;Creating PARs and Web Applications&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;4.4&nbsp;Creating and Using Configuration Artifacts</td></tr></table></div></body></html>