summaryrefslogtreecommitdiffstats
path: root/site/trunk/site-publish/documentation-2x/classloading.html
blob: aa51c9626522ced2e8a9d6c2084f31acabe33bc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
    <HEAD>
           <META name="description" content="Apache Tuscany">
   <META name="keywords" content="apache, apache tuscany, tuscany, service, services, fabric, soa, service oriented architecture,  sca, service component architecture, das, sdo, csa, ruby, opensource">

        <LINK type="text/css" rel="stylesheet" href="http://tuscany.apache.org/stylesheets/default.css">
        <LINK rel="SHORTCUT ICON" href="https://cwiki.apache.org/confluence/display/TUSCANYxDOCx2x/$images/favicon.ico">   
        <TITLE>Classloading : Apache Tuscany</TITLE>
    <META http-equiv="Content-Type" content="text/html;charset=UTF-8"></HEAD>

   <STYLE>
    .spacetree * ul {
       padding-left:0px;
       margin-left: 0px;
    }
    .spacetree * li {
       margin-left: 5px;
       padding-left:5px;
    }
   </STYLE>

    <BODY onload="init()">
            <!-- topNav -->
    <TABLE border="0" cellpadding="2" cellspacing="0" width="100%">
      <TR class="topBar">
        <TD align="left" valign="middle" class="topBarDiv" align="left" nowrap="">
          <A href="https://cwiki.apache.org/geronimo"> Home</A> &gt;&nbsp;<A href="index.html" title="Apache Tuscany Docs 2.x">Apache Tuscany Docs 2.x</A>&nbsp;&gt;&nbsp;<A href="index.html" title="Index">Index</A>&nbsp;&gt;&nbsp;<A href="development-guides.html" title="Development Guides">Development Guides</A>&nbsp;&gt;&nbsp;<A href="sca-java-runtime-overview.html" title="SCA Java Runtime Overview">SCA Java Runtime Overview</A>&nbsp;&gt;&nbsp;<A href="" title="Classloading">Classloading</A>
        </TD>
        <TD align="right" valign="middle" nowrap="">
          <FORM name="search" action="http://www.google.com/search" method="get">
            <INPUT type="hidden" name="ie" value="UTF-8">
            <INPUT type="hidden" name="oe" value="UTF-8">
            <INPUT type="hidden" name="domains" value="">
            <INPUT type="hidden" name="sitesearch" value="">
            <INPUT type="text" name="q" maxlength="255" value="">        
            <INPUT type="submit" name="btnG" value="Google Search">
          </FORM>
        </TD>
      </TR> 
    </TABLE>

        
    <TABLE border="0" cellpadding="2" cellspacing="0" width="100%">
        <TR class="topBar">
            <TD align="left" valign="middle" class="topBarDiv" nowrap="true" width="100%">
                &nbsp;<A href="index.html" title="Apache Tuscany Docs 2.x">Apache Tuscany Docs 2.x</A>&nbsp;&gt;&nbsp;<A href="index.html" title="Index">Index</A>&nbsp;&gt;&nbsp;<A href="development-guides.html" title="Development Guides">Development Guides</A>&nbsp;&gt;&nbsp;<A href="sca-java-runtime-overview.html" title="SCA Java Runtime Overview">SCA Java Runtime Overview</A>&nbsp;&gt;&nbsp;<A href="" title="Classloading">Classloading</A>
            </TD>

            <TD align="right" valign="middle" class="topBarDiv" align="left" nowrap="true">
            <A href="http://tuscany.apache.org/">Tuscany Home</A> | <A href="http://mail-archives.apache.org/mod_mbox/tuscany-user">User List</A> | <A href="http://mail-archives.apache.org/mod_mbox/tuscany-dev">Dev List</A> | <A href="http://issues.apache.org/jira/browse/Tuscany">Issue Tracker</A>&nbsp;&nbsp;
            </TD>
        </TR>
    </TABLE>

        <TABLE border="0" cellpadding="0" width="100%" bgcolor="#FFFFFF">
            <TR>
                <TD valign="top" align="left" width="22%" bgcolor="#F9F9F9" class="noprint">
                        <DIV class="tabletitle">Table of Contents</DIV>
        <DIV class="spacetree">
            
            
            </DIV>
                </TD>
                <TD align="left" valign="top" width="78%">
                        <!-- pageContent -->
    <DIV id="PageContent">
      <DIV class="pageheader" style="padding: 6px 0px 0px 0px;">
        <!-- We'll enable this once we figure out how to access (and save) the logo resource -->
        <!--img src="http://geronimo.apache.org/images/confluence_logo.gif" style="float: left; margin: 4px 4px 4px 10px;" border="0"-->
        <DIV style="margin: 0px 10px 0px 10px" class="smalltext">Apache Tuscany Docs 2.x</DIV>
        <DIV style="margin: 0px 10px 8px 10px" class="pagetitle">Classloading</DIV>

        <DIV class="greynavbar" align="right" style="padding: 2px 10px; margin: 0px;">
