Orindasoft

OrindaSoft Getting Started Guide

Creating Web Services With JDBCWizard And Apache Axis

    Topics

  1. Introduction
  2. Environment
  3. Setting Up
  4. Generate Web Service code using JDBCWizard./a>
  5. Test generated Web Service code before installing it on Axis.
  6. Make JDBCWizard code usable by Apache Axis
  7. Configure Apache Axis - Create web service definition (WSDL) File
  8. Configure Apache Axis - Create deployment descriptor (WSDD) Files
  9. Configure Apache Axis - Deploy the generated application
  10. Test your web service
  11. Testing your generated Apache Axis client software
  12. Next Steps


Introduction


JDBCWizard generates code that fills the gap between your existing Oracle database and web services toolkits such as Apache Axis. It does this by examining your database and writing Java to call your stored procedures and SQL statements. Unlike other products it doesn't require a precompiler and can write code to run almost all Oracle stored procedures. The diagram below shows where JDBCWizard fits in.

JDBCWizard and Web Service Generation

This tutorial walks you through the creation of a simple web service that uses the Orinda demo database. 

Environment


This tutorial was developed using the following environment:


Component
Product/Version
Obtained From
Operating System Windows XP, SP2 Microsoft
Java Virtual Machine
Java 1.4 (j2sdk1.4.2_04) Sun Microsystems 
Web Server
Apache Tomcat/4.1.31
Apache Jakarta Project
Oracle Database Server
V10.1.0.2. (on a different machine)
Oracle
JDBCWizard
V5.0.2200
Orinda Software
Web Service Toolkit
Apache Axis 1.1 (on developer's PC)
Apache Web Services Project
Java IDE
Eclipse 3.0.2
Eclipse Foundation

You don't have to exactly replicate this environment to use JDBCWizard to create Web Services. JDBCWizard does not have any dependencies on Apache Axis or Tomcat.


Setting Up

Oracle Database Server

There is no reason why the Oracle database server has to be on the same machine as the web server.  JDBCWizard generated code works against any Oracle server from V8.1.5  onwards provided you use the right JDBC driver to access it. To create the OrindaDemo demo database do the following while logged into your database 'database_name' as SYSTEM using SQL*Plus:

GRANT CONNECT, RESOURCE TO ORINDADEMO IDENTIFIED BY ORINDADEMO;
CONNECT ORINDADEMO/ORINDADEMO@database_name;
START orindabuild_demo_ddl.sql

To add data to the tables you'll need to run another SQL script. Use SQL*Plus to log into the Orindademo account and run the sample data script:

START orindabuild_demo_dml.sql

To access this database using JDBC we'll need to know the hostname/IP Address, the port Oracle's listener is running on and the database SID (instance identifier).


Install Tomcat And Axis

Axis 11 install

At this stage you should stop and restart tomcat and make sure that your Axis installation is working. Test this by entering the URL

in your web browser:

http://localhost:8080/axis/index.html


Generate Web Service code using JDBCWizard./h2>

Unzip the JDBCWizard demo to 'C:\JDBCWizard.emo'. For information on the demo see here.

Log into the database

Start JDBCWizard and log in to your database. In our case we used an Oracle 10.1 database called 'LX1010' located at the local IP address 192.168.0.30:



Logging into Database Server

 

Select objects to create code for

Click on the 'Select Objects" tab and select all the PL/SQL Stored Procedures:



Select all PL/SQL procedures to create Java for

Move to the "Sql Statements" tab. Change the SQL file path to 'C:\JDBCWizard.emo\demo\SqlFiles` and then press the 'Refresh ' button. The SQL statements in the SqlFiles directory should appear in the tree structure. Press the 'Select All...' button to include them in the Web Service code.



Choose SQL statements to include in your web service

The "Tables" tab isn't used by Web Services. JDBCWizard will create a

Data Access Object Factory class to access the tables you select.

Use the "Sequences" tab to add the sequence "SEQUENTIAL_NUMBER_GENERATOR" to the list of objects you wish to generate code for.

Add a sequence

 

Code Options

This screen controls how the generated code looks and behaves. Change the 'Target Version of Oracle' in step 3.3.5 so it's the same as your database and move on to step 4.



Code Options for generated web services code

 

Service Options

This screen is used to define how your service classes behave.

Options for Java Web Service Code

In order to make your code usable you need to change several values on this screen:

Field
Our Value
Comment
4.1 - Enter root directory for Java Code
C:\JDBCWizard.emo\Src
Where the code is generated to. We used 'C:\JDBCWizard.emo\Src'.
4.2 - Enter package name
com.orindasoft.demo.generated
Should always end in 'generated'.
4.3 - DAO Factory Class name
DAOFactory
Our web service classes extend DAOFactory. You can change the name if you want.
4.3 - Log Messages Using...
Text Log
For the purposes of this tutorial we'll use Orinda's com.orindasoft.pub.TextLog instead of the web server logging.
4.3 - Get DB Connection Using...
Hard coded connect string
We're telling JDBCWizard that we will create our own connection instead os using JNDI.
4.3 - Log Name/Directory
user.home
This can be any valid directory or the Java System Properties user.home or user.dir
4.3 - Connection Name
jdbc:oracle:thin:ORINDADEMO/ORINDADEMO@192.168.0.30:1521:LX1010
Because we're using a hard coded connect string rather than JNDI we enter the string here. If we were using JNDI we'd enter the JNDI name for the connection instead. You will almost certainly have to change this value to get your code to work.
4.3 - Close Connections
Selected
We're telling JDBCWizard to close the connection when it releases database resources.
4.3 - Commit Connections
Selected
Tell JDBCWizard to call 'commit' at the end of each call.
4.4 - Create Web Service Classes
Selected
The 'DAOFactoryServiceInterface' and 'DAOFactoryServiceImpl' classes are only generated if this is selected.
4.4 - Interface Class Name
DAOFactoryServiceInterface
Axis's Java2WSDL works best when you give it an Java Interface that only contains the public methods you want turned into a Web Service.
4.4 - Implementing Class Name
DAOFactoryServiceImpl
The name of the class that will extend our DAOFactory class and implement the web service methods.
4.4 - Number type used by service
double
By default generated code uses java.math.BigDecimal to represent numbers. For convenience you can change this to a friendlier Java datatype.
4.4 - Always Release Connection
Selected
Tells JDBCWizard to get rid of the database connection at the end of each Web Service call. This is not efficient but makes demonstrations simpler.

Having filled in your values recheck the value for 'Connection Name' and move on to the last step.


Generate Code

Press the 'Generate Code' button to generate your code.  You can then exit JDBCWizard.



Generate Code



Test generated Web Service code before installing it on Axis.

Having generated our code we need to make sure that it will be able to connect to the database successfully before continuing. For the purposes of this tutorial we use Eclipse 3.0.2 to compile, test and package the generated classes. JDBCWizard also runs as an Eclipse Plugin, but to keep things simple we won't refer to it here.

Start Eclipse (or your IDE) and create a new project called 'orindademo'. Note that we point the project at our generated code. We could also move the generated code to the project directory and use 'Refresh' to make it visible to the IDE.
 
Axis Web Service Project For Eclipse

The next step is compiling the code. Before we can do this we have to add an Oracle JDBC driver and the OrindaSoft com.orindasoft.pub library JAR files to the project.



Add Orinda Libraries to web services project

At this point the code should compile and be usable. To make sure of this we'll write a small additional class to test that we can connect to the database:

File C:\JDBCWizard.emo\Src\com\orindasoft\demo\WsTest.java
package com.orindasoft.demo;
// We should never create a class in the same directory JDBCWizard 
// uses. 'DAOFactoryServiceImpl' is in 'generated', the directory 
// below this one.
import com.orindasoft.demo.generated.DAOFactoryServiceImpl;
// This is a special exception thrown when something goes wrong
// with the service code. In a full web services environment it
// will be returned to the client.
import com.orindasoft.demo.generated.DAOFactoryServiceException;
public class WsTest {
    public static void main(String[] args) {
    
    // Create an instance of our service class.
    DAOFactoryServiceImpl theService = new DAOFactoryServiceImpl();
    
    // Until we ask the service to do something we won't know
    // whether it works or not. We'll ask it for the next value
    // from the demo's unique number generator. You should get 
    // a different value every time you access the sequence.
    try
      {
      for (int i=0; i < 3; i++)
        {
        long ourNumber = theService.serviceSequenceSequentialNumberGenerator();
        System.out.println("Got value of " + ourNumber + " from database");
        }
      }
    catch (DAOFactoryServiceException e)
      {
      System.err.println("DAOFactoryServiceImpl is broken:");
      System.err.println(e.getMessage());
      } 
        
    }
}


When run one of two things will happen. If the code is working then you'll see something like this:



Got value of 33 from database
Got value of 34 from database
Got value of 35 from database

If you didn't specify the right connect string you'll see something like this:

DAOFactoryServiceImpl is broken:
java.sql.SQLException: No suitable driver

If you do get an error there is no point in continuing until you have resolved it.

Make JDBCWizard code usable by Apache Axis

Using either the 'jar' program or your IDE create a JAR file containing your generated code. In order for our JDBCWizard JAR file to be usable by Axis it will need two other JAR files:


 

Shutdown the Tomcat web server and copy all three of these files into Axis's 'lib' directory. The Axis file stricture should then look like this:

Jar files


Configure Apache Axis - Create web service definition (WSDL) File

Prerequisites

We now need to deploy our application to Axis. Before continuing you should have read the following Axis Documents:

The Java2WSDL: Building WSDL from Java section in the Apache Axis User Guide
The section on Java2WSDL in the Apache Axis Reference Guide.

In order to create our WSDL file we need a CLASSPATH with the entire contents of the axis\WEB-INF\lib directory on it, including

This can be done using a script or by creating a new project in your IDE and adding the libraries. Do NOT use the same Java project you generated the code in for this. We created a new project called 'orindademo_java2wsdl' and added all the libraries from axis\WEB-INF\lib:



JAR files for Axis Java2WSDL

We then created a small program that calls org.apache.axis.wsdl.Java2WSDL:

File C:\JDBCWizard.emo\Src\com\orindasoft\demo\WsRunJava2WSDL.java
package com.orindasoft.publishdemo;

public class WsRunJava2Wsdl {

    public static void main(String[] args) {

    final java.io.File outputDir = new java.io.File("c:\\OrindaTemp");

    final java.io.File wsdlFile = new java.io.File(outputDir,"orindademo.wsdl");
    
    final String[] wsdlArgs = 
      {
      // output WSDL filename. 
      "-o", wsdlFile.getAbsolutePath()
      // service location url
      // 'http://localhost:8080/' is the address of the web server
      // 'axis/services' identifies it as an axis service
      // 'ORINDADEMO' is what we're calling the service
      ,"-l" ,"http://localhost:8080/axis/services/ORINDADEMO"
      //target namespace. This is our package name, backwards.
      ,"-n","urn:generated.demo.orindasoft.com"
      // binding name
      ,"-b", "DAOFactoryService"
      // Interface class we wish to generate WSDL for
      ,"com.orindasoft.demo.generated.DAOFactoryServiceInterface"
      };

    // Create output dir if it doesn't exist
    if (! outputDir.exists())
      {
      outputDir.mkdirs();
      }
    else
      // Delete old WSDL file if exists
      {
      if (wsdlFile.exists())
        {
          wsdlFile.delete();
        }
      }
    
    // Print out the arguments we're going to use
    for (int i=0; i < wsdlArgs.length; i++)
      {
      System.out.println(wsdlArgs[i]);
      }
    
    // Now call org.apache.axis.wsdl.Java2WSDL and see what happens
    org.apache.axis.wsdl.Java2WSDL.main(wsdlArgs);
    
    // We never get to this line - Java2WSDL calls System.exit()....
    
    }
}


When run this program will either produce angry error messages from Axis or terminate without saying anything at all. If it has worked a WSDL file like this one will have been created:

File C:\OrindaTemp\orindademo.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:generated.demo.orindasoft.com" 
xmlns:tns3="http://sql.generated.demo.orindasoft.com" 
xmlns:impl="urn:generated.demo.orindasoft.com" xmlns:intf="urn:generated.demo.orindasoft.com" 
xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:tns2="http://plsql.generated.demo.orindasoft.com" xmlns:tns1="http://generated.demo.orindasoft.com" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
 <wsdl:types>
  <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://generated.demo.orindasoft.com">
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   <complexType name="DAOFactoryServiceException">
    <sequence>
     <element name="detailMessage" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
  </schema>
  <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://plsql.generated.demo.orindasoft.com">
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   <complexType name="CustomersAttrs">
    <sequence>
     <element name="paramName" nillable="true" type="xsd:string"/>
     <element name="paramAddress" nillable="true" type="xsd:string"/>
     <element name="paramCity" nillable="true" type="xsd:string"/>
     <element name="paramState" nillable="true" type="xsd:string"/>
     <element name="paramZip" nillable="true" type="xsd:decimal"/>
     <element name="paramBirthdate" nillable="true" type="xsd:dateTime"/>
     <element name="paramPhone" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="BookingsTypeAttrs">
    <sequence>
     <element name="paramCustomerName" nillable="true" type="xsd:string"/>
     <element name="paramAirlineName" nillable="true" type="xsd:string"/>
     <element name="paramFlightNumber" nillable="true" type="xsd:decimal"/>
     <element name="paramDepartureTime" nillable="true" type="xsd:dateTime"/>
     <element name="paramSeat" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="CityPairOracleTypeAttrs">
    <sequence>
     <element name="paramFromCity" nillable="true" type="xsd:string"/>
     <element name="paramToCity" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="ComplexExampleCityPairPlsqlRecordAttrs">
    <sequence>
     <element name="paramFromCity" nillable="true" type="xsd:string"/>
     <element name="paramToCity" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="AirportsAttrs">
    <sequence>
     <element name="paramAirportCode" nillable="true" type="xsd:string"/>
     <element name="paramAirportName" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="SimpleExamplesAirlineRefcursorTypeAttrs">
    <sequence>
     <element name="paramAirlineName" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="FlightsTypeAttrs">
    <sequence>
     <element name="paramDepartureCity" nillable="true" type="xsd:string"/>
     <element name="paramArrivalCity" nillable="true" type="xsd:string"/>
     <element name="paramAirlineName" nillable="true" type="xsd:string"/>
     <element name="paramFlightNumber" nillable="true" type="xsd:decimal"/>
     <element name="paramDepartureTime" nillable="true" type="xsd:dateTime"/>
     <element name="paramArrivalTime" nillable="true" type="xsd:dateTime"/>
     <element name="paramAircraftType" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="SimpleExamplesFlightsRefcursorTypeAttrs">
    <sequence>
     <element name="paramDepartureCity" nillable="true" type="xsd:string"/>
     <element name="paramArrivalCity" nillable="true" type="xsd:string"/>
     <element name="paramAirlineName" nillable="true" type="xsd:string"/>
     <element name="paramFlightNumber" nillable="true" type="xsd:decimal"/>
     <element name="paramDepartureTime" nillable="true" type="xsd:dateTime"/>
     <element name="paramArrivalTime" nillable="true" type="xsd:dateTime"/>
     <element name="paramAircraftType" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="OrindademoSimpleExamplesAirlineRefcursorTypeAttrs">
    <sequence>
     <element name="paramAirlineName" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="SimpleExamplesAirportRefcursorTypeAttrs">
    <sequence>
     <element name="paramAirportCode" nillable="true" type="xsd:string"/>
     <element name="paramAirportName" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="SimpleExamplesAircraftRefcursorTypeAttrs">
    <sequence>
     <element name="paramAircraftType" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="SimpleExamplesGetlistsReturn">
    <sequence>
     <element name="paramPAirlineListing" nillable="true" 
type="tns2:OrindademoSimpleExamplesAirlineRefcursorTypeAttrs" maxOccurs="unbounded"/>
     <element name="paramPAirportListing" nillable="true" 
type="tns2:SimpleExamplesAirportRefcursorTypeAttrs" maxOccurs="unbounded"/>
     <element name="paramPAircraftListing" nillable="true" 
type="tns2:SimpleExamplesAircraftRefcursorTypeAttrs" maxOccurs="unbounded"/>
    </sequence>
   </complexType>
  </schema>
  <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:generated.demo.orindasoft.com">
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   <complexType name="ArrayOf_tns2_BookingsTypeAttrs">
    <complexContent>
     <restriction base="soapenc:Array">
      <attribute ref="soapenc:arrayType" wsdl:arrayType="tns2:BookingsTypeAttrs[]"/>
     </restriction>
    </complexContent>
   </complexType>
   <complexType name="ArrayOf_tns2_SimpleExamplesAirlineRefcursorTypeAttrs">
    <complexContent>
     <restriction base="soapenc:Array">
      <attribute ref="soapenc:arrayType" wsdl:arrayType="tns2:SimpleExamplesAirlineRefcursorTypeAttrs[]"/>
     </restriction>
    </complexContent>
   </complexType>
   <complexType name="ArrayOf_tns2_FlightsTypeAttrs">
    <complexContent>
     <restriction base="soapenc:Array">
      <attribute ref="soapenc:arrayType" wsdl:arrayType="tns2:FlightsTypeAttrs[]"/>
     </restriction>
    </complexContent>
   </complexType>
   <complexType name="ArrayOf_tns2_SimpleExamplesFlightsRefcursorTypeAttrs">
    <complexContent>
     <restriction base="soapenc:Array">
      <attribute ref="soapenc:arrayType" wsdl:arrayType="tns2:SimpleExamplesFlightsRefcursorTypeAttrs[]"/>
     </restriction>
    </complexContent>
   </complexType>
   <complexType name="ArrayOf_tns3_DemoGetFlightsCursorAttr">
    <complexContent>
     <restriction base="soapenc:Array">
      <attribute ref="soapenc:arrayType" wsdl:arrayType="tns3:DemoGetFlightsCursorAttr[]"/>
     </restriction>
    </complexContent>
   </complexType>
  </schema>
  <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://sql.generated.demo.orindasoft.com">
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   <complexType name="DemoGetFlightsCursorAttr">
    <sequence>
     <element name="departureCity" nillable="true" type="xsd:string"/>
     <element name="arrivalCity" nillable="true" type="xsd:string"/>
     <element name="airlineName" nillable="true" type="xsd:string"/>
     <element name="flightNumber" nillable="true" type="xsd:decimal"/>
     <element name="departureTime" nillable="true" type="xsd:dateTime"/>
     <element name="arrivalTime" nillable="true" type="xsd:dateTime"/>
     <element name="aircraftType" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
  </schema>
 </wsdl:types>

   <wsdl:message name="servicePlsqlComplexExampleAddBookingsResponse">

      <wsdl:part name="servicePlsqlComplexExampleAddBookingsReturn" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="serviceSequenceSequentialNumberGeneratorResponse">

      <wsdl:part name="serviceSequenceSequentialNumberGeneratorReturn" type="xsd:long"/>

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoMakeBookingRequest">

      <wsdl:part name="in0" type="xsd:string"/>

      <wsdl:part name="in1" type="xsd:string"/>

      <wsdl:part name="in2" type="xsd:double"/>

      <wsdl:part name="in3" type="xsd:dateTime"/>

      <wsdl:part name="in4" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlComplexExampleFliesBetweenAllRequest">

      <wsdl:part name="in0" type="tns2:CityPairOracleTypeAttrs"/>

      <wsdl:part name="in1" type="tns2:ComplexExampleCityPairPlsqlRecordAttrs"/>

      <wsdl:part name="in2" type="tns2:AirportsAttrs"/>

      <wsdl:part name="in3" type="tns2:AirportsAttrs"/>

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoMakeBookingResponse">

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoTruncateBookingsResponse">

   </wsdl:message>

   <wsdl:message name="DAOFactoryServiceException">

      <wsdl:part name="fault" type="tns1:DAOFactoryServiceException"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlSimpleExamplesGetlistsResponse">

      <wsdl:part name="servicePlsqlSimpleExamplesGetlistsReturn" type="tns2:SimpleExamplesGetlistsReturn"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlComplexExampleGetTableOfFlightsFromRequest">

      <wsdl:part name="in0" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlSimpleExamplesDirectFlightAvailableRequest">

      <wsdl:part name="in0" type="xsd:string"/>

      <wsdl:part name="in1" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlComplexExampleFliesBetweenAllResponse">

      <wsdl:part name="servicePlsqlComplexExampleFliesBetweenAllReturn" type="impl:ArrayOf_tns2_SimpleExamplesAirlineRefcursorTypeAttrs"/>

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoAddCustRequest">

      <wsdl:part name="in0" type="xsd:string"/>

      <wsdl:part name="in1" type="xsd:string"/>

      <wsdl:part name="in2" type="xsd:string"/>

      <wsdl:part name="in3" type="xsd:string"/>

      <wsdl:part name="in4" type="xsd:double"/>

      <wsdl:part name="in5" type="xsd:dateTime"/>

      <wsdl:part name="in6" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlSimpleExamplesDirectFlightAvailableResponse">

      <wsdl:part name="servicePlsqlSimpleExamplesDirectFlightAvailableReturn" type="xsd:boolean"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlSimpleExamplesFindDirectFlightsResponse">

      <wsdl:part name="servicePlsqlSimpleExamplesFindDirectFlightsReturn" type="impl:ArrayOf_tns2_SimpleExamplesFlightsRefcursorTypeAttrs"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlComplexExampleGetTableOfFlightsFromResponse">

      <wsdl:part name="servicePlsqlComplexExampleGetTableOfFlightsFromReturn" type="impl:ArrayOf_tns2_FlightsTypeAttrs"/>

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoGetFlightsRequest">

      <wsdl:part name="in0" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoGetFlightsResponse">

      <wsdl:part name="serviceSqlDemoGetFlightsReturn" type="impl:ArrayOf_tns3_DemoGetFlightsCursorAttr"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlSimpleExamplesGetlistsRequest">

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoTruncateBookingsRequest">

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoAddCustResponse">

   </wsdl:message>

   <wsdl:message name="servicePlsqlComplexExampleAddBookingsRequest">

      <wsdl:part name="in0" type="tns2:CustomersAttrs"/>

      <wsdl:part name="in1" type="impl:ArrayOf_tns2_BookingsTypeAttrs"/>

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoUpdCustResponse">

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoUpdCustRequest">

      <wsdl:part name="in0" type="xsd:string"/>

      <wsdl:part name="in1" type="xsd:string"/>

      <wsdl:part name="in2" type="xsd:string"/>

      <wsdl:part name="in3" type="xsd:double"/>

      <wsdl:part name="in4" type="xsd:dateTime"/>

      <wsdl:part name="in5" type="xsd:string"/>

      <wsdl:part name="in6" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoDeleteCustomersResponse">

   </wsdl:message>

   <wsdl:message name="serviceSequenceSequentialNumberGeneratorRequest">

   </wsdl:message>

   <wsdl:message name="serviceSqlDemoDeleteCustomersRequest">

      <wsdl:part name="in0" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="servicePlsqlSimpleExamplesFindDirectFlightsRequest">

      <wsdl:part name="in0" type="xsd:string"/>

      <wsdl:part name="in1" type="xsd:string"/>

      <wsdl:part name="in2" type="xsd:dateTime"/>

      <wsdl:part name="in3" type="xsd:dateTime"/>

      <wsdl:part name="in4" type="xsd:double"/>

   </wsdl:message>

   <wsdl:portType name="DAOFactoryServiceInterface">

      <wsdl:operation name="serviceSequenceSequentialNumberGenerator">

         <wsdl:input name="serviceSequenceSequentialNumberGeneratorRequest" message="impl:serviceSequenceSequentialNumberGeneratorRequest"/>

         <wsdl:output name="serviceSequenceSequentialNumberGeneratorResponse" message="impl:serviceSequenceSequentialNumberGeneratorResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlComplexExampleAddBookings" parameterOrder="in0 in1">

         <wsdl:input name="servicePlsqlComplexExampleAddBookingsRequest" message="impl:servicePlsqlComplexExampleAddBookingsRequest"/>

         <wsdl:output name="servicePlsqlComplexExampleAddBookingsResponse" message="impl:servicePlsqlComplexExampleAddBookingsResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlComplexExampleFliesBetweenAll" parameterOrder="in0 in1 in2 in3">

         <wsdl:input name="servicePlsqlComplexExampleFliesBetweenAllRequest" message="impl:servicePlsqlComplexExampleFliesBetweenAllRequest"/>

         <wsdl:output name="servicePlsqlComplexExampleFliesBetweenAllResponse" message="impl:servicePlsqlComplexExampleFliesBetweenAllResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlComplexExampleGetTableOfFlightsFrom" parameterOrder="in0">

         <wsdl:input name="servicePlsqlComplexExampleGetTableOfFlightsFromRequest" message="impl:servicePlsqlComplexExampleGetTableOfFlightsFromRequest"/>

         <wsdl:output name="servicePlsqlComplexExampleGetTableOfFlightsFromResponse" message="impl:servicePlsqlComplexExampleGetTableOfFlightsFromResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlSimpleExamplesDirectFlightAvailable" parameterOrder="in0 in1">

         <wsdl:input name="servicePlsqlSimpleExamplesDirectFlightAvailableRequest" message="impl:servicePlsqlSimpleExamplesDirectFlightAvailableRequest"/>

         <wsdl:output name="servicePlsqlSimpleExamplesDirectFlightAvailableResponse" message="impl:servicePlsqlSimpleExamplesDirectFlightAvailableResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlSimpleExamplesFindDirectFlights" parameterOrder="in0 in1 in2 in3 in4">

         <wsdl:input name="servicePlsqlSimpleExamplesFindDirectFlightsRequest" message="impl:servicePlsqlSimpleExamplesFindDirectFlightsRequest"/>

         <wsdl:output name="servicePlsqlSimpleExamplesFindDirectFlightsResponse" message="impl:servicePlsqlSimpleExamplesFindDirectFlightsResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlSimpleExamplesGetlists">

         <wsdl:input name="servicePlsqlSimpleExamplesGetlistsRequest" message="impl:servicePlsqlSimpleExamplesGetlistsRequest"/>

         <wsdl:output name="servicePlsqlSimpleExamplesGetlistsResponse" message="impl:servicePlsqlSimpleExamplesGetlistsResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoAddCust" parameterOrder="in0 in1 in2 in3 in4 in5 in6">

         <wsdl:input name="serviceSqlDemoAddCustRequest" message="impl:serviceSqlDemoAddCustRequest"/>

         <wsdl:output name="serviceSqlDemoAddCustResponse" message="impl:serviceSqlDemoAddCustResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoDeleteCustomers" parameterOrder="in0">

         <wsdl:input name="serviceSqlDemoDeleteCustomersRequest" message="impl:serviceSqlDemoDeleteCustomersRequest"/>

         <wsdl:output name="serviceSqlDemoDeleteCustomersResponse" message="impl:serviceSqlDemoDeleteCustomersResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoGetFlights" parameterOrder="in0">

         <wsdl:input name="serviceSqlDemoGetFlightsRequest" message="impl:serviceSqlDemoGetFlightsRequest"/>

         <wsdl:output name="serviceSqlDemoGetFlightsResponse" message="impl:serviceSqlDemoGetFlightsResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoMakeBooking" parameterOrder="in0 in1 in2 in3 in4">

         <wsdl:input name="serviceSqlDemoMakeBookingRequest" message="impl:serviceSqlDemoMakeBookingRequest"/>

         <wsdl:output name="serviceSqlDemoMakeBookingResponse" message="impl:serviceSqlDemoMakeBookingResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoTruncateBookings">

         <wsdl:input name="serviceSqlDemoTruncateBookingsRequest" message="impl:serviceSqlDemoTruncateBookingsRequest"/>

         <wsdl:output name="serviceSqlDemoTruncateBookingsResponse" message="impl:serviceSqlDemoTruncateBookingsResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoUpdCust" parameterOrder="in0 in1 in2 in3 in4 in5 in6">

         <wsdl:input name="serviceSqlDemoUpdCustRequest" message="impl:serviceSqlDemoUpdCustRequest"/>

         <wsdl:output name="serviceSqlDemoUpdCustResponse" message="impl:serviceSqlDemoUpdCustResponse"/>

         <wsdl:fault name="DAOFactoryServiceException" message="impl:DAOFactoryServiceException"/>

      </wsdl:operation>

   </wsdl:portType>

   <wsdl:binding name="DAOFactoryService" type="impl:DAOFactoryServiceInterface">

      <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>

      <wsdl:operation name="serviceSequenceSequentialNumberGenerator">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="serviceSequenceSequentialNumberGeneratorRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="serviceSequenceSequentialNumberGeneratorResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlComplexExampleAddBookings">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="servicePlsqlComplexExampleAddBookingsRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="servicePlsqlComplexExampleAddBookingsResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlComplexExampleFliesBetweenAll">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="servicePlsqlComplexExampleFliesBetweenAllRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="servicePlsqlComplexExampleFliesBetweenAllResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlComplexExampleGetTableOfFlightsFrom">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="servicePlsqlComplexExampleGetTableOfFlightsFromRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="servicePlsqlComplexExampleGetTableOfFlightsFromResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlSimpleExamplesDirectFlightAvailable">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="servicePlsqlSimpleExamplesDirectFlightAvailableRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="servicePlsqlSimpleExamplesDirectFlightAvailableResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlSimpleExamplesFindDirectFlights">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="servicePlsqlSimpleExamplesFindDirectFlightsRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="servicePlsqlSimpleExamplesFindDirectFlightsResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="servicePlsqlSimpleExamplesGetlists">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="servicePlsqlSimpleExamplesGetlistsRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="servicePlsqlSimpleExamplesGetlistsResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoAddCust">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="serviceSqlDemoAddCustRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="serviceSqlDemoAddCustResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoDeleteCustomers">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="serviceSqlDemoDeleteCustomersRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="serviceSqlDemoDeleteCustomersResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoGetFlights">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="serviceSqlDemoGetFlightsRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="serviceSqlDemoGetFlightsResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoMakeBooking">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="serviceSqlDemoMakeBookingRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="serviceSqlDemoMakeBookingResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoTruncateBookings">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="serviceSqlDemoTruncateBookingsRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="serviceSqlDemoTruncateBookingsResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

      <wsdl:operation name="serviceSqlDemoUpdCust">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="serviceSqlDemoUpdCustRequest">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:input>

         <wsdl:output name="serviceSqlDemoUpdCustResponse">

            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:output>

         <wsdl:fault name="DAOFactoryServiceException">

            <wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:generated.demo.orindasoft.com"/>

         </wsdl:fault>

      </wsdl:operation>

   </wsdl:binding>

   <wsdl:service name="DAOFactoryServiceInterfaceService">

      <wsdl:port name="ORINDADEMO" binding="impl:DAOFactoryService">

         <wsdlsoap:address location="http://localhost:8080/axis/services/ORINDADEMO"/>

      </wsdl:port>

   </wsdl:service>

</wsdl:definitions>

Configure Apache Axis - Create deployment descriptor (WSDD) Files

Having created our WSDL file we now use it to create deploy.wsdd and undeploy.wsdd, which are needed to tell Axis about our service. The program below was used to generate our WSDD files.



File C:\JDBCWizard.emo\Src\com\orindasoft\demo\WsRunJava2WSDL.java
package com.orindasoft.publishdemo;

public class WsRunWsdl2Java {

    public static void main(String[] args) {

    final java.io.File outputDir = new java.io.File("c:\\OrindaTemp");

    final java.io.File wsdlFile = new java.io.File(outputDir,"orindademo.wsdl");
    
    final String[] wsdlArgs = 
      {
      // output directory. 
      "-o", outputDir.getAbsolutePath()
      // emit server-side bindings for web service
      ,"-s"
      // add scope to deploy.xml: "Application", "Request", "Session"
      // 'Application' means that the Axis server keeps the service alive
      // once instantiated.
      ,"-d","Application"
      // WSDL file we're using to create deployment descriptor
      ,wsdlFile.getAbsolutePath()
      };

    // Create output dir if it doesn't exist
    if (! outputDir.exists())
      {
      outputDir.mkdirs();
      }
    
    // Print out the arguments we're going to use
    for (int i=0; i < wsdlArgs.length; i++)
      {
      System.out.println(wsdlArgs[i]);
      }
    
    // Now call org.apache.axis.wsdl.Java2WSDL and see what happens
    org.apache.axis.wsdl.WSDL2Java.main(wsdlArgs);
    
    // We never get to this line - WSDL2Java calls System.exit()....
    
    }
}


When run this program will either produce error messages from Axis or terminate without saying anything at all. Checking the directory we should see our WSDD files:

WSDD files for Oracle Web Service

deploy.wsdd contains the much of the same information that C:\OrindaTemp\orindademo.wsdl does, but in a different format.



undeploy.wsdd
is much smaller because it doesn't have to define how the service should work, only that it should be removed.

Also visible will be a large number of Java files. They are a 'default server implementation' - files that have the right methods but don't actually do anything. Because we have used JDBCWizard we already have all the code we need and do not need them. Do not let these Java files into your CLASSPATH and whatever you do don't create them in the same project as your JDBCWizard generated code.

Configure Apache Axis - Deploy the generated application


File C:\JDBCWizard.emo\Src\com\orindasoft\demo\WsRunAdminClient.java
package com.orindasoft.publishdemo;

public class WsRunAdminClient {

    public static void main(String[] args) {

    final java.io.File outputDir = new java.io.File("c:\\OrindaTemp");

    final java.io.File wsddDir
       = new java.io.File(outputDir,"com\\orindasoft\\demo\\generated");

    final java.io.File wsddFile = new java.io.File(wsddDir,"deploy.wsdd");
    
    final String[] wsddArgs = 
      {
      // The name of the deploy.wsdd file.
      wsddFile.getAbsolutePath()
      };
    
    System.out.println("Trying to deploy:");
    System.out.println(wsddFile.getAbsolutePath());
    
    // Now call org.apache.axis.wsdl.Java2WSDL and see what happens
    org.apache.axis.client.AdminClient.main(wsddArgs);
    
    // We never get to this line - AdminClient calls System.exit()....
    
    }
}


When run this program should produce output like this:



Trying to deploy:
c:\OrindaTemp\com\orindasoft\demo\generated\deploy.wsdd
Processing file c:\OrindaTemp\com\orindasoft\demo\generated\deploy.wsdd
<Admin>Done processing</Admin>

The "Done Processing" message is a good sign but does not mean that the deployment succeeded.



Test your web service

See if the Web Service is listed by Apache Axis

The first step in testing our web service is to see if it shows up in Axis's list of services, which in our case is at the URL http://localhost:8080/axis/servlet/AxisServlet. If everything is working we'll see the following:



http://localhost:8080/axis/servlet/AxisServlet

And now... Some Services

  • AdminService (wsdl)
    • AdminService
  • Version (wsdl)
    • getVersion
  • ORINDADEMO (wsdl)
    • serviceSequenceSequentialNumberGenerator
    • servicePlsqlComplexExampleAddBookings
    • servicePlsqlComplexExampleFliesBetweenAll
    • servicePlsqlComplexExampleGetTableOfFlightsFrom
    • servicePlsqlSimpleExamplesDirectFlightAvailable
    • servicePlsqlSimpleExamplesFindDirectFlights
    • servicePlsqlSimpleExamplesGetlists
    • serviceSqlDemoAddCust
    • serviceSqlDemoDeleteCustomers
    • serviceSqlDemoGetFlights
    • serviceSqlDemoMakeBooking
    • serviceSqlDemoTruncateBookings
    • serviceSqlDemoUpdCust

Create a Client version of the generated code using the WSDL URL provided by Apache Axis

We should now be able to write a client program to use our web service. 'WsCreateClient.java' is very similar to 'WsRunWsdl2Java', the main difference being that it uses the service URL instead of a WSDL file. We also generate the code to a new location - 'c:\\OrindaDemoClient'. This is because we'll create a third project in our IDE to test the Web Service end to end.


 

File C:\JDBCWizard.emo\Src\com\orindasoft\demo\WsCreateClient.java
package com.orindasoft.publishdemo;

public class WsCreateClient {

    public static void main(String[] args) {

    final java.io.File outputDir = new java.io.File("c:\\OrindaDemoClient");

    final String wsdlURL = "http://localhost:8080/axis/services/ORINDADEMO?wsdl";
    
    final String[] wsdlArgs = 
      {
      // output directory. 
      "-o", outputDir.getAbsolutePath()
      // emit server-side bindings for web service
      ,"-s"
      // add scope to deploy.xml: "Application", "Request", "Session"
      // 'Application' means that the Axis server keeps the service alive
      // once instantiated.
      ,"-d","Application"
      // WSDL file we're using to create deployment descriptor
      ,wsdlURL
      };

    // Create output dir if it doesn't exist
    if (! outputDir.exists())
      {
      outputDir.mkdirs();
      }
    
    // Print out the arguments we're going to use
    for (int i=0; i < wsdlArgs.length; i++)
      {
      System.out.println(wsdlArgs[i]);
      }
    
    // Now call org.apache.axis.wsdl.Java2WSDL and see what happens
    org.apache.axis.wsdl.WSDL2Java.main(wsdlArgs);
    
    // We never get to this line - WSDL2Java calls System.exit()....
    
    }
}

 

When run for the first time this program should terminate without any messages from Apache Axis. If you want to run it again you'll need to delete the code it created to avoid a 'ORINDADEMOSoapBindingImpl.java already exists, WSDL2Java will not overwrite it.' message.



Testing your generated  Apache Axis client software

We should now be able to run an end-to-end test. Since we want to show that we really are using the web service and not logging into the database we'll create a third project in our IDE that doesn't have a JDBC driver or JDBCWizard libraries in its CLASSPATH.  Note that we fix it so that the project is pointed at the code we just generated in C:\OrindaDemoClient.


create client project to run pl/sql procedures using apache axis

We then have to set up the libraries for our test client project. We import all the Apache Axis libraries but do not import an Oracle JDBC driver, the generated code or the OrindaSoft com.orindasoft.pub libraries.



Libraries for Apache Axis and Oracle

To test our Web Service we create a runnable class in com.orindasoft.demo:

File C:\OrindaDemoClient\com\orindasoft\demo\AxisTestClient.java
package com.orindasoft.demo;

import java.util.GregorianCalendar;

import com.orindasoft.demo.generated.*;
import com.orindasoft.demo.generated.plsql.*;
import com.orindasoft.demo.generated.sql.*;

public class AxisTestClient {

public static void main(String[] args)
  {
  try
    {
    DAOFactoryServiceInterfaceServiceLocator locator = new DAOFactoryServiceInterfaceServiceLocator();
        
    DAOFactoryServiceInterface theWebService = locator.getORINDADEMO();
        
    // Try and get some database sequence numbers...
    System.out.println("Try and get some database sequence numbers...");
    
    long aSeqno = Long.MIN_VALUE;
    
    for (int i=0; i < 3; i++)
      {
      aSeqno = theWebService.serviceSequenceSequentialNumberGenerator();
      System.out.println("Got sequence number of " + aSeqno + " from Oracle via web service");
      }    
    
    // Now call a service which returns lists of airlines, airports and
    // aircraft types. Note that JDBCWizard created Java record classes
    // for each.
    
    
    System.out.println("");
    System.out.println("Try calling a PL/SQL procedure that returns 3 lists...");
    System.out.println("");
   // 'SimpleExamplesGetlistsReturn' is a record created because the 
    // service has more than one output parameter and we're in an 
    // environment where the 'functions can not modify their parameters' 
    // rule is taken seriously.
    SimpleExamplesGetlistsReturn theList 
     = theWebService.servicePlsqlSimpleExamplesGetlists();
    
    // Unload theList so we can see what's inside
    
    // First get airport list.
    // Some of these airports are very obscure regional airfields...
    SimpleExamplesAirportRefcursorTypeAttrs[] theAirports 
      = theList.getParamPAirportListing();
    System.out.println("Got " + theAirports.length + " airports");
    System.out.println("Second Airport on list is " 
              + theAirports[1].getParamAirportCode() + ": "
              + theAirports[1].getParamAirportName());
    System.out.println("Last Airport on list is " 
              + theAirports[theAirports.length-1].getParamAirportCode() + ": "
              + theAirports[theAirports.length-1].getParamAirportName());
  
    // Now get airline list
    OrindademoSimpleExamplesAirlineRefcursorTypeAttrs[] theAirlines 
       = theList.getParamPAirlineListing();
    System.out.println("");
    System.out.println("Got " + theAirlines.length + " airlines");
    System.out.println("First Airline on list is " 
              + theAirlines[0].getParamAirlineName());
    System.out.println("Last Airline on list is " 
              + theAirlines[theAirlines.length-1].getParamAirlineName());

    // Now get airplane type list
    SimpleExamplesAircraftRefcursorTypeAttrs[] theAirplanes 
       = theList.getParamPAircraftListing();
    System.out.println("");
    System.out.println("Got " + theAirplanes.length + " airplane types");
    System.out.println("First Airplane on list is " 
              + theAirplanes[0].getParamAircraftType());
    System.out.println("Last Airplane on list is " 
              + theAirplanes[theAirplanes.length-1].getParamAircraftType());

    // Now show how we can add stuff to the database - create a
    // new customer with what should be a unique name...
    String newUserName = "John Citizen " + aSeqno;
    
    System.out.println("");
    System.out.println("Now call a SQL insert statement...");
    System.out.println("About to add '" + newUserName + "' as a customer...");
    theWebService.serviceSqlDemoAddCust(newUserName
                                       ,"1 Random Way"
                                       ,"Vista Point"
                                       ,"CA", 94583
                                       , new GregorianCalendar(1967,11,5)
                                       , "555 1212");
    System.out.println(newUserName + " added.");
    
    System.out.println("");
    System.out.println("Now call a PL/SQL procedure that takes records as parameters");

    // JDBCWizard can write code for complex stored procedures that
    // take records (such a %ROWTYPE) as parameters.
    // 'ComplexExampleFliesBetweenAll' takes 3 different kinds of records
    // as input parameters. It was created to show how JDBCWizard supports
    // the different PL/SQL record types but is also excellent for showing
    // how JDBCWizard generated code can be turned into a web service. All
    // the record types used were created by WSDL2Java.
    
    // The first parameter is an Oracle TYPE record representing a city pair
    CityPairOracleTypeAttrs cityPair 
       = new CityPairOracleTypeAttrs();
    cityPair.setParamFromCity("SFO");
    cityPair.setParamToCity("LAX");

    // the second parameter is a PL/SQL Package record which also
    // represents a city pair
    ComplexExampleCityPairPlsqlRecordAttrs cityPair2 
       = new ComplexExampleCityPairPlsqlRecordAttrs();
    cityPair2.setParamFromCity("LAX");
    cityPair2.setParamToCity("ORD");
    
    // The remaining parameters are %ROWTYPE records, which mimic the
    // structure of the AIRPORTS table.
    AirportsAttrs city3a = new AirportsAttrs();
    city3a.setParamAirportCode("ORD");
    city3a.setParamAirportName("Chicago O'Hare");
    
    AirportsAttrs city3b = new AirportsAttrs();
    city3b.setParamAirportCode("SFO");
    city3b.setParamAirportName("San Francisco");
    
    // We don't need a 'Return' class because only one 
    // thing is being returned. 'flysAll' is a list of
    // all airlines that fly between San Francisco/Los Angeles, 
    // Los Angeles/Chicacgo and Chicago/San Francisco
    System.out.println("Getting list of airlines that fly between");
    System.out.println("");
    System.out.println("San Francisco/Los Angeles, Los Angeles/Chicacgo");
    System.out.println("and Chicago/San Francisco");
    SimpleExamplesAirlineRefcursorTypeAttrs[] flysAll 
          = theWebService.servicePlsqlComplexExampleFliesBetweenAll
          (cityPair, cityPair2, city3a, city3b);    
    
    System.out.println("");
    System.out.println("List has " + flysAll.length + " airlines:");
    for (int i=0; i < flysAll.length; i++)
      {
      System.out.println(i+1 + ": " + flysAll[i].getParamAirlineName());    
      }    
        
    }
  catch (DAOFactoryServiceException e)
    {
    System.err.println(e.getFaultString());
    }
  catch (Exception e)
    {
    System.err.println(e.getMessage());
    }
  }
}


When run we get the following output:

Try and get some database sequence numbers...
Got sequence number of 106 from Oracle via web service
Got sequence number of 107 from Oracle via web service
Got sequence number of 108 from Oracle via web service

Try calling a PL/SQL procedure that returns 3 lists...

Got 986 airports
Second Airport on list is 0S9: Port Townsend, WA (0S9)
Last Airport on list is ZTM: Shamattawa, MB, Canada (ZTM)

Got 386 airlines
First Airline on list is ACM Air Charter
Last Airline on list is bmiBaby

Got 176 airplane types
First Airplane on list is A124
Last Airplane on list is Twin Beech 18/Super H18

Now call a SQL insert statement...
About to add 'John Citizen 108' as a customer...
John Citizen 108 added.

Now call a PL/SQL procedure that takes records as parameters
Getting list of airlines that fly between

San Francisco/Los Angeles, Los Angeles/Chicacgo
and Chicago/San Francisco

List has 1 airlines:
1: United


The program above demonstrates how JDBCWizard makes it easy to implement web services with Oracle.



Next Steps

Once you've got your first Axis Web Service to work you should consider the following:

Use JNDI for database Connections - JNDI is a far better way of managing database connections than hard coding a connect string like we did in our demo.

Use Log4J for logging - Log4J or java.util.logging are both options for generated code. Using a built in logging protocol will make integrating generated code much easier.

Allocate appropriate amounts of memory for your Web Server - The Java Virtual Machine defaults aren't big enough in most cases.

Make a list of PL/SQL stored procedures and SQL statements you want in your web service - Many existing PL/SQL procedures will probably be usable in a web service without modification. By examining existing application code you will be able to find the SQL statements that drive your application and make copies of them that are usable by JDBCWizard.