Download a [http://www.eclipse.org/downloads/packages version of the Eclipse IDE that includes the ''Plug-in Development Environment'' (PDE)] (''Eclipse IDE for Java EE Developers'', ''Eclipse Classic 3.6.0'' or <br> ''Eclipse for RCP and RAP Developers''). We will need an OSGi-friendly JDBC driver - for this example, we will use the Apache Derby bundle:

<font color="red"><i>{Note - once the Eclipse P2 Repository has the correct version of EclipseLink that supports running DBWS with OSGi, <br>

+

−

the following steps will no longer be required and the EclipseLink target Component can be used}''</i></font> <br>

+

−

EclipseLink builds after <tt>2.1.2.v20100914-r8170</tt> have EclipseLink DBWS available as a [http://www.eclipse.org/downloads/download.php?file=/rt/eclipselink/nightly/2.1.1/20100805/eclipselink-plugins-2.1.1.v20100805-r7986.zip bundle] <br>

+

−

Extract the following 6 bundles to some directory:

+

−

<source lang="text">

+

−

$ ls additionalBundles/

+

−

org.eclipse.persistence.asm.source_2.1.2.v20100914-r8170.jar

+

−

org.eclipse.persistence.asm_2.1.2.v20100914-r8170.jar

+

−

org.eclipse.persistence.core.source_2.1.2.v20100914-r8170.jar

+

−

org.eclipse.persistence.core_2.1.2.v20100914-r8170.jar

+

−

org.eclipse.persistence.dbws.source_2.1.2.v20100914-r8170.jar

+

−

org.eclipse.persistence.dbws_2.1.2.v20100914-r8170.jar

+

−

</source>

+

−

Edit the Target Platform, adding the directory with the additional bundles:<br/>

+

−

[[Image:EclipseLink DBWS with OSGi UpdatedBundles1.png]]<br/><br/>

+

−

[[Image:EclipseLink DBWS with OSGi UpdatedBundles2.png]]<br/><br/>

+

−

Reload the Target Platform

+

−

+

−

=== Create a new Plug-in project ===

+

−

From the 'Plug-in Development' Perspective, create a new Plug-in project <b>SimpleTable</b>:<br/>

+

−

{Note the choice of 'standard' for OSGi framework}<br/>

+

−

[[Image:EclipseLink DBWS with OSGi SimpleTable.png]]<br/>

+

−

Proceed to the next panel of the wizard where the (OSGi bundle) Activator for SimpleTable is defined:<br/>

Change the Activator to extend <code>org.eclipse.persistence.internal.dbws.ProviderHelper</code> (NB - will show errors):<br/>

+

−

[[Image:EclipseLink DBWS with OSGi ProviderHelperwavy.png]]<br/>

+

−

In order to correct the errors, the <b>SimpleTable</b> project needs to update its list of required bundles. Open the <tt>MANIFEST.MF</tt> file in the 'Plug-in Manifest Editor' and select the 'Dependencies' tab and add the following bundles:

+

−

[[Image:EclipseLink DBWS with OSGi Dependencies.png]]<br/>

+

−

<br/>

+

−

The Activator needs to be annotated to support a (dynamic) Web services Endpoint:

In the Eclipse IDE, select the <code>MANIFEST.MF</code> file and bring up the context menu for 'Run As' -> 'Run Configurations' -> 'OSGi Framework' to create a new launch configuration.<br/><br/>

+

−

Deselect the 'Include optional dependencies when computing required bundles' and the <br/>

+

−

'Add new workspace bundles to this launch configuration automatically' check-boxes.<br/><br/>

+

−

Deselect all bundles and re-select 'SimpleTable' and then click 'Add Required Bundles'. This simplifies the list of Required Bundles:<br/>

+

−

[[Image:EclipseLink DBWS with OSGi NewLaunch.png]]<br/>

+

−

<br/>

+

−

When this launch configuration is run, an exception is thrown indicating that some DBWS files cannot be found. The <b>SimpleTable</b> project needs two additional source-folders. The first folder already exists - add the <code>META-INF</code> folder as a source-folder. The second needs to be created:

+

−

+

−

[[Image:EclipseLink DBWS with OSGi NewFolders.png]]<br/>

+

−

<br/>

+

−

In the next section, we will re-use a previous example [[EclipseLink/Examples/DBWS/DBWSBasicTable|(Basic Table)]] to generate the required files.

+

−

+

−

=== Generating the DBWS file ===

+

−

The simple use-case is the creation of a Web service that exposes a database table's <b>CRUD</b> (<b><i><u>C</u></i>reate/<i><u>R</u></i>ead</b>(findByPK,findAll)<b>/<i><u>U</u></i>pdate/<i><u>D</u></i>elete</b>) lifecycle operations. Here is the table <tt>SIMPLETABLE</tt> on my local MySql database:<br/>

+

−

[[Image:EclipseLink DBWS with OSGi SimpleTableDescription.png]]<br/>

+

−

<br/>

+

−

The DBWSBuilder utility requires a DBWS configuration file as input. NB - When running the DBWSBuilder, the setenv.{cmd, sh} file in .../eclipselink/utils/dbws needs to be updated with the path to JDBC driver jar:

+

−

<source lang="text">

+

−

@REM User MUST set DRIVER_CLASSPATH to point to their desired driver jar(s). For example:

+

−

set DRIVER_CLASSPATH=C:\external\libs\mysql-connector-java-5.1.13-bin.jar

The above builder file is a little 'weird' as it specifies how to log in to my local MySql database, but it declares that the platform is Derby. The following files are generated:

+

−

<source lang="text">

+

−

$ROOT

+

−

│

+

−

├───output_directory

+

−

│ DBWSProvider.class

+

−

│ DBWSProvider.java

+

−

│ eclipselink-dbws-or.xml

+

−

│ eclipselink-dbws-ox.xml

+

−

│ eclipselink-dbws-schema.xsd

+

−

│ eclipselink-dbws-sessions.xml

+

−

│ eclipselink-dbws.wsdl

+

−

│ eclipselink-dbws.xml

+

−

│ ProviderListener.class

+

−

│ ProviderListener.java

+

−

</source>

+

−

+

−

Copy the <code>eclipselink-dbws.xml</code>, <code>eclipselink-dbws-or.xml</code>, <code>eclipselink-dbws-ox.xml</code> and <code>eclipselink-dbws-sessions.xml</code> to the <tt>META-INF</tt> directory; <code>eclipselink-dbws-schema.xsd</code> and <code>eclipselink-dbws.wsdl</code> to the <tt>wsdl</tt> directory.

+

−

+

−

The <code>eclipselink-dbws-sessions.xml</code> needs some manual updates:

Typically, JAX-WS Client are generated - either partially or completely - based on the published WSDL. In the example we can see that while the WSDL file is generated, it is not available via a 'live' URL (some tools exist to generate Clients from standalone WSDL files).

+

−

+

−

An alternate (simpler?) option is to use the <code>javax.xml.ws.Dispatch</code> API to directly send pre-computed SOAP messages:

This example relies on the built-in JavaSE HTTP server (<code>com.sun.net.httpserver.HttpServer</code>) which has some known issues ([http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6675392 6675392], [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6946825 6946825]). A user may wish to 'swap-in' a different HTTP Server, such as [http://www.eclipse.org/jetty Jetty], which can be added to the PDE Target Platform from the Helios P2 Update Repository:<br/>

+

−

<br/>

+

−

[[Image:EclipseLink DBWS with OSGi in PDE.png]]

+

−

<br/>

+

−

<br/>

+

−

Open the Manifest Editor and add the following to the Required Plug-ins list of dependencies:

+

−

<source lang="text">

+

−

org.eclipse.jetty.continuation

+

−

org.eclipse.jetty.http

+

−

org.eclipse.jetty.io

+

−

org.eclipse.jetty.server

+

−

org.eclipse.jetty.util

+

−

</source>

+

−

There is a system property to override the built-in JavaSE HTTP server class:

However, the SPI used to load the new <code>HttpServerProvider</code> class is not OSGi-friendly; a 'revised' version of <code>com.sun.net.httpserver.spi.HttpServerProvider</code> (using source from the OpenJDK 6 project) is changed to use the Thread Context Classloader instead of the System Classloader. The revised code is pre-pended to the JVM's bootclassloader so as to override the version that is built-in to JDK 6:

+

−

<source lang="text">

+

−

-Xbootclasspath/p:c:/temp/http_server_spi.jar

+

−

</source>

+

−

The new <code>HttpServerProvider</code> can be found in maven <tt>.../org/mortbay/jetty/jetty-jaxws2spi/7.0.1.v20091125</tt> in the package <code>org.eclipse.jetty.jaxws2spi</code><br/>

+

−

<source lang="text">

+

−

prompt> ls

+

−

JAXWS2ContextHandler.java JettyHttpServer.java

+

−

JettyHttpContext.java JettyHttpServerProvider.java

+

−

JettyHttpExchange.java ThreadPoolExecutorAdapter.java

+

−

</source>

+

−

Once the above classes are added to the project and the required configuration changes are done, the existing code in <code>simpletable.Activator</code> will run - using Jetty - without modification.<br/>

The files under <tt>META-INF</tt> and <tt>wsdl</tt> (<tt>eclipselink-dbws.xml</tt>, <tt>eclipselink-dbws-or.xml</tt>, etc.) can be generated at runtime when the Activator is first initialized. Starting with EclipseLink 2.1.2, portions of the initialization of <code>org.eclipse.persistence.internal.dbws.ProviderHelper</code> can be sub-classed:<br/>

<code>DBWSBuilder</code> is normally invoked as a command-line tool along with a file containing 'operations' that are converted to DBWS runtime artifacts (<tt>eclipselink-dbws.xml</tt>, <tt>eclipselink-dbws-or.xml</tt>, etc.) It is also possible to <b>program</b> an instance of <code>DBWSBuilder</code>:

The call to <code>super.init(XRDynamicClassLoader, null, false)</code> makes callbacks to the three <code>init</code> routines mentioned above where we return the information computed in <code>builder.build(DBWS_SCHEMA_STREAM,...)</code>:

{Note - once the Eclipse P2 Repository has the correct version of EclipseLink that supports running DBWS with OSGi,
the following steps will no longer be required and the EclipseLink target Component can be used}
EclipseLink builds after 2.1.2.v20100928-r8243 have EclipseLink DBWS available as a bundle
Extract the following 6 bundles to some directory:

Edit the Target Platform, adding the directory with the additional bundles:

Reload the Target Platform

Create a new Plug-in project

From the 'Plug-in Development' Perspective, create a new Plug-in project SimpleTable:
{Note the choice of 'standard' for OSGi framework}
Proceed to the next panel of the wizard where the (OSGi bundle) Activator for SimpleTable is defined:
Click 'Finish' and open the generated Activator:

Modifying Activator to implement javax.xml.ws.Provider

Change the Activator to extend org.eclipse.persistence.internal.dbws.ProviderHelper (NB - will show errors):
In order to correct the errors, the SimpleTable project needs to update its list of required bundles. Open the MANIFEST.MF file in the 'Plug-in Manifest Editor' and select the 'Dependencies' tab and add the following bundles:

The Activator needs to be annotated to support a (dynamic) Web services Endpoint:

Running the DBWS Provider-Activator

In the Eclipse IDE, select the MANIFEST.MF file and bring up the context menu for 'Run As' -> 'Run Configurations' -> 'OSGi Framework' to create a new launch configuration called 'Server'.

Deselect the 'Include optional dependencies when computing required bundles' and the
'Add new workspace bundles to this launch configuration automatically' check-boxes.

Deselect all bundles and re-select 'Server' and then click 'Add Required Bundles'. This simplifies the list of Required Bundles:

When this launch configuration is run, an exception is thrown indicating that some DBWS files cannot be found. The SimpleTable project needs two additional source-folders. The first folder already exists - add the META-INF folder as a source-folder. The second needs to be created:

In the next section, we will re-use a previous example (Basic Table) to generate the required files.

Generating the DBWS file

The simple use-case is the creation of a Web service that exposes a database table's CRUD (Create/Read(findByPK,findAll)/Update/Delete) lifecycle operations. Here is the table SIMPLETABLE on my local MySql database:

The DBWSBuilder utility requires a DBWS configuration file as input. NB - When running the DBWSBuilder, the setenv.{cmd, sh} file in .../eclipselink/utils/dbws needs to be updated with the path to JDBC driver jar:

@REM User MUST set DRIVER_CLASSPATH to point to their desired driver jar(s). For example:
set DRIVER_CLASSPATH=C:\external\libs\mysql-connector-java-5.1.13-bin.jar

Copy the eclipselink-dbws.xml, eclipselink-dbws-or.xml, eclipselink-dbws-ox.xml and eclipselink-dbws-sessions.xml to the META-INF directory; eclipselink-dbws-schema.xsd and eclipselink-dbws.wsdl to the wsdl directory.

The eclipselink-dbws-sessions.xml needs some manual updates:

<?xmlversion="1.0"encoding="UTF-8"?><sessionsversion="2.0.0"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><sessionxsi:type="database-session"><name>simpletable-dbws-or-session</name><loggingxsi:type="eclipselink-log"><log-level>fine</log-level></logging><!-- add the META-INF dir to the path to find the OR project --><primary-projectxsi:type="xml">META-INF/eclipselink-dbws-or.xml</primary-project><loginxsi:type="database-login"><platform-class>org.eclipse.persistence.platform.database.DerbyPlatform</platform-class><!-- change the driver class to use Derby's EmbeddedDriver --><driver-class>org.apache.derby.jdbc.EmbeddedDriver</driver-class><!-- change the URL: use Derby's 'create' attribute to create database if it doesn't already exist --><connection-url>jdbc:derby:test;create=true</connection-url><byte-array-binding>false</byte-array-binding><optimize-data-conversion>false</optimize-data-conversion><trim-strings>false</trim-strings></login></session><sessionxsi:type="database-session"><name>simpletable-dbws-ox-session</name><loggingxsi:type="eclipselink-log"><log-level>off</log-level></logging><!-- add the META-INF dir to the path to find the OX project --><primary-projectxsi:type="xml">META-INF/eclipselink-dbws-ox.xml</primary-project></session></sessions>

Since the database won't exist the first time the service is run, need to create the table and populate a few rows:

A Simple(!) JAX-WS Client

Typically, JAX-WS Client are generated - either partially or completely - based on the published WSDL. In the example we can see that while the WSDL file is generated, it is not available via a 'live' URL (some tools exist to generate Clients from standalone WSDL files).

An alternate (simpler?) option is to use the javax.xml.ws.Dispatch API to directly send pre-computed SOAP messages:

Advanced Customization - Part I: Jetty

The above example relies on the built-in JavaSE HTTP server (com.sun.net.httpserver.HttpServer) which has some known issues (6675392, 6946825). A user may wish to 'swap-in' a different HTTP Server, such as Jetty, which can be added to the PDE Target Platform from the Helios P2 Update Repository:

Open the Manifest Editor and add the following to the Required Plug-ins list of dependencies:

The files under META-INF and wsdl (eclipselink-dbws.xml, eclipselink-dbws-or.xml, etc.) can be generated at runtime when the Activator is first initialized. Starting with EclipseLink 2.1.2, portions of the initialization of org.eclipse.persistence.internal.dbws.ProviderHelper can be sub-classed:

From the EclipseLink installation, add eclipselink-dbwsutils.jar and javax.wsdl_1.6.2.v200806030405.jar to the SimpleTable project, under a lib dir:

Open the MANIFEST.MF file in the 'Plug-in Manifest Editor' and select the 'Runtime' tab and add the above jars to the plug-in's classpath:

The wsdl directory can be removed, along with all the DBWS files under META-INF (the project no longer needs these directories to be 'src' directories).

DBWSBuilder is normally invoked as a command-line tool along with a file containing 'operations' that are converted to DBWS runtime artifacts (eclipselink-dbws.xml, eclipselink-dbws-or.xml, etc.) It is also possible to program an instance of DBWSBuilder:

Advanced Customization - Part III: OSGi and JDBC Drivers

The SimpleTable demonstrates how to run an EclipseLink DBWS service in an OSGi environment. One aspect of that environment was simplified by the use of the Apache Derby database which has a JDBC driver that is also an OSGi bundle. Unfortunately, this is not normally the case - most JDBC drivers are not OSGi-friendly. This section describes some of the techniques one can use to manage this addition complexity.
TBD