blob: 06fd9bfadc56cf22657eb2e7bc4c99a28e5b32fd [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.3">
<title>Developing Applications</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
/* Remove comment around @import statement below when using as a custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
audio,canvas,video{display:inline-block}
audio:not([controls]){display:none;height:0}
[hidden],template{display:none}
script{display:none!important}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
body{margin:0}
a{background:transparent}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
body{-webkit-font-smoothing:antialiased}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.center{margin-left:auto;margin-right:auto}
.spread{width:100%}
p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:none}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.no-bullet{list-style:none}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite:before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7;font-weight:bold}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
body{tab-size:4}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
.clearfix:after,.float-group:after{clear:both}
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menu{color:rgba(0,0,0,.8)}
b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
b.button:before{content:"[";padding:0 3px 0 2px}
b.button:after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
#content{margin-top:1.25em}
#content:before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span:before{content:"\00a0\2013\00a0"}
#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark:before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber:after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
.sect1{padding-bottom:.625em}
@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
.sect1+.sect1{border-top:1px solid #efefed}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.listingblock>.content{position:relative}
.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
.listingblock:hover code[data-lang]:before{display:block}
.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
table.pyhltable td.code{padding-left:.75em;padding-right:0}
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
pre.pygments .lineno{display:inline-block;margin-right:.25em}
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
.quoteblock .quoteblock blockquote:before{display:none}
.verseblock{margin:0 1em 1.25em 1em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
table.tableblock{max-width:100%;border-collapse:separate}
table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot{border-width:1px 0}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
td>div.verse{white-space:pre}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
ul.inline>li>*{display:block}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
.colist>table tr>td:last-of-type{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background-color:#00fafa}
.black{color:#000}
.black-background{background-color:#000}
.blue{color:#0000bf}
.blue-background{background-color:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background-color:#fa00fa}
.gray{color:#606060}
.gray-background{background-color:#7d7d7d}
.green{color:#006000}
.green-background{background-color:#007d00}
.lime{color:#00bf00}
.lime-background{background-color:#00fa00}
.maroon{color:#600000}
.maroon-background{background-color:#7d0000}
.navy{color:#000060}
.navy-background{background-color:#00007d}
.olive{color:#606000}
.olive-background{background-color:#7d7d00}
.purple{color:#600060}
.purple-background{background-color:#7d007d}
.red{color:#bf0000}
.red-background{background-color:#fa0000}
.silver{color:#909090}
.silver-background{background-color:#bcbcbc}
.teal{color:#006060}
.teal-background{background-color:#007d7d}
.white{color:#bfbfbf}
.white-background{background-color:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background-color:#fafa00}
span.icon>.fa{cursor:default}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]:after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@media print{@page{margin:1.25cm .75cm}
*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]:after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
.sect1{padding-bottom:0!important}
.sect1+.sect1{border:0!important}
#header>h1:first-child{margin-top:1.25rem}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span:before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]:before{display:block}
#footer{background:none!important;padding:0 .9375em}
#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
</style>
</head>
<body class="article">
<div id="header">
</div>
<div id="content">
<div class="paragraph">
<p><a id="developing-applications"></a></p>
</div>
<div class="sect1">
<h2 id="_developing_applications">Developing Applications</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Applications that take advantage of the OSGi capabilities of Virgo
are typically comprised of multiple bundles. Each bundle may have dependencies on
other bundles. Furthermore, each bundle exposes only certain packages and
services. In this chapter, we look at how to create bundles, import and export
appropriate functionality, and create artifacts to deploy web applications on the Virgo for Apache Tomcat.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-bundle"></a></p>
</div>
<div class="sect2">
<h3 id="_anatomy_of_a_bundle">Anatomy of a Bundle</h3>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">
<div class="paragraph">
<p>This is an abbreviated introduction to OSGi bundles. Please refer to the <a href="https://www.eclipse.org/gemini/blueprint/documentation/reference/2.0.0.RELEASE/html/index.html">Eclipse Gemini Blueprint Reference Guide</a> for full details.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>An OSGi bundle is simply a jar file with metadata that describe
additional characteristics such as version and imported and exported packages.</p>
</div>
<div class="paragraph">
<p>A bundle exports types and publishes services to be used by other bundles:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Types</strong>: via the OSGi <code>Export-Package</code> directive,</p>
</li>
<li>
<p><strong>Services</strong>: via Gemini Blueprint&#8217;s <code>&lt;service &#8230;&#8203; &gt;</code> XML namespace element.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>A bundle may import types and services exported by other bundles:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Types</strong>: via the OSGi <code>Import-Package</code> directive,</p>
</li>
<li>
<p><strong>Services</strong>: via Gemini Blueprint&#8217;s <code>&lt;reference &#8230;&#8203; &gt;</code> XML namespace element.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Let&#8217;s see an example from the PetClinic sample application. The following listing shows the
<code>MANIFEST.MF</code> file for the <code>org.springframework.petclinic.infrastructure.hsqldb</code> bundle.</p>
</div>
<div class="listingblock">
<div class="title">MANIFEST.MF</div>
<div class="content">
<pre class="highlight"><code class="language-txt" data-lang="txt">Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: PetClinic HSQL Database Infrastructure
Bundle-SymbolicName: org.springframework.petclinic.infrastructure.hsqldb
Bundle-Version: 1.0
Import-Library: org.springframework.spring;version="[2.5,2.6]"
Import-Bundle: com.springsource.org.apache.commons.dbcp;version="[1.2.2.osgi,1.2.2.osgi]",
com.springsource.org.hsqldb;version="[1.8.0.9,1.8.0.9]"
Import-Package: javax.sql
Export-Package: org.springframework.petclinic.infrastructure</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>org.springframework.petclinic.infrastructure.hsqldb</code> bundle expresses its dependencies on
the <code>javax.sql</code> package, the Commons DBCP and HSQLDB bundles, and the Spring library (we will examine
the details of the library artifact in <a href="#developing-applications-defining-libraries">Defining Libraries</a>. The Commons DBCP
bundle is imported at a version of exactly <code>1.2.2.osgi</code> and the HSQLDB bundle is imported at a version of exactly
<code>1.8.0.9</code>. The Spring library is imported at a version between <code>2.5</code> inclusive and <code>2.6</code> exclusive.</p>
</div>
<div class="paragraph">
<p>Note that you do not specify the bundle that will provide the imported packages.
Virgo will examine the available bundles and satisfy the required dependencies.</p>
</div>
<div class="paragraph">
<p>The following <code>osgi-context.xml</code> file from the PetClinic sample&#8217;s
<code>org.springframework.petclinic.repository.jdbc</code> bundle declares a service published by the bundle and
references a service published by another bundle.</p>
</div>
<div class="listingblock">
<div class="title">osgi-context.xml</div>
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans:beans xmlns="http://www.springframework.org/schema/osgi"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;
&lt;service id="osgiClinic" ref="clinic" interface="org.springframework.petclinic.repository.Clinic" /&gt;
&lt;reference id="dataSource" interface="javax.sql.DataSource"/&gt;
&lt;/beans:beans&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>service</code> element publishes the <code>clinic</code> bean
(a regular Spring bean declared in the <code>module-context.xml</code> file) and specifies
<code>org.springframework.petclinic.repository.Clinic</code> as the type
of the published service.</p>
</div>
<div class="paragraph">
<p>The <code>reference</code> elements define a <code>dataSource</code> bean that references
a service published by another bundle with a an interface type of <code>javax.sql.DataSource</code>.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-packaging"></a></p>
</div>
</div>
<div class="sect2">
<h3 id="_creating_pars_and_web_applications">Creating PARs and Web Applications</h3>
<div class="paragraph">
<p>Virgo supports two OSGi-oriented ways of packaging applications: the PAR format
and application bundles (including web bundles). The VTS also supports three
distinct WAR deployment and packaging formats: standard Java EE WAR, Shared Libraries WAR, Shared Services WAR.</p>
</div>
<div class="paragraph">
<p>Virgo also supports plans as a way to describe an application. This method is similar to a PAR
in that it encapsulates all the artifacts of an application as a single unit, but differs in that a plan simply
lists the bundles in an XML file rather than packaging all the bundles in a single JAR file. The use of plans
offers additional benefits to using PARs; for this reason, we recommend their use. For details, see
<a href="#developing-applications-plans">Creating Plans</a>.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-packaging-par"></a></p>
</div>
<div class="sect3">
<h4 id="_pars">PARs</h4>
<div class="paragraph">
<p>An OSGi application is packaged as a JAR file, with extension <code>.par</code>. A PAR artifact offers several benefits:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A PAR file has an application name, version, symbolic name, and description.</p>
</li>
<li>
<p>The artifacts of a PAR file are scoped so that they cannot
be shared accidentally by other applications. The scope forms a boundary for automatic
propagation of load time weaving and bundle refresh.
See <a href="#developing-applications-plans-scoping">Plans and Scoping</a> for more on scoping.</p>
</li>
<li>
<p>Since a PAR is scoped, its artifacts have their exported packages imported by the
synthetic context bundle which 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 PAR file using the thread context class loader.</p>
</li>
<li>
<p>A PAR file is visible to management interfaces.</p>
</li>
<li>
<p>A PAR file can be undeployed and redeployed as a unit.</p>
</li>
<li>
<p>A PAR file is <strong>atomic</strong> in that it ties together the lifecycle of its artifacts. If you start, stop, or uninstall
one of a PAR&#8217;s artifacts, Virgo escalates the operation to the whole PAR file.
So Virgo prevents artifacts of a PAR from being in inconsistent states.
For example, if one artifact should fail to start, then Virgo stops all artifacts in the PAR.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>See <a href="#developing-applications-plans-scoping">Plans and Scoping</a> for more information on scoping.</p>
</div>
<div class="paragraph">
<p>A PAR includes one or more application bundles and its manifest specifies the following
manifest headers:</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-packaging-par-headers-table"></a></p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 1. PAR file headers</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Header</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Application-SymbolicName</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Identifier for the application which, in combination with Application-Version, uniquely identifies an application</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Application-Name</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Human readable name of the application</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Application-Version</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Version of the application</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Application-Description</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Short description of the application</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The following code shows an example MANIFEST.MF in a PAR file:</p>
</div>
<div class="listingblock">
<div class="title">MANIFEST.MF</div>
<div class="content">
<pre class="highlight"><code>Application-SymbolicName: com.example.shop
Application-Version: 1.0
Application-Name: Online Shop
Application-Description: Example.com's Online Shopping Application</code></pre>
</div>
</div>
<div class="paragraph">
<p>anchor:developing-applications-web-application-bundles</p>
</div>
</div>
<div class="sect3">
<h4 id="_web_application_bundles">Web Application Bundles</h4>
<div class="paragraph">
<p>Virgo for Apache Tomcat supports Web Application Bundles that are compliant with the OSGi Web Applications specification.
The defining property of a Bundle that makes it a Web Application Bundle is a manifest header, <code>Web-ContextPath</code>.
This defines the context path the web application will be registered under.</p>
</div>
<div class="paragraph">
<p>See <a href="#using-spring">Using Spring and Gemini Blueprint</a> for information on using Spring or Gemini Blueprint in a Web Application Bundle.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-plans"></a></p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_creating_plans">Creating Plans</h3>
<div class="paragraph">
<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 <strong>parent</strong> plans may refer to other plans, known as <strong>child</strong> plans.</p>
</div>
<div class="paragraph">
<p>Plans share several benefits with PARs:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A plan has a (symbolic) name and a version.</p>
</li>
<li>
<p>A plan may be <strong>scoped</strong>, although this is optional.
See <a href="#developing-applications-plans-scoping">Plans and Scoping</a> for more on scoping.</p>
</li>
<li>
<p>A plan is visible to management interfaces.</p>
</li>
<li>
<p>A plan can be undeployed and redeployed as a unit.</p>
</li>
<li>
<p>A plan may be <strong>atomic</strong>, although this is optional.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Plans have the following additional benefits compared to PARs:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>Plans may contain child plans, but PARs cannot contain other PARs.</p>
</li>
<li>
<p>You can make certain plans deploy faster by disabling the provisioning of bundles to satisfy missing dependencies,
but you cannot disable provisioning for PARs.</p>
</li>
<li>
<p>You can specify whether a plan is scoped or unscoped and atomic or non-atomic; PARs are always scoped and atomic.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The artifacts of a plan are usually stored in Virgo&#8217;s repository. This means, for example, that if you drop one of the plan&#8217;s artifacts in the <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>
</div>
<div class="paragraph">
<p>The artifacts of a plan may also be stored outside Virgo&#8217;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>
<div class="paragraph">
<p><a id="developing-applications-plans-create"></a></p>
</div>
<div class="sect3">
<h4 id="_creating_the_plan_xml_file">Creating the Plan XML File</h4>
<div class="paragraph">
<p>Plans are XML files that have a <code>.plan</code> file extension, such as <code>multi-artifact.plan</code>.
The structure of the XML file is simple:
the root element is <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>&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>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;plan name="multi-artifact.plan" version="1.0.0" scoped="true" atomic="true"
xmlns="http://www.eclipse.org/virgo/schema/plan"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.eclipse.org/virgo/schema/plan
http://www.eclipse.org/virgo/schema/plan/eclipse-virgo-plan.xsd"&gt;
&lt;artifact type="configuration" name="app-properties" version="1.0.0"/&gt;
&lt;artifact type="bundle" name="com.springsource.exciting.app" version="[2.0.0, 3.1.0)"/&gt;
&lt;/plan&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the preceding example, the name of the plan is <code>multi-artifact.plan</code> and its version is <code>1.0.0</code>.
The plan is both scoped and atomic. The plan contains two artifacts: one is a bundle called <code>com.springsource.exciting.app</code> and the other is a configuration file called <code>app-properties</code>.</p>
</div>
<div class="paragraph">
<p>The following table describes the attributes of the <code>&lt;plan&gt;</code> element.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 2. PAR file headers</caption>
<colgroup>
<col style="width: 20%;">
<col style="width: 60%;">
<col style="width: 20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required?</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>name</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the name of this plan.
Virgo uses the name as one component of the unique
identifier of this plan.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>version</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the version of this plan.
You must use OSGi version specification syntax,
such as <code>2.1.0</code>.
Virgo uses the version as one component of
the unique identifier of this plan.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>scoped</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">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>true</code> to enable scoping or
<code>false</code> to disable it.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>atomic</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">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>true</code> to enable atomicity or
<code>false</code> to disable it.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>provisioning</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">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. A value of
<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 <strong>auto-provisioning</strong>.
A value of <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.
A value of <code>inherit</code>, which is the default if no value is specified, inherits the parent plan&#8217;s provisioning behaviour.
If the plan does not have a parent, it inherits Virgo&#8217;s
auto-provisioning behaviour.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No. If not specified, defaults to <code>inherit</code>.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The following table describes the attributes of the <code>&lt;artifact&gt;</code> element. Note that you must either specify <code>type</code>, <code>name</code>, and (optionally) <code>version</code>,
in which case Virgo&#8217;s repository is searched for the artifact, or <code>uri</code> in which case the artifact is obtained directly from the file system.
If you specify <code>uri</code>, you must not specify <code>type</code>, <code>name</code>, or <code>version</code>.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-plans-create-artifact-attributes"></a></p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 3. PAR file headers</caption>
<colgroup>
<col style="width: 20%;">
<col style="width: 60%;">
<col style="width: 20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required?</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>type</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the type of the artifact. Valid values are:
</p><p class="tableblock"><code>bundle</code>: Specifies an OSGi bundle. Use this artifact type for WAR files and Web application bundles.
<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.
<code>plan</code>: Specifies that the artifact is a plan.
<code>par</code>: Specifies that the artifact is a PAR.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, unless <code>uri</code> is specified in which case <code>type</code> must not be specified and is automatically determined from the artifact.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>name</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the name of the artifact.
See <a href="#artifact-names">Artifact Names</a> for guidelines for determining
the name of an artifact.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, unless <code>uri</code> is specified in which case <code>name</code> must not be specified and is automatically determined from the artifact.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>version</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">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>[1.0.0, 2.0.0)</code>.
Note that a single version number represents the range
from that version number upwards.
For example, <code>1.3</code> represents the range of versions
greater than or equal to <code>1.3</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No. If <code>uri</code> is specified, <code>version</code> must not be specified.
If neither <code>uri</code> nor <code>version</code> are specified, <code>version</code> defaults to <code>0</code>, which in OSGi means 0 to infinity, or any version.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>uri</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies an optional, absolute URI string beginning
with <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&#8217;s repository.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No. If not specified, Virgo searches for the artifact in its repository.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p><a id="artifact-names"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_artifact_names">Artifact Names</h4>
<div class="paragraph">
<p>When you create a plan, you use the <code>name</code> attribute of the <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>
</div>
<div class="paragraph">
<p>Use the following guidelines to determine the name of an artifact:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Bundle</strong>: In this context, a <strong>bundle</strong> 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>Bundle-SymbolicName</code> header in the <code>META-INF/MANIFEST.MF</code> file of the <code>*.jar</code>.
If a WAR file has <code>Bundle-SymbolicName</code> header then it will be treated as a Web Application Bundle. The following <code>MANIFEST.MF</code> snippet shows a bundle with name <code>com.springsource.exciting.app</code>:</p>
</li>
</ul>
</div>
<div class="literalblock">
<div class="content">
<pre>Bundle-SymbolicName: org.eclispe.virgo.exciting.app</pre>
</div>
</div>
<div class="paragraph">
<p>If the bundle does not contain a <code>META-INF/MANIFEST.MF</code> file or the <code>MANIFEST.MF</code> doesn&#8217;t contain a <code>Bundle-SymbolicName</code> header, then the name of the bundle is its filename minus the <code>.jar</code> or <code>.war</code> extension.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Configuration File</strong>: The name of a configuration or PID (Persistent Identity) is its filename minus the <code>.properties</code> extension. The PID can also be specified within the properties file with the
<strong>service.pid</strong> property.</p>
</li>
<li>
<p><strong>Plan</strong>: The name of a plan is the value of the required <code>name</code> attribute of the <code>&lt;plan&gt;</code> element in the plan&#8217;s XML file. In the following XML snippet, the plan name is <code>multi-artifact.plan</code>:</p>
</li>
</ul>
</div>
<div class="literalblock">
<div class="content">
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;plan name="multi-artifact.plan" version="1.0.0" scoped="true" atomic="true"
xmlns="http://www.eclipse.org/virgo/schema/plan"&gt;</pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>PAR</strong>: The name of a PAR is the value of the <code>Application-SymbolicName</code> header in the <code>META-INF/MANIFEST.MF</code> file of the <code>*.par</code> file. The following <code>MANIFEST.MF</code> snippet shows a PAR with name <code>com.springsource.my.par</code>:</p>
</li>
</ul>
</div>
<div class="literalblock">
<div class="content">
<pre>Application-SymbolicName: org.eclipse.virgo.my.par</pre>
</div>
</div>
<div class="paragraph">
<p>If the PAR does not contain a <code>META-INF/MANIFEST.MF</code> file, then the name of the PAR is its filename minus the <code>.par</code> extension.</p>
</div>
<div class="paragraph">
<p><a id="passing-properties"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_supplying_properties_to_artifacts">Supplying Properties to Artifacts</h4>
<div class="paragraph">
<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>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&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;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The only supported property is <code>header</code> which will overwrite the given manifest header with the supplied value. This should be used with care!</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-plans-use"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_using_the_plan">Using the Plan</h4>
<div class="paragraph">
<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>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Copy the artifacts that make up the plan to the <code>usr</code> repository, which by default is the <code>$SERVER_HOME/repository/usr</code> directory, where <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 <strong>watched</strong> 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>$SERVER_HOME/pickup</code> directory.</p>
</li>
<li>
<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>$SERVER_HOME/pickup</code> directory.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><a id="developing-applications-plans-scoping"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_plans_and_scoping">Plans and Scoping</h4>
<div class="paragraph">
<p>As described in previous sections, you can specify that a plan be <strong>scoped</strong>. 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>
</div>
<div class="paragraph">
<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>
</div>
<div class="paragraph">
<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>
</div>
<div class="paragraph">
<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>org.eclipse.virgo.service.scope</code> service property set to <code>global</code>. Use the <code>&lt;service-properties&gt;</code> child element of <code>&lt;service&gt;</code>, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;service id="publishIntoGlobal" interface="java.lang.CharSequence"&gt;
&lt;service-properties&gt;
&lt;beans:entry key="org.eclipse.virgo.service.scope" value="global" /&gt;
&lt;/service-properties&gt;
&lt;beans:bean class="java.lang.String"&gt;
&lt;beans:constructor-arg value="foo"/&gt;
&lt;/beans:bean&gt;
&lt;/service&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<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>
</div>
<div class="paragraph">
<p>To ensure predictable class loading behaviour and avoid other issues associated with <strong>split packages</strong> (packages whose classes
are split across more than one bundle), the synthetic context bundle has a restriction:
no package may be exported by more than one
bundle in the scope*.
If this restriction is broken, the scoped application will fail to deploy.
This restriction can cause problems for <a href="#scoping-and-substitutable-exports">substitutable exports</a>.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-plans-scoping-webapps"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_web_applications_and_scoping">Web Applications and Scoping</h4>
<div class="paragraph">
<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>
</div>
<div class="paragraph">
<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 class="paragraph">
<p><a id="developing-applications-configuration-artifacts"></a></p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_creating_and_using_configuration_artifacts">Creating and Using Configuration Artifacts</h3>
<div class="paragraph">
<p>Applications typically include some sort of configuration data
that might change depending on the environment in which the
application is deployed. For example, if an application connects to a
database server using JDBC, the configuration data would include the
JDBC URL of the database server, the JDBC drvier, and the username and
password that the application uses to connect to the database server.
This information often changes as the application is deployed to
different computers or the application moves from the testing phase to
the production phase.</p>
</div>
<div class="paragraph">
<p>Virgo provides a feature called
<strong>configuration artifacts</strong>
that makes it very easy for you to manage this configuration data. A
configuration artifact is simply a properties file that is made
available at runtime using the OSGi
<code>ConfigurationAdmin</code>
service. When you create this properties file, you set the values of
the properties for the specific environment in which you are going to
deploy your application, and then update the metadata of your Spring
application to use the properties file. You then deploy the
application and properties file together, typically as a
<a href="#developing-applications-plans">plan</a>. Virgo automatically creates a configuration artifact from
the properties file, and you can manage the lifecycle of this
configuration artifact in the same way you manage the lifecycle of
PARs, bundles, and plans, using the Admin
Console. Additionally, Virgo subscribes your
application for notification of any refresh of the configuration
artifact and the application can then adapt accordingly, which means
you can easily
<strong>change</strong>
the configuration of your application without redeploying it.</p>
</div>
<div class="paragraph">
<p>In sum, configuration artifacts, especially when combined with
plans, provide an excellent mechanism for managing external
configuration data for your applications.</p>
</div>
<div class="paragraph">
<p>The following sections describe the format of the configuration
artifact, how to update the Spring application context file of your
application so that it knows about the configuration artifact, and
finally how to include it in a plan alongside your application.</p>
</div>
<div class="paragraph">
<p>As an example to illustrate the configuration artifact feature, assume
that you have a Spring bean called
<code>PropertiesController</code>
whose constructor requires that four property values be passed to it,
as shown in the following snippet of Java code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@Controller
public class PropertiesController {
private final String driverClassName;
private final String url;
private final String username;
private final String password;
public PropertiesController(String driverClassName, String url, String username, String password) {
this.driverClassName = driverClassName;
this.url = url;
this.username = username;
this.password = password;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the preceding example, the <code>PropertiesController</code> constructor requires four property values: <code>driverClassName</code>, <code>url</code>, <code>username</code>, and <code>password</code>. Note that the example shows just one way that a class might require property values; your application may code it another way.</p>
</div>
<div class="paragraph">
<p>Additionally, assume that the following snippet of the associated Spring application context XML file shows how the <code>PropertiesController</code> bean is configured:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;bean class="com.springsource.configuration.properties.PropertiesController"&gt;
&lt;constructor-arg value="${driverClassName}"/&gt;
&lt;constructor-arg value="${url}"/&gt;
&lt;constructor-arg value="${username}"/&gt;
&lt;constructor-arg value="${password}"/&gt;
&lt;/bean&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The rest of this section describes how the bean can get these property values using a configuration artifact.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-configuration-artifacts-propfile"></a></p>
</div>
<div class="sect3">
<h4 id="_creating_the_properties_file">Creating the Properties File</h4>
<div class="paragraph">
<p>To create a properties file that in turn will become a configuration artifact when deployed to Virgo from which a Spring bean, such as the <code>PropertiesController</code> bean, will get the actual property values, follow these guidelines:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Create a text file in which each property is listed as a name/value pair, one pair per line. Precede comments with a <code>#</code>. For example:</p>
</li>
</ul>
</div>
<div class="literalblock">
<div class="content">
<pre># Properties for the com.springsource.configuration.properties sample
driverClassName = org.w3.Driver
url = http://www.springsource.com
username = joe
password = secret</pre>
</div>
</div>
<div class="paragraph">
<p>The example shows four properties whose name correspond to the constructor arguments of the <code>PropertiesController</code> Spring bean.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Name the file anything you want, as long as it has a <code>.properties</code> extension, such as <code>app-properties.properties</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><a id="developing-applications-configuration-artifacts-app"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_updating_your_application">Updating Your Application</h4>
<div class="paragraph">
<p>To update your application so that it "knows" about the configuration artifact, you update the application&#8217;s Spring application context XML file, typically located in the <code>WEB-INF</code> or <code>META-INF/spring</code> directories (read <a href="#using-spring">Using Spring and Gemini Blueprint</a>
to understand which directory to use).</p>
</div>
<div class="paragraph">
<p>You use the <code>&lt;context:property-placeholder&gt;</code> element to specify that you want to use the Virgo mechanism for substituting values into bean properties. The <code>properties-ref</code> attribute of this element points to a <code>&lt;osgi-compendium:cm-properties&gt;</code> element which you use to specify the configuration artifact that contains the property values. You set the value of the <code>persistent-id</code> attribute of this element equal to the name of the configuration artifact, which is the name of the properties file <strong>minus</strong> the <code>.properties</code> extension.</p>
</div>
<div class="paragraph">
<p>The following sample Spring application context XMl file shows everything wired together; only relevant parts of the file are shown:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium"
xsi:schemaLocation="http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/osgi-compendium
http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium-1.2.xsd"&gt;
...
&lt;bean class="com.springsource.configuration.properties.PropertiesController"&gt;
&lt;constructor-arg value="${driverClassName}"/&gt;
&lt;constructor-arg value="${url}"/&gt;
&lt;constructor-arg value="${username}"/&gt;
&lt;constructor-arg value="${password}"/&gt;
&lt;/bean&gt;
&lt;context:property-placeholder properties-ref="configAdminProperties"/&gt;
&lt;osgi-compendium:cm-properties id="configAdminProperties" persistent-id="app-properties"/&gt;
...
&lt;/beans&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The preceding example shows how the id <code>configAdminProperites</code> wires the <code>&lt;context:property-placeholder&gt;</code> and <code>&lt;osgi-compendium:cm-properties&gt;</code> elements together. Based on the value of the <code>persistent-id</code> attribute, you must also deploy a properties file called <code>app-properties.properties</code> which Virgo installs as a configuration artifact.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-configuration-artifacts-plan"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_adding_the_configuration_artifact_to_a_plan">Adding the Configuration Artifact to a Plan</h4>
<div class="paragraph">
<p>Although you can always deploy your application and associated configuration artifact using the <code>pickup</code> directory, we recommends that you group the two together in a plan, add the two artifacts to the repository, and then deploy the plan using the <code>pickup</code> directory. The following sample plan includes the two artifacts:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;plan name="multi-artifact.plan" version="1.0.0"
scoped="false" atomic="false"
xmlns="http://www.eclipse.org/virgo/schema/plan"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.eclipse.org/virgo/schema/plan
http://www.eclipse.org/virgo/schema/plan/eclipse-virgo-plan.xsd"&gt;
&lt;artifact type="configuration" name="app-properties" version="0"/&gt;
&lt;artifact type="bundle" name="org.eclipse.virgo.configuration.properties" version="1.0.0"/&gt;
&lt;/plan&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>For additional information about plans, see <a href="#developing-applications-plans">Creating Plans</a>.</p>
</div>
<div class="paragraph">
<p><a id="using-spring"></a></p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_using_spring_and_gemini_blueprint">Using Spring and Gemini Blueprint</h3>
<div class="paragraph">
<p>Virgo supports the use of Spring framework and Gemini Blueprint by application bundles.</p>
</div>
<div class="paragraph">
<p>Spring (and Gemini Blueprint) application context XML files should generally be placed in a bundle&#8217;s <code>META-INF/spring</code> directory, but
for a web application, these files must be placed in the <code>WEB-INF</code> directory.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">
<div class="title">A common mistake</div>
<div class="paragraph">
<p>Placing a web application&#8217;s Spring application context XML files in the <code>META-INF/spring</code> directory produces
unpredictable results since Spring DM will attempt to build an application context independently of, and asynchronously from,
the web application.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To use Gemini Blueprint from a web application, the <code>contextClass</code> servlet parameter and the servlet context listener
should be configured (in <code>WEB-INF/web.xml</code>) like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;context-param&gt;
&lt;param-name&gt;contextClass&lt;/param-name&gt;
&lt;param-value&gt;org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext&lt;/param-value&gt;
&lt;/context-param&gt;
&lt;listener&gt;
&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
&lt;/listener&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Virgo has Gemini Blueprint built-in and thereby supports the OSGi Blueprint standard in addition to Spring DM.</p>
</div>
<div class="paragraph">
<p>For detailed information on Spring Framework and Blueprint, please see <a href="#prerequisites-references">[prerequisites-references]</a>.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-programmatic-access"></a></p>
</div>
</div>
<div class="sect2">
<h3 id="_programmatic_access_to_the_servlet_context">Programmatic Access to the Servlet Context</h3>
<div class="paragraph">
<p>This section describes how to programmatically access the servlet context to obtain the WebApplicationContext or the BundleContext.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-programmatic-access-web"></a></p>
</div>
<div class="sect3">
<h4 id="_programmatic_access_to_web_features">Programmatic Access to Web Features</h4>
<div class="paragraph">
<p><a id="developing-applications-programmatic-access-web-application-context"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_programmatic_access_to_the_webapplicationcontext">Programmatic Access to the WebApplicationContext</h4>
<div class="paragraph">
<p>The Virgo for Apache Tomcat automatically creates a <code>WebApplicationContext</code>
for Web Application Bundles and WAR files. When used in conjunction with an
an auto-configured Spring MVC <code>DispatcherServlet</code>,
there is generally no need to access the <code>WebApplicationContext</code>
programmatically, since all components of the web application are configured
within the scope of the <code>WebApplicationContext</code>
itself. However, if you wish to access the <code>WebApplicationContext</code>
you can do so via the web application&#8217;s <code>ServletContext</code>.
Virgo stores the bundle&#8217;s
<code>WebApplicationContext</code> in the ServletContext under
the attribute name &#8220;BSN-ApplicationContext&#8221;, where
<code>BSN</code> is the <code>Bundle-SymbolicName</code>
of your WAR or Web Application Bundle.</p>
</div>
<div class="paragraph">
<p>Alternatively, since Virgo also stores the
<code>WebApplicationContext</code> under the attribute name
with the value of the <code>WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE</code>
constant, you may choose to use Spring MVC&#8217;s WebApplicationContextUtils'
<code>getWebApplicationContext(servletContext)</code>
or
<code>getRequiredWebApplicationContext(servletContext)</code>
methods to access the <code>WebApplicationContext</code> without providing
an explicit attribute name.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-programmatic-access-web-bundle-context"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_programmatic_access_to_the_bundlecontext">Programmatic Access to the BundleContext</h4>
<div class="paragraph">
<p>As required by the OSGi Web Applications specification, you can access the
<code>BundleContext</code> of your WAR or Web Application Bundle via the web application&#8217;s
<code>ServletContext</code>. The bundle context is stored in the
<code>ServletContext</code> under the attribute name <code>osgi-bundlecontext</code>.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-automatic-imports-web"></a></p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_web_application_manifest_processing">Web Application Manifest Processing</h3>
<div class="paragraph">
<p>Virgo for Apache Tomcat generates automatic package imports (i.e., via the
<code>Import-Package</code> manifest header) for certain web applications.
This section lists which packages are automatically generated.</p>
</div>
<div class="paragraph">
<p>VTS supports Web Application Bundles (WABs) as defined by the OSGi Web Applications Specification and WAR files.
A WAR will typically not contain any OSGi defined manifest headers.
A WAB is distinguished from a WAR by the presence of one or more of the following OSGi defined headers:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Bundle-SymbolicName</code></p>
</li>
<li>
<p><code>Bundle-Version</code></p>
</li>
<li>
<p><code>Bundle-ManifestVersion</code></p>
</li>
<li>
<p><code>Import-Package</code></p>
</li>
<li>
<p><code>Web-ContextPath</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>As required by the OSGi Web Applications specification, the following defaults are applied to a WAR:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Bundle-ManifestVersion</code> is set to <code>2</code></p>
</li>
<li>
<p><code>Bundle-SymbolicName</code> is generated from the path from which the bundle was installed</p>
</li>
<li>
<p><code>Bundle-ClassPath</code> is set to <code>WEB-INF/classes</code> followed by the JARs in
<code>WEB-INF/lib</code> in an unspecified order, followed by any transitive dependencies declared
by the JARs in <code>WEB-INF/lib</code></p>
</li>
<li>
<p><code>Import-Package</code> is extended in an implementation defined way, as described below</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following packages are automatically imported into WARs:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>javax.servlet;version="2.5"</code></p>
</li>
<li>
<p><code>javax.servlet.http;version="2.5"</code></p>
</li>
<li>
<p><code>javax.servlet.jsp;version="2.1"</code></p>
</li>
<li>
<p><code>javax.servlet.jsp.el;version="2.1"</code></p>
</li>
<li>
<p><code>javax.servlet.jsp.tagext;version="2.1"</code></p>
</li>
<li>
<p><code>javax.el;version="1.0"</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In addition to the above-described imports, VTS will also
generate automatic imports for all of the packages that are exported by the system
bundle, unless an import for the package already exists in the WAR&#8217;s manifest,
or the WAR contains the package, i.e. within <code>WEB-INF/classes</code>,
or in a jar file in <code>WEB-INF/lib</code>. When an import is generated, it
is versioned such that it exactly matches the version or versions of the package that
are exported from the system bundle. For example, a package that&#8217;s exported only at
version <code>1.0.0</code> will generate an import with a version of
<code>[1.0.0,1.0.0]</code>, and a package that&#8217;s exported at version
<code>1.0.0</code> and version <code>2.0.0</code> will generate an import
with a version of <code>[1.0.0,2.0.0]</code>.</p>
</div>
<div class="paragraph">
<p>Web Application Bundles are not subject to the above manifest processing.
This is a change of behaviour compared to Virgo Web Server 2.1.x.
See (see <a href="#known-issues-web-bundle-default-headers">Default Web
Application Bundle Headers</a>) if you need the old behaviour until you
have changed your WABs to match the new behaviour.</p>
</div>
<div class="paragraph">
<p>VTS supports ROOT.war as a default web application. The <code>Web-ContextPath</code>
of the deployed ROOT.war is set to the default web context path - <code>/</code>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">
<div class="title">System Bundle Package Exports</div>
<div class="paragraph">
<p>For further details on which packages are exported by the
OSGi system bundle, consult the &lt;filename&gt;java-server.profile&lt;/filename&gt;
file located in the <code>SERVER_HOME/configuration</code> directory.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p><a id="developing-applications-dependencies"></a></p>
</div>
</div>
<div class="sect2">
<h3 id="_working_with_dependencies">Working with Dependencies</h3>
<div class="paragraph">
<p>Complex enterprise frameworks such a Spring and Hibernate are typically divided into many, many different
packages. Traditionally, if an OSGi bundle wished to make extensive use of such a framework its manifest would
have to import a huge number of different packages. This can be an error-prone and tedious process. Furthermore,
application developers are used to thinking in terms of their application using a framework, such as Spring, as a
whole, rather than a long list of all the different packages that comprise the framework.</p>
</div>
<div class="paragraph">
<p>The following figure provides a simple illustration of the complexity of only using <code>Import-Package</code>:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="assets/images/import-package.png" alt="import package"></span></p>
</div>
<div class="paragraph">
<p>Virgo reduces the need for long lists of imported packages by introducing two new manifest
headers; <code>Import-Bundle</code> and <code>Import-Library</code>. The following figure provides an
illustration of the simplification that these new headers offer:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="assets/images/import-bundle_import-library.png" alt="import bundle import library"></span></p>
</div>
<div class="paragraph">
<p>As you can see, use of <code>Import-Bundle</code> and <code>Import-Library</code> can lead to a dramatic reduction
in the number of imports that you need to include in an application bundle&#8217;s manifest. Furthermore, <code>Import-Bundle</code>
and <code>Import-Library</code> are simply aliases for <code>Import-Package</code>; at deployment time <code>Import-Bundle</code>
and <code>Import-Library</code> header entries are automatically expanded into numerous <code>Import-Package</code> entries. This
means that you retain the exact same semantics of using <code>Import-Package</code>, without having to go through the labourious
process of doing so.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-importing-libraries"></a></p>
</div>
<div class="sect3">
<h4 id="_importing_libraries">Importing Libraries</h4>
<div class="paragraph">
<p>A bundle in an application can declare a dependency on a library by using the
Eclipse Virgo specific <code>Import-Library</code> header. This header specifies a
comma-separated list of library symbolic names and version ranges that determine which libraries
are imported. By default a dependency on a library is mandatory but this can be
controlled through use of the resolution directive in exactly the same way as
it can with <code>Import-Package</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-txt" data-lang="txt">Import-Library: org.springframework.spring;version="[2.5.4, 3.0)",
org.aspectj;version="[1.6.0,1.6.0]";resolution:="optional"</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example <code>Import-Library</code> header declares a mandatory dependency on the Spring
library at a version from 2.5.4 inclusive to 3.0 exclusive. It also declares an
optional dependency on the AspectJ library at exactly 1.6.0.</p>
</div>
<div class="paragraph">
<p>anchor:developing-applications-importing-bundles</p>
</div>
</div>
<div class="sect3">
<h4 id="_importing_bundles">Importing Bundles</h4>
<div class="paragraph">
<p>A bundle in an application can declare a dependency on a bundle by using the
Eclipse Virgo specific <code>Import-Bundle</code> header. The header specifies a comma-separated
list of bundle symbolic names, version ranges, and scope declarmations that determine which bundles are imported and the scope of their dependency. By default a dependency
on a bundle is mandatory but this can be controlled through use of the resolution directive in exactly
the same way as it can with <code>Import-Package</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-txt" data-lang="txt">Import-Bundle: com.springsource.org.apache.commons.dbcp;version="[1.2.2.osgi, 1.2.2.osgi]"</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example <code>Import-Bundle</code> header declares a mandatory dependency on the Apache Commons
DBCP bundle at exactly 1.2.2.osgi.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-importing-bundles-disadvantages"></a></p>
</div>
<div class="sect4">
<h5 id="_disadvantages">Disadvantages</h5>
<div class="paragraph">
<p>A disadvantage of using <code>Import-Bundle</code> or especially <code>Import-Library</code>, is that the application
bundle has a greater apparent fan-out than it strictly needs. An Alternative is to use a tool such as bnd or Bundlor
to generate the package imports of the bundle.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-scoping-libraries-bundles"></a></p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_scoping_bundles_in_an_application">Scoping Bundles in an Application</h4>
<div class="paragraph">
<p>When working with a scoped application, such as a PAR file or a plan, you might run into a situation where one of the bundles in the application (call it <code>bundleA</code>) depends on another bundle (<code>bundleB</code>) that performs a runtime task (such as class generation) that a third bundle (<code>bundleC</code>) might need to know about, although <code>bundleC</code> does not explicitly depend on <code>bundleB</code>.</p>
</div>
<div class="paragraph">
<p>For example, Hibernate uses CGLIB (code generation library) at runtime to generate proxies for persistent classes. Assume that a domain bundle in your application uses Hibernate for its persistent objects, and thus its <code>Import-Bundle</code> manifest header includes the Hibernate bundle. Further assume that a separate Web bundle uses reflection in its data-binding code, and thus needs to reflect on the persistent classes generated by Hibernate at runtime. The Web bundle now has an indirect dependency on the Hibernate bundle because of these dynamically generated classes, although the Web bundle does not typically care about the details of how these classes are persisted. One way to solve this dependency problem is to explicitly add the Hibernate bundle to the <code>Import-Bundle</code> header of the Web bundle; however, this type of explicit-specified dependency breaks the modularity of the application and is not a programming best practice.</p>
</div>
<div class="paragraph">
<p>A better way to solve this problem is to specify that Virgo itself dynamically import
the bundle (Hibernate in the example above) to all bundles in the application at runtime.
You do this by adding the <code>import-scope:=application</code> directive to the <code>Import-Bundle</code> header
of the bundle that has the direct dependency (the domain bundle in our example). At runtime, although the Web bundle
does not explicitly import the Hibernate bundle, Virgo implicitly imports it and thus its classes are available
to the Web bundle. This mechanism allows you to declare the dependencies you need to make your application run,
without having to make changes to your application that might limit its flexibility.</p>
</div>
<div class="paragraph">
<p>The following example shows how to use the <code>import-scope</code> directive with the <code>Import-Bundle</code> header:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-txt" data-lang="txt">Import-Bundle: com.springsource.org.hibernate;version="[3.2.6.ga,3.2.6.ga]";import-scope:=application</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also set the <code>import-scope</code> directive to the (default) value <code>bundle</code>; in this case, the scope of the bundle is just the bundle itself and thus Virgo does not perform any implicit importing into other bundles of the application.</p>
</div>
<div class="paragraph">
<p>Note that use of the <code>import-scope:=application</code> directive of the <code>Import-Bundle</code> header only makes sense when the bundle is part of a scoped application (PAR or plan); if the bundle is not part of a scoped application, then this directive has no effect.</p>
</div>
<div class="paragraph">
<p>Finally, because <code>import-scope:=application</code> implicitly adds a bundle import to each bundle of the PAR or plan, the impact of subsequently refreshing the imported bundle is, in general, broader than it would have been if you had not used <code>import-scope:=application</code>. This may well affect the performance of refresh.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-defining-libraries"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_defining_libraries">Defining Libraries</h4>
<div class="paragraph">
<p>Libraries are defined in a simple text file, typically with a <code>.libd</code> suffix. This file identifies the
library and lists all of its constituent bundles. For example, the following is the library definition for
Spring 2.5.4:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-txt" data-lang="txt">Library-SymbolicName: org.springframework.spring
Library-Version: 2.5.4
Library-Name: Spring Framework
Import-Bundle: org.springframework.core;version="[2.5.4,2.5.5)",
org.springframework.beans;version="[2.5.4,2.5.5)",
org.springframework.context;version="[2.5.4,2.5.5)",
org.springframework.aop;version="[2.5.4,2.5.5)",
org.springframework.web;version="[2.5.4,2.5.5)",
org.springframework.web.servlet;version="[2.5.4,2.5.5)",
org.springframework.jdbc;version="[2.5.4,2.5.5)",
org.springframework.orm;version="[2.5.4,2.5.5)",
org.springframework.transaction;version="[2.5.4,2.5.5)",
org.springframework.context.support;version="[2.5.4,2.5.5)",
org.springframework.aspects;version="[2.5.4,2.5.5)",
com.springsource.org.aopalliance;version="1.0"</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following table lists all of the headers that may be used in a library definition:</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-defining-libraries-library-headers-table"></a></p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 4. Library definition headers</caption>
<colgroup>
<col style="width: 28%;">
<col style="width: 71%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Header</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Library-SymbolicName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Identifier for the library</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Library-Version</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Version number for the library</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Import-Bundle</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A comma separated list of bundle symbolic names.
Each entry may optionally specify a version (using the <code>version=</code> directive)
and the scope of the import (using the <code>import-scope</code> directive).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Library-Name</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Optional. The human-readable name of the library</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Library-Description</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Optional. A human-readable description of the library</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p><a id="developing-applications-installing-dependencies"></a></p>
</div>
</div>
<div class="sect3">
<h4 id="_installing_dependencies">Installing Dependencies</h4>
<div class="paragraph">
<p>Rather than encouraging the packaging of all an application&#8217;s dependencies within the application itself, Virgo
uses a local provisioning repository of bundles and libraries upon which an application can depend. When the Virgo
encounters an application with a particular dependency, it will automatically provide, from its provisioning repository,
the appropriate bundle or library.</p>
</div>
<div class="paragraph">
<p>Making a dependency available for provisioning is simply a matter of copying it to the appropriate location in the
Virgo&#8217;s local provisioning repository. By default this is
<code>SERVER_HOME/repository/usr</code>. A more detailed discussion of the provisioning
repository can be found in the <a href="http://www.eclipse.org/virgo/documentation/virgo-documentation-3.7.0.RELEASE/docs/virgo-user-guide/html/index.html">User Guide</a>.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-application-trace"></a></p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_application_trace">Application Trace</h3>
<div class="paragraph">
<p>As described in the <a href="http://www.eclipse.org/virgo/documentation/virgo-documentation-3.7.0.RELEASE/docs/virgo-user-guide/html/index.html">User Guide</a> Virgo provides support for
per-application trace for PARs, scoped Plans and WABs. Virgo provides SLF4J with Logback logging for Event Logging and Tracing.
Application trace is configured in the <code>serviceability.xml</code> file.
See the <a href="http://www.eclipse.org/virgo/documentation/virgo-documentation-3.7.0.RELEASE/docs/virgo-user-guide/html/index.html">User Guide</a> for more details.</p>
</div>
<div class="paragraph">
<p><a id="developing-applications-versioning"></a></p>
</div>
</div>
<div class="sect2">
<h3 id="_application_versioning">Application Versioning</h3>
<div class="paragraph">
<p>In much the same way that individual OSGi bundles can be versioned, Virgo allows applications to be versioned. How exactly you do this depends on how you have packaged the application:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If you package your application using a PAR, you version the application by using the <code>Application-Version</code> header in the <code>MANIFEST.MF</code> file of the PAR file.</p>
</li>
<li>
<p>If you use a plan to describe the artifacts that make up your application, you version it by using the <code>version</code> attribute of the <code>&lt;plan&gt;</code> root element of the plan&#8217;s XML file.</p>
</li>
<li>
<p>If your application consists of a single bundle, you version it in the standard OSGi way: by using the <code>Bundle-Version</code> header of the <code>MANIFEST.MF</code> file of the bundle.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Virgo uses an application&#8217;s version to prevent clashes when multiple versions of the same application are deployed at
the same time. For example, the application trace support described in <a href="#developing-applications-application-trace">Application Trace</a>,
includes the application&#8217;s name and version in the file path. This ensures that each version of the same application has its
own trace or logging file.</p>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2017-02-23 21:06:51 +01:00
</div>
</div>
</body>
</html>