| <?xml version="1.0" encoding="UTF-8"?> |
| <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" |
| "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> |
| <section id="osgi.reference"> |
| <title>Referencing an OSGi Service</title> |
| <para> |
| In an OSGi-based application, the business logic behind a controller is typically accessed through the OSGi |
| Service Registry. |
| </para> |
| |
| <section id="osgi.reference.export.package"> |
| <title>Exporting Packages</title> |
| <para> |
| By default, Bundlor detects and exports all packages in a bundle. |
| In this step Bundlor is told what to |
| export from the <literal>greenpages.app</literal> bundle and which types from those packages to use in the |
| <literal>greenpages.web</literal> bundle. |
| </para> |
| |
| <para> |
| Add and save the following entry to the <filename>template.mf</filename> file in the |
| <literal>greenpages.app</literal> project and then run the <literal>MANIFEST.MF</literal> generation on the project as |
| explained in <xref linkend="deploy.bundle.web.module.manifest"/>. |
| <programlisting><![CDATA[Excluded-Exports: |
| greenpages.internal]]> |
| </programlisting> |
| (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.) |
| </para> |
| |
| <para> |
| Check that the package is no longer exported in the <literal>greenpages.app</literal> <literal>MANIFEST.MF</literal> file |
| which should look something like this: |
| <programlisting><![CDATA[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]]> |
| </programlisting> |
| Go to the next step. |
| </para> |
| </section> |
| |
| <section id="osgi.reference.referencing.projects.packages"> |
| <title>Referencing Projects and Packages</title> |
| <para> |
| Now that the <literal>greenpages.app</literal> bundle exports the package that the |
| <interfacename>Directory</interfacename> and <interfacename>Listing</interfacename> interfaces reside in, |
| the <literal>greenpages.web</literal> bundle must import it. |
| In this step the Maven |
| <filename>pom.xml</filename> file is updated to depend on the <literal>greenpages.app</literal> bundle and import the |
| package. |
| </para> |
| |
| <para> |
| Open the <filename>pom.xml</filename> file in the <literal>greenpages.web</literal> project. |
| (Edit the source directly by using the <literal>pom.xml</literal> tab in the editor.) |
| In this file add |
| the following entry (between the <literal><![CDATA[<dependencies>]]></literal> tags): |
| <programlisting language="xml"><![CDATA[<dependency> |
| <groupId>com.springsource.dmserver</groupId> |
| <artifactId>greenpages.app</artifactId> |
| <version>${project.version}</version> |
| </dependency>]]> |
| </programlisting> |
| </para> |
| <para> |
| Open the <classname>@greenpages@Controller</classname> class and import the <classname>Listing</classname> and |
| <classname>Directory</classname> types. |
| (Eclipse should now offer these as a <emphasis>Quick Fix</emphasis>. |
| It it does not, set <literal>greenpages.app</literal> as a project dependency of <literal>greenpages.web</literal> |
| in the Build Path of the web project.) |
| The class should now compile cleanly. |
| </para> |
| <para> |
| The following imports should now have been added to the <classname>@greenpages@Controller</classname> 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; |
| </programlisting> |
| </para> |
| <para> |
| Add the following package clause to the <literal>Import-Template</literal> entry in the |
| <filename>template.mf</filename> file in the <literal>greenpages.web</literal> project. When added run the |
| MANIFEST.MF generation on the project as described in <xref linkend="deploy.bundle.web.module.manifest"/>. |
| <programlisting><![CDATA[greenpages.*;version="[2.3, 2.4)"]]></programlisting> |
| Be careful to include the <quote><literal>.*</literal></quote> in the package pattern. |
| </para> |
| <para> |
| Once Bundlor has finished, go to the next step. |
| </para> |
| </section> |
| |
| <section id="osgi.reference.deploy.par"> |
| <title>Deploying a PAR</title> |
| <para> |
| Currently the @webserv@ instance has a single web module bundle deployed. In this step, the |
| <literal>greenpages.web</literal> bundle is undeployed and <literal>greenpages</literal> PAR is deployed. |
| </para> |
| |
| <para> |
| Right-click on the @webserv@ in the <emphasis>Servers</emphasis> view, and select |
| <emphasis>Add and Remove…</emphasis>. In the dialog that opens, remove the |
| <literal>greenpages.web</literal> bundle and add the <literal>greenpages</literal> PAR to the server. When |
| the configuration is complete, press <emphasis>Finish</emphasis>. |
| <mediaobject> |
| <imageobject role="fo"> |
| <imagedata fileref="images/web-module/add-remove-projects.png" format="PNG" align="center" width="10cm"/> |
| </imageobject> |
| <imageobject role="html"> |
| <imagedata fileref="images/web-module/add-remove-projects.png" format="PNG" align="center"/> |
| </imageobject> |
| </mediaobject> |
| </para> |
| <para> |
| Eclipse automatically undeploys the <literal>greenpages.web</literal> bundle and deploys the |
| <literal>greenpages</literal> PAR. |
| When this happens, the deployment may fail with an error. |
| If it does not, open the browser again at |
| <ulink url="http://localhost:8080/greenpages">http://localhost:8080/greenpages</ulink> |
| and observe the failure which should have a root cause similar to: |
| <programlisting><![CDATA[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)}]]> |
| </programlisting> |
| This error is caused by there being no instance of <classname>Directory</classname> to inject into the controller. |
| The next section will supply one. |
| </para> |
| </section> |
| <section id="osgi.reference.reference"> |
| <title>Referencing an OSGi Service</title> |
| <para> |
| There is no instance of <interfacename>Directory</interfacename> to be |
| injected into the controller. |
| In the @greenpages@ application, it is intended that this |
| implementation is used through an interface in |
| the OSGi <emphasis>Service Registry</emphasis>. |
| 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. |
| @webserv@ supports the use of the Spring DM <emphasis>namespace</emphasis> for |
| referencing elements in the OSGi Service Registry. |
| This step adds an OSGi Service Reference to an implementation of the |
| <interfacename>Directory</interfacename> interface. |
| </para> |
| <para> |
| In the <filename>webapp/WEB-INF/applicationContext.xml</filename> file in the <literal>greenpages.web</literal> |
| projects add a reference to a |
| <interfacename>greenpages.Directory</interfacename> instance in the OSGi service registry using |
| the <literal><![CDATA[<osgi:reference/>]]></literal> tag as follows: |
| <programlisting language="xml"><![CDATA[<osgi:reference id="directory" interface="greenpages.Directory"/>]]> |
| </programlisting> |
| </para> |
| <para> |
| The tools will automatically redeploy the <literal>greenpages.web</literal> bundle when the change to the |
| bean definition has been saved. |
| The web bundle will not completely start. |
| <!-- After some time, the following error should occur: |
| <programlisting><![CDATA[<CC0001W> Mandatory reference '&directory' in bundle |
| 'greenpages-1-greenpages.web' version '2.3.0' is waiting for service with filter |
| '(&(objectClass=greenpages.Directory)(!(org.eclipse.virgo.server.app.name=*)))'.]]> |
| </programlisting> --> |
| </para> |
| <para> |
| This is because there is no provider of a <interfacename>greenpages.Directory</interfacename> in |
| the Service Registry. The next step will address this. |
| </para> |
| <para> |
| The error is re-issued as the @webserv@ instance waits for the service to be supplied. After about five minutes |
| the server will <quote>time-out</quote> 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. |
| </para> |
| <para>Stop the server instance by right-clicking on the server in the <emphasis>Servers</emphasis> view and |
| selecting <emphasis>Stop</emphasis>. This will avoid unnecessary delays as changes are made. |
| </para> |
| </section> |
| </section> |