| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>4.6 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. The Web Module"><link rel="prev" href="ch04s05.html" title="4.5 Creating a PAR"><link rel="next" href="ch04s07.html" title="4.7 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 Referencing an OSGi Service</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch04s05.html">Prev</a> </td><th width="60%" align="center">4. The Web Module</th><td width="20%" align="right"> <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 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 “Creating web module metadata”</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—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"><dependencies></code> tags): |
| </p><pre class="programlisting"><<span class="hl-tag">dependency</span>> |
| <<span class="hl-tag">groupId</span>>com.springsource.dmserver<<span class="hl-tag">/groupId</span>> |
| <<span class="hl-tag">artifactId</span>>greenpages.app<<span class="hl-tag">/artifactId</span>> |
| <<span class="hl-tag">version</span>>${project.version}<<span class="hl-tag">/version</span>> |
| <<span class="hl-tag">/dependency</span>> |
| </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 “Creating web module metadata”</a>. |
| </p><pre class="programlisting">greenpages.*;version="[2.3, 2.4)"</pre><p> |
| Be careful to include the “<span class="quote"><code class="literal">.*</code></span>” 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…</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"><osgi:reference/></code> tag as follows: |
| </p><pre class="programlisting"><<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>/> |
| </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 “<span class="quote">time-out</span>” 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> </td><td width="20%" align="center"><a accesskey="u" href="ch04.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch04s07.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4.5 Creating a PAR </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 4.7 Publishing an OSGi Service</td></tr></table></div></body></html> |