<!-- -->         
            <A href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=20644728">
            <IMG src="http://geronimo.apache.org/images/icons/notep_16.gif" height="16" width="16" border="0" align="absmiddle" title="Edit Page"></A>
            <A href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=20644728">Edit Page</A>
          &nbsp;
          <A href="https://cwiki.apache.org/confluence/pages/listpages.action?key=TUSCANYxDOCx2x">
            <IMG src="http://geronimo.apache.org/images/icons/browse_space.gif" height="16" width="16" border="0" align="absmiddle" title="Browse Space"></A>
            <A href="https://cwiki.apache.org/confluence/pages/listpages.action?key=TUSCANYxDOCx2x">Browse Space</A>
          &nbsp;
          <A href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=TUSCANYxDOCx2x&fromPageId=20644728">
            <IMG src="http://geronimo.apache.org/images/icons/add_page_16.gif" height="16" width="16" border="0" align="absmiddle" title="Add Page"></A>
          <A href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=TUSCANYxDOCx2x&fromPageId=20644728">Add Page</A>
          &nbsp;
          <A href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=TUSCANYxDOCx2x&fromPageId=20644728">
            <IMG src="http://geronimo.apache.org/images/icons/add_blogentry_16.gif" height="16" width="16" border="0" align="absmiddle" title="Add News"></A>
          <A href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=TUSCANYxDOCx2x&fromPageId=20644728">Add News</A>
<!-- -->	 
        </DIV>
      </DIV>

      <DIV class="pagecontent">
        <DIV class="wiki-content">
          <P>Need to detail the various ways the Tuscany runtime loads classes and the issues involved. Here are some notes to kick of this document</P>

<H1><A name="Classloading-ClassloadingObjectives"></A>Classloading Objectives</H1>

<P>The runtime must work in both OSGi and non-OSGI environments. I.e. we can't rely on the OSGi service registry for extensibility<BR>
The runtime must not be generally environment specific. I.e. no buddy classloading<BR>
...</P>

<H1><A name="Classloading-GeneralPatterns"></A>General Patterns</H1>

<H2><A name="Classloading-ExtensionloadingJSE"></A>Extension loading - JSE</H2>

<P>tuscany-extensibility<BR>
Tuscany finds extensions by looking for META-INF/services files on the classpath.</P>

<H2><A name="Classloading-ExtensionloadingOSGi"></A>Extension loading - OSGi</H2>

<P>tuscany-extensibility-equinox<BR>
It's a bit more complicated here. The extensibility-equinox bundle is given the entire OSGi context at start up and from there is looks in all of the loaded bundles looking for META-INF/services files. It caches them against the bundle in which they are found.</P>

<P>The tuscany-extensibility-equinox bundle also has a dynamic import</P>

<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">
DynamicImport-Package: org.apache.tuscany.sca.extensibility.equinox,
 javax.transaction;version=<SPAN class="code-quote">&quot;1.1&quot;</SPAN>,
 javax.transaction.xa;version=<SPAN class="code-quote">&quot;1.1&quot;</SPAN>,
</PRE>
</DIV></DIV>

<P>Which allows it to generally load any classes in the runtime</P>

<H2><A name="Classloading-SplitPackagesJSE"></A>Split Packages - JSE</H2>

<P>We don't take any special account of this in JSE <IMG class="emoticon" src="https://cwiki.apache.org/confluence/images/icons/emoticons/help_16.gif" height="16" width="16" align="absmiddle" alt="" border="0"><BR>
We avoid split packages across the JARs we create as it messes OSGi up.</P>

<H2><A name="Classloading-SplitPackagesOSGI"></A>Split Packages - OSGI</H2>

<P>We avoid split packages across the bundles we create<BR>
They may exist in third party bundles (or jars that we turn into bundles) so we need a way round it</P>

