blob: 6247effe0bd1499a4ac38d9d11f7d809fa1a81f1 [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>4.6&nbsp;Referencing an OSGi Service</title><link rel="stylesheet" href="css/stylesheet.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"><link rel="home" href="index.html" title="Creating an application with EclipseRT Virgo Web Server"><link rel="up" href="ch04.html" title="4.&nbsp;The Web Module"><link rel="prev" href="ch04s05.html" title="4.5&nbsp;Creating a PAR"><link rel="next" href="ch04s07.html" title="4.7&nbsp;Publishing an OSGi Service"><!--Begin Google Analytics code--><script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script><script type="text/javascript">
var pageTracker = _gat._getTracker("UA-2728886-3");
pageTracker._setDomainName("none");
pageTracker._setAllowLinker(true);
pageTracker._trackPageview();
</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">4.6&nbsp;Referencing an OSGi Service</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch04s05.html">Prev</a>&nbsp;</td><th width="60%" align="center">4.&nbsp;The Web Module</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="ch04s07.html">Next</a></td></tr></table><hr></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="osgi.reference"></a>4.6&nbsp;Referencing an OSGi Service</h2></div></div></div><p>
In an OSGi-based application, the business logic behind a controller is typically accessed through the OSGi
Service Registry.
</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="osgi.reference.export.package"></a>Exporting Packages</h3></div></div></div><p>
By default, Bundlor detects and exports all packages in a bundle.
In this step Bundlor is told what to
export from the <code class="literal">greenpages.app</code> bundle and which types from those packages to use in the
<code class="literal">greenpages.web</code> bundle.
</p><p>
Add and save the following entry to the <code class="filename">template.mf</code> file in the
<code class="literal">greenpages.app</code> project and then run the <code class="literal">MANIFEST.MF</code> generation on the project as
explained in <a class="xref" href="ch04s04.html#deploy.bundle.web.module.manifest" title="Creating web module metadata">the section called &#8220;Creating web module metadata&#8221;</a>.
</p><pre class="programlisting">Excluded-Exports:
greenpages.internal
</pre><p>
(As before, be careful not to leave trailing spaces on the ends of lines, except for the one space after the colon,
and not to add any blank lines to the file. The second line of this entry has a leading space&#8212;do not omit it.)
</p><p>
Check that the package is no longer exported in the <code class="literal">greenpages.app</code> <code class="literal">MANIFEST.MF</code> file
which should look something like this:
</p><pre class="programlisting">Manifest-Version: 1.0
Bundle-Name: GreenPages Service
Bundle-ManifestVersion: 2
Bundle-SymbolicName: greenpages
Tool: Bundlor 1.0.0.RELEASE
Export-Package: greenpages;version="2.3.0"
Bundle-Version: 2.3.0
</pre><p>
Go to the next step.
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="osgi.reference.referencing.projects.packages"></a>Referencing Projects and Packages</h3></div></div></div><p>
Now that the <code class="literal">greenpages.app</code> bundle exports the package that the
<code class="interfacename">Directory</code> and <code class="interfacename">Listing</code> interfaces reside in,
the <code class="literal">greenpages.web</code> bundle must import it.
In this step the Maven
<code class="filename">pom.xml</code> file is updated to depend on the <code class="literal">greenpages.app</code> bundle and import the
package.
</p><p>
Open the <code class="filename">pom.xml</code> file in the <code class="literal">greenpages.web</code> project.
(Edit the source directly by using the <code class="literal">pom.xml</code> tab in the editor.)
In this file add
the following entry (between the <code class="literal">&lt;dependencies&gt;</code> tags):
</p><pre class="programlisting">&lt;<span class="hl-tag">dependency</span>&gt;
&lt;<span class="hl-tag">groupId</span>&gt;com.springsource.dmserver&lt;<span class="hl-tag">/groupId</span>&gt;
&lt;<span class="hl-tag">artifactId</span>&gt;greenpages.app&lt;<span class="hl-tag">/artifactId</span>&gt;
&lt;<span class="hl-tag">version</span>&gt;${project.version}&lt;<span class="hl-tag">/version</span>&gt;
&lt;<span class="hl-tag">/dependency</span>&gt;
</pre><p>
</p><p>
Open the <code class="classname">GreenPagesController</code> class and import the <code class="classname">Listing</code> and
<code class="classname">Directory</code> types.
(Eclipse should now offer these as a <span class="emphasis"><em>Quick Fix</em></span>.
It it does not, set <code class="literal">greenpages.app</code> as a project dependency of <code class="literal">greenpages.web</code>
in the Build Path of the web project.)
The class should now compile cleanly.
</p><p>
The following imports should now have been added to the <code class="classname">GreenPagesController</code> class:
</p><pre class="programlisting">import greenpages.Directory;
import greenpages.Listing;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
</pre><p>
</p><p>
Add the following package clause to the <code class="literal">Import-Template</code> entry in the
<code class="filename">template.mf</code> file in the <code class="literal">greenpages.web</code> project. When added run the
MANIFEST.MF generation on the project as described in <a class="xref" href="ch04s04.html#deploy.bundle.web.module.manifest" title="Creating web module metadata">the section called &#8220;Creating web module metadata&#8221;</a>.
</p><pre class="programlisting">greenpages.*;version="[2.3, 2.4)"</pre><p>
Be careful to include the &#8220;<span class="quote"><code class="literal">.*</code></span>&#8221; in the package pattern.
</p><p>
Once Bundlor has finished, go to the next step.
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="osgi.reference.deploy.par"></a>Deploying a PAR</h3></div></div></div><p>
Currently the Web Server instance has a single web module bundle deployed. In this step, the
<code class="literal">greenpages.web</code> bundle is undeployed and <code class="literal">greenpages</code> PAR is deployed.
</p><p>
Right-click on the Web Server in the <span class="emphasis"><em>Servers</em></span> view, and select
<span class="emphasis"><em>Add and Remove&#8230;</em></span>. In the dialog that opens, remove the
<code class="literal">greenpages.web</code> bundle and add the <code class="literal">greenpages</code> PAR to the server. When
the configuration is complete, press <span class="emphasis"><em>Finish</em></span>.
</p><div class="mediaobject" align="center"><img src="images/web-module/add-remove-projects.png" align="middle"></div><p>
</p><p>
Eclipse automatically undeploys the <code class="literal">greenpages.web</code> bundle and deploys the
<code class="literal">greenpages</code> PAR.
When this happens, the deployment may fail with an error.
If it does not, open the browser again at
<a class="ulink" href="http://localhost:8080/greenpages" target="_top">http://localhost:8080/greenpages</a>
and observe the failure which should have a root cause similar to:
</p><pre class="programlisting">org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [greenpages.Directory] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
</pre><p>
This error is caused by there being no instance of <code class="classname">Directory</code> to inject into the controller.
The next section will supply one.
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="osgi.reference.reference"></a>Referencing an OSGi Service</h3></div></div></div><p>
There is no instance of <code class="interfacename">Directory</code> to be
injected into the controller.
In the GreenPages application, it is intended that this
implementation is used through an interface in
the OSGi <span class="emphasis"><em>Service Registry</em></span>.
Using a service in the Service Registry enables
another bundle to
provide an implementation without revealing the implementation or the provider to all clients of the
service.
Web Server supports the use of the Spring DM <span class="emphasis"><em>namespace</em></span> for
referencing elements in the OSGi Service Registry.
This step adds an OSGi Service Reference to an implementation of the
<code class="interfacename">Directory</code> interface.
</p><p>
In the <code class="filename">webapp/WEB-INF/applicationContext.xml</code> file in the <code class="literal">greenpages.web</code>
projects add a reference to a
<code class="interfacename">greenpages.Directory</code> instance in the OSGi service registry using
the <code class="literal">&lt;osgi:reference/&gt;</code> tag as follows:
</p><pre class="programlisting">&lt;<span class="hl-tag">osgi:reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"directory"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"greenpages.Directory"</span>/&gt;
</pre><p>
</p><p>
The tools will automatically redeploy the <code class="literal">greenpages.web</code> bundle when the change to the
bean definition has been saved.
The web bundle will not completely start.
</p><p>
This is because there is no provider of a <code class="interfacename">greenpages.Directory</code> in
the Service Registry. The next step will address this.
</p><p>
The error is re-issued as the Web Server instance waits for the service to be supplied. After about five minutes
the server will &#8220;<span class="quote">time-out</span>&#8221; and the deploy will be abandoned. This same error (and time-out)
will occur each time the PAR is redeployed as each change is made.
</p><p>Stop the server instance by right-clicking on the server in the <span class="emphasis"><em>Servers</em></span> view and
selecting <span class="emphasis"><em>Stop</em></span>. This will avoid unnecessary delays as changes are made.
</p></div></div><!--Begin LoopFuse code--><script src="http://loopfuse.net/webrecorder/js/listen.js" type="text/javascript"></script><script type="text/javascript">
_lf_cid = "LF_48be82fa";
_lf_remora();
</script><!--End LoopFuse code--><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch04s05.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="ch04.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="ch04s07.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4.5&nbsp;Creating a PAR&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;4.7&nbsp;Publishing an OSGi Service</td></tr></table></div></body></html>