<P>The Tuscany eclipse plugin is used to generate bundles manifest for jars which don't have them. This is done automatically with all packages exported <IMG class="emoticon" src="https://cwiki.apache.org/confluence/images/icons/emoticons/help_16.gif" height="16" width="16" align="absmiddle" alt="" border="0"> and the resulting bundle it in the distribution modules directory in the following form</P>

<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">
bundle-name
  META-INF
     MANIFEST.MF
  bundle-name.jar
</PRE>
</DIV></DIV>

<P>The MANIFEST.MF is generated and will have a bundle classpath pointing to the jar (which doesn't itself have a manifest</P>

<P>The runtime (node-launcher-equinox) has code to load these directories as bundles.</P>

<P>There is a way of overriding these automatically generated bundles so that split packages (or any other manifest problems) can be worked round. Generate the manifest manually and put it in</P>

<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">
distribution/all/manifests
</PRE>
</DIV></DIV>

<P>Update distribution/pom.xml to configure the Tuscany version of the maven bundle plugin to apply this manifest</P>

<DIV class="preformatted panel" style="border-width: 1px;"><DIV class="preformattedContent panelContent">
<PRE>            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.tuscany.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-bundle-plugin&lt;/artifactId&gt;
                &lt;version&gt;1.0.6&lt;/version&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;id&gt;distribution-modules&lt;/id&gt;
                        &lt;phase&gt;generate-resources&lt;/phase&gt;
                        &lt;goals&gt;
                             &lt;goal&gt;generate-modules&lt;/goal&gt;
                        &lt;/goals&gt;
                        &lt;configuration&gt;
                             &lt;targetDirectory&gt;target/modules&lt;/targetDirectory&gt;
                             &lt;useDistributionName&gt;${useDistributionName}&lt;/useDistributionName&gt;
                             &lt;generateAggregatedBundle&gt;${generateAggregatedBundle}&lt;/generateAggregatedBundle&gt;
                             &lt;generateManifestJar&gt;true&lt;/generateManifestJar&gt;
                             &lt;artifactManifests&gt;
                                 &lt;artifactManifest&gt;
                                     &lt;groupId&gt;org.apache.ws.commons.axiom&lt;/groupId&gt;
                                     &lt;artifactId&gt;axiom-api&lt;/artifactId&gt;
                                     &lt;version&gt;1.2.8&lt;/version&gt;
                                     &lt;manifestFile&gt;${basedir}/manifests/axiom-api-1.2.8.MF&lt;/manifestFile&gt;
                                 &lt;/artifactManifest&gt;
                                 &lt;artifactManifest&gt;
                                     &lt;groupId&gt;org.apache.woden&lt;/groupId&gt;
                                     &lt;artifactId&gt;woden-impl-dom&lt;/artifactId&gt;
                                     &lt;version&gt;1.0M8&lt;/version&gt;
                                     &lt;manifestFile&gt;${basedir}/manifests/woden-impl-dom-1.0M8.MF&lt;/manifestFile&gt;
                                 &lt;/artifactManifest&gt;
                                 &lt;!--artifactManifest&gt;
                                     &lt;groupId&gt;org.apache.tuscany.sdo&lt;/groupId&gt;
                                     &lt;artifactId&gt;tuscany-sdo-api-r2.1&lt;/artifactId&gt;
                                     &lt;version&gt;1.1.1&lt;/version&gt;
                                     &lt;manifestFile&gt;${basedir}/manifests/tuscany-sdo-api-r2.1-1.1.1.MF&lt;/manifestFile&gt;
                                 &lt;/artifactManifest--&gt;
                                 &lt;!-- artifactAggregations (below) is the right approach to solving the split
                                      package between axis-kernel and axis2-transport-http however the Tuscany
                                      runtime doesn't take any notice of it so using a fragment at the moment --&gt;
                                 &lt;artifactManifest&gt;
                                     &lt;groupId&gt;org.apache.axis2&lt;/groupId&gt;
                                     &lt;artifactId&gt;axis2-kernel&lt;/artifactId&gt;
                                     &lt;version&gt;1.5.1&lt;/version&gt;
                                     &lt;manifestFile&gt;${basedir}/manifests/axis2-kernel-1.5.1.MF&lt;/manifestFile&gt;
                                 &lt;/artifactManifest&gt;
                                 &lt;artifactManifest&gt;
                                     &lt;groupId&gt;org.apache.axis2&lt;/groupId&gt;
                                     &lt;artifactId&gt;axis2-transport-http&lt;/artifactId&gt;
                                     &lt;version&gt;1.5.1&lt;/version&gt;
                                     &lt;manifestFile&gt;${basedir}/manifests/axis2-transport-http-1.5.1.MF&lt;/manifestFile&gt;
                                 &lt;/artifactManifest&gt;
                                 &lt;artifactManifest&gt;
                                     &lt;groupId&gt;org.apache.axis2&lt;/groupId&gt;
                                     &lt;artifactId&gt;*&lt;/artifactId&gt;
                                     &lt;version&gt;*&lt;/version&gt;
                                 &lt;/artifactManifest&gt;
                             &lt;/artifactManifests&gt;
                             &lt;!--artifactAggregations&gt;
                                  &lt;artifactAggregation&gt;
                                      &lt;symbolicName&gt;org.apache.tuscany.sca.axis2-kernel&lt;/symbolicName&gt;
                                      &lt;version&gt;1.5.1&lt;/version&gt;
                                      &lt;artifactMembers&gt;
                                          &lt;artifactMember&gt;
                                              &lt;groupId&gt;org.apache.axis2&lt;/groupId&gt;
                                              &lt;artifactId&gt;axis2-kernel&lt;/artifactId&gt;
                                              &lt;version&gt;1.5.1&lt;/version&gt;
                                          &lt;/artifactMember&gt;
                                          &lt;artifactMember&gt;
                                              &lt;groupId&gt;org.apache.axis2&lt;/groupId&gt;
                                              &lt;artifactId&gt;axis2-transport-http&lt;/artifactId&gt;
                                              &lt;version&gt;1.5.1&lt;/version&gt;
                                          &lt;/artifactMember&gt;
                                      &lt;/artifactMembers&gt;
                                  &lt;/artifactAggregation&gt;
                              &lt;/artifactAggregations--&gt;
                        &lt;/configuration&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
                &lt;dependencies&gt;
                   &lt;dependency&gt;
                      &lt;groupId&gt;org.eclipse&lt;/groupId&gt;
                      &lt;artifactId&gt;osgi&lt;/artifactId&gt;
                      &lt;version&gt;3.3.0-v20070530&lt;/version&gt;
                   &lt;/dependency&gt;
                &lt;/dependencies&gt;
            &lt;/plugin&gt;
</PRE>
</DIV></DIV>

<P>You'll note that there is an artifact aggregation element that doesn't work at the moment. This should aggregate the two bundles together so that a split package isn't an issue. As this doesn't work at the moment another way to achieve the same result is to make one package a fragement of the other by configuring separate manifests manually.</P>

<P>NOTE&#33;&#33;&#33;&#33;&#33; you also need to put the manually generated manifest in node-launcher-equinox\src\main\resources\org\apache\tuscany\sca\node\equinox\launcher otherwise you'll spend a lot of time trying to get this to work. (we need to fix this&#33;)</P>

<H2><A name="Classloading-ThirdpartylibrariesJSE"></A>Third-party libraries - JSE</H2>

<P>TBD</P>

<H2><A name="Classloading-ThirdpartylibrariesOSGI"></A>Third-party libraries - OSGI</H2>

<P>Third-party libraries often rely on TCCL to load implementation classes in an extensible way. For example, the SDO API loads the HelperContext implementation in this way. In an OSGi environment there will not be a static dependency between the api bundle and the impl bundle so we need to fake it. Typically we do this by setting up the TCCL appropriately before the library us called.</P>

<P>See ClassLoaderContext which help us to set up a multi-classloader configurations.</P>

<P>Typically in OSGi one of the classloaders we pass in here will be the extensibiliy-equinox bundle classloader (the ServiceDiscoverer) as this bundles has a dynamic import which allows it to load any class in the runtime.</P>


<H2><A name="Classloading-TuscanyNodeAPIJSE"></A>Tuscany Node API - JSE</H2>

<P>TBD</P>

<H2><A name="Classloading-TuscanyNodeAPIOSGi"></A>Tuscany Node API - OSGi</H2>

<P>There are a small number of Tuscany Jars you need to use in the app launcher in the OSGi environment</P>

<P>tuscany-sca-api<BR>
tuscany-node-api<BR>
tuscany-node-launcher-equinox</P>

<P>The node API has to load the node implementation and has a dynamic import in its manifest</P>

<P>DynamicImport-Package: org.apache.tuscany.sca.node.impl,org.apache.tuscany.sca.extensibility</P>



<H2><A name="Classloading-SCAClientAPIJSE"></A>SCA Client API - JSE</H2>

<P>Factory finder impl is injected into the API class by the implementation</P>

<H2><A name="Classloading-SCAClientAPIOSGi"></A>SCA Client API - OSGi</H2>

<P>NodeFactory maintains a NodeProxy inner class that supports cross-classloader calls. The calling client api will have been loaded by the app classloader but the underlying node will have been loaded by a bundle classloader. We need to bridge that gap.</P>

<H2><A name="Classloading-%23ContributionClassLoading"></A><A href="#Classloading-Contribution">Contribution</A> Class Loading </H2>

<P>When a contribution is read, containing an implementation.java element, a ClassReference is instantiated, which contains the name of the class. ClassReference instances are resolved by a ClassLoaderModelResolver, by virtue of the entry in&nbsp;[2]</P>

<P>The ClassLoaderModelResolver (CLMR) specializes java.net.URL.URLClassLoader and implements o.a.t.s....ModelResolver. Each contribution is associated with a single CLMR . On construction the CLMR is endowed with a set of URLs that allow it to find all classes in its contribution via the URLClassLoader behaviour.</P>

<P>The itest project <EM>import-export-tests</EM> has a class TestTestCase with method testOneNode which demonstrates a&nbsp;more complex scenario&nbsp;where a cross contribution import/export of a java package exists between the contributions. &nbsp;In this example a node is created using 2 composite URIs for contributions ... &quot;../exports/target/classes&quot;, &quot;../imports/target/classes&quot;. An imported class is resolved using the CLMR of the exporting contribution. &nbsp;The exporter's CLMR is made available to the importing CLMR by deployment [1] code which traverses all contributions, identifying cross contribution dependencies (see buildDependencies at [1])&nbsp;&nbsp;and using the set of remaining contributions to resolve the import, potentially more than once.</P>

<P>[<A href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=TUSCANYxDOCx2x&title=1&linkCreation=true&fromPageId=20644728" class="createlink">1</A>]&nbsp;<A href="http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java?view=markup&pathrev=948564" class="external-link" rel="nofollow">http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java?view=markup&amp;pathrev=948564</A>&#124;http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java?view=markup&amp;pathrev=948564]</P>

<P>[2]&nbsp;<A href="http://svn.apache.org/repos/asf/tuscany/sca-java-2.x/trunk/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver" class="external-link" rel="nofollow">http://svn.apache.org/repos/asf/tuscany/sca-java-2.x/trunk/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver</A></P>

        </DIV>

              </DIV>
    </DIV>
                </TD>
            </TR>
        </TABLE>

            <!-- footer -->
    <TABLE border="0" cellpadding="2" cellspacing="0" width="100%">
        <TR>
          <TD align="left" valign="middle" class="footer">
            &nbsp;&nbsp;
            <IMG src="http://static.delicious.com/img/delicious.small.gif" height="10" width="10" alt="Delicious">
            <A href="http://delicious.com/save" onclick="window.open('http://delicious.com/save?v=5&noui&jump=close&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title),'delicious','toolbar=no,width=550,height=550'); return false;">Bookmark this on Delicious</A>
            &nbsp;&nbsp;
            <IMG src="http://digg.com/img/badges/16x16-digg-guy.gif" width="16" height="16" alt="Digg!">
            <A href="" onclick="window.open('http://digg.com/submit?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)+'&topic=programming');">Digg this</A>
            <!-- Slicker, but no text
            <script type="text/javascript">
              digg_skin = 'icon';
              digg_window = 'new';
              digg_title = 'Apache Geronimo v2.2 Documentation : Classloading';
              digg_topic = 'programming';
            </script>
            <script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script>
            -->
            &nbsp;&nbsp;
          </TD>
          <TD align="right" valign="middle" class="footer">
            <A href="http://cwiki.apache.org/GMOxPMGT/geronimo-privacy-policy.html">Privacy Policy</A>&nbsp;&nbsp;-&nbsp;&nbsp;
            Copyright &copy; 2003-2010, The Apache Software Foundation, Licensed under <A href="http://www.apache.org/licenses/LICENSE-2.0">ASL 2.0.</A>&nbsp;&nbsp;
          </TD>
        </TR>
    </TABLE> 

    </BODY>
</HTML>