As promised in my posting about EJB3 webservices, I will explain in this blog how you can implement a client for the EJB3 webservice using the Apache Axis2 framework.
Axis2 is build on the Apache Axiom, which is a pull based XML object model. Due to Axiom Axis2 is more efficient in processing XML documents than its previous version Axis 1.0 that uses DOM to process XML messages. Large XML documents may cause out-of-memory errors when using Axis 1.0. Axis2 also supports, besides SOAP 1.1 en 1.2, REST-style webservices and it enables synchronous and asynchronous webservice calls. The ability to perform asynchronous webservice calls overcomes the problem of time-out errors, which occur when a webservice call has to wait too long for a server response. See the Axis home page for more details on its abilities and disabilities. In this posting, I will show you how to generate the client stub code using Ant and how the webservice call is made using the generated client code.
The Axis2 distribution is delivered with a WSDL2Java tool to generate the client stub code for a given WSDL file. Although Axis2 provides a build in ANT task, as Axis1.0 did, I did not use
it because I did not get it to work and read on the internet that others had the same problems in getting the build-in Ant task work. So instead of the ANT task, I used the standaard Java exec task to directly invoke the WSDL2Java tool. Here’s the Ant task that generates the client stub code for my Customer service:
<target name="wsdl2java">
<delete dir="${axis.generated.dir}" />
<java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true">
<classpath refid="tools.classpath"/>
<arg value="-uri"/>
<arg line="http://localhost:8888/customerService/CustomerFacade?WSDL"/>
<arg value="-s"/>
<arg value="-d"/>
<arg value="xmlbeans"/>
<arg value="-o"/>
<arg file="${axis.generated.dir}"/>
<arg value="-p"/>
<arg value="nl.iteye.ws.stub"/>
</java>
</target>
You can see in the Ant task definition that I set several command-line options for the WSDL2Java tool. Look here to see a complete a list of possible options. I have chosen to only generate code for synchronous calls (-s option) and to use Apache XMLBeans as the XML binding mechanism. Instead of XMLBeans, I could also used the Axis2 Databinding framework (adb), but I found XMLBeans more intuitive in its use. I also specified the output directory for the generated files (-o option) and the package name for the stub classes(-p option).
With generated stub code it’s quite easy to make the webservice call:
/**
* Retrieve all the customers
* @return all customers
*/
public List findAllCustomers() throws Exception {
CustomerServiceStub stub = new CustomerServiceStub();
FindAllDocument input = FindAllDocument.Factory.newInstance()
FindAllResponseDocument resp = stub.findAll(input);
com.oracle.www.webservices.internal.literal.List oralist = resp.getFindAllResponse().getReturn();
List retList = Arrays.asList(oraList.getItemArray());
return list,
}
I first made an instance of the stub class for our webservice. With the code-fragment below
FindAllDocument.Factory.newInstance()
I made the XML document that serves as the input for the webservice function. In this case the document is empty, because the findAll function does not expect an input argument here. The call to the findAll webservice returns an FindAllResponseDocument, which contains the FindAllResponse document that in turn contains the return document. This completely resembles the XSD structure of the messages in the WSDL file. Because the return type of the findAll function is an Oracle litaral List type, I have to convert it to a regular Java List type.
Although Axis2 works without problems in this example, it has some limitations. One of the limitations of Axis2 is that it doesnot support rpc/encoded WSDL documents yet in its stub-code generation process. In my current project, we are using mainly rpc/encoded WSDLs so we are still using Axis1.0 despite its problems with processing large XML documents. Despite the current limitations of Axis2 it certainly have great features in it to become a very usefull Webservice framework.
Posted July 30th, 2006 by | 1 Comment »
We are currently running into a problem with ADF Faces which seems to cause many people headaches: being unable to easily specify which form element needs to get focus after leaving a field which uses partial page rendering (aka PPR, aka AJAX).
After an autoSubmit the focus is returned to the field which caused the autoSubmit. This means that the user usually has to hit the tab key twice to get to the next field. Once to leave the first field and cause the autoSubmit, and then a second time to go to the next field when the ppr call is finished.
For more complaints about tab handling in ADF Faces visit the oracle Forums: Setting field focus after PPR event. Lots of frustration in this thread (and very little help from Oracle). Robert Willems of Brilman proposed a solution in his blog entry: Focussing conditionally in a table after a partial page refresh.
The page i’m working on is a bit different, which caused some extra problems. The page, a simple version is displayed below, uses a lot of autoSubmits. All input fields are autoSubmit, changing the first field causes the second and third field to be reset, and the second dropdown list to be refilled. The second field causes the third field to be reset. And the values of all fields are immediately displayed in the table below after leaving a field.

The problem with this construction is that one PPR causes others. For example, when you leave the first field, the second field is redrawn, which causes the third field to be updated. So if you put PPR triggered javascript on all of these fields leaving the first dropdown will first put the focus in the second dropdown which will then cause the focus to be put in the third field. Not really what you want.
The trick is to have only one tag of PPR triggered javascript, at the end of the page. This javascript will be triggered when all other PPR updates are finished. In our case we now just return the focus to where the user put it, i.e., in the next field. You can remember the last focus by putting a onFocus trigger on every field.
< ?xml version='1.0' encoding='UTF-8'?>
<jsp :root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:af="http://xmlns.oracle.com/adf/faces"
xmlns:afh="http://xmlns.oracle.com/adf/faces/html">
<jsp
utput omit-xml-declaration="true" doctype-root-element="HTML"
doctype-system="http://www.w3.org/TR/html4/loose.dtd"
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
<jsp :directive.page contentType="text/html;charset=UTF-8"/>
<f :view>
<afh :html>
</afh><afh :head title="Test PPR + focus">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</afh>
<afh :body>
<afh :script text="var focusItem;
function setCurrentFocus(item){
focusItem = item.id;
}
function setNextFocus(){
var el = document.getElementById(focusItem);
if(el){
el.focus();
}
}
"/>
<h :form id="productform">
<af :panelHeader text="Enter product">
</af><af :panelForm >
</af><af :selectOneChoice label="Product"
value="#{Page1Backing.product}"
id="productlov" autoSubmit="true"
onfocus="setCurrentFocus(this);">
<f :selectItems value="#{Page1Backing.products}"/>
</af>
<af :selectOneChoice label="Unit" value="#{Page1Backing.unit}"
id="unitlov" autoSubmit="true"
partialTriggers="productlov"
onfocus="setCurrentFocus(this);">
<f :selectItems value="#{Page1Backing.units}"/>
</af>
<af :inputText label="Amount" value="#{Page1Backing.amount}"
id="amounttext" partialTriggers="unitlov"
autoSubmit="true"
onfocus="setCurrentFocus(this);"/>
<af :panelHeader text="Overview"/>
<afh :tableLayout borderWidth="1">
</afh><afh :rowLayout>
<af
utputText value="#{Page1Backing.amount}"
partialTriggers="amounttext" inlineStyle="padding: 3px;"/>
<af
utputText value="#{Page1Backing.unit}"
partialTriggers="unitlov" inlineStyle="padding: 3px;"/>
<af
utputText value="#{Page1Backing.product}"
partialTriggers="productlov" inlineStyle="padding: 3px;"/>
</afh>
</h></afh>
<afh :script text="setNextFocus();"
partialTriggers="productlov unitlov amounttext"/>
</f>
</jsp>
This bit of code restores normal focus sequence.
Posted July 28th, 2006 by Andrej Koelewijn | 9 Comments »
A couple of days ago I received the challenge to create a calendar in Oracle Application Express, APEX for short (formerly known as HTML DB). The only restriction I had was that the calendar must support the function to be across days. With my Oracle experience I thought to be able to create a SQL statement with a simple between where clause to meet the requirements. Well, that wasn’t the case.
APEX support calendars that are based on a single date column from a table or a SQL selection with at least one date column in the result set. That means if you would like to create a calendar across days, like me, you have to write a SQL statement that selects a record for every day that exists within the date range of your start date and end date.
Suppose I have the following table definition. The table contains a column for my description of an event, a start date and an end date. The table is uniquely identified by a primary key.
CREATE TABLE EVENTS_CAL
(
ID NUMBER NOT NULL,
DESCRIPTION VARCHAR2(100) NOT NULL,
START_DATE DATE NOT NULL,
END_DATE DATE
, CONSTRAINT EVENTS_CAL_PK PRIMARY KEY (ID)
)
;
The table contains these fictitious records:
| ID |
DESCRIPTION |
START_DATE |
END_DATE |
| 1 |
Oracle Open World |
24-10-2006 |
31-10-2006 |
| 2 |
IT-eye seminar SOA |
01-10-2006 |
|
| 3 |
Business meeting Amsterdam |
01-10-2006 |
03-10-2006 |
I would like to incorporate these events into the calendar. For each day, starting with the start date, I would have an entry in my APEX calendar. The lack of an end date means the event is a single day event.
I had to write a SQL statement that generates a record for each date between the start date and the end date. The query below shows how to do that. I first post the query before I explain it in detail.
select res1.description description
, res1.start_date + (res1.curr_row - 1) calendar_date
, res1.days_between days_between
from (
select res2.id id
, res2.description description
, res2.start_date start_date
, res2.days_between days_between
, row_number() over (partition by res2.id order by res2.start_date) curr_row
from (
select id id
, description description
, start_date start_date
, (nvl(end_date, start_date) - start_date) + 1 days_between
from events_cal
) res2
, user_tables uts
) res1
where res1.curr_row <= res1.days_between
order by 2, 3
Looking at the most inner query I extend the result set with a days_between column. This column calculates the days between the start date and the end date. The result must be raised by one to allow single day events. sysdate – sysdate equals zero, that’s why.
The inline view with alias res2 is joined with a table that contains at least the amount of records which equals the maximum number of days_between. Without any restriction these two from clause objects are combined into a Cartesian product, but that’s exactly what we need. The join with user_tables in this case is only needed to generate the necessary amount of records for the calendar days. Another (application) table can be used as well.
The analytic function row_number() in the result set of the second inline view with alias res1 is used to identify every record with an increasing number. Due to the partition over clause, the increasing number is reset every unique occurrence of the primary key with the Cartesian product.
With this information available it is easy to restrict the result set with only those records that have a current row indicator which is equal or less the days_between value.
We now have a record for each day within the range of start date and end date. Now we only have to assign an increasing date, starting with the start date for each record in the result set. This is solved with a small computation of start_date plus the current row minus one.
Executing the query against my events_cal table results into the following result set:
| DESCRIPTION |
CALENDAR_DATE |
| IT-eye seminar SOA |
01-10-2006 |
| Business meeting Amsterdam |
01-10-2006 |
| Business meeting Amsterdam |
02-10-2006 |
| Business meeting Amsterdam |
03-10-2006 |
| Oracle Open World |
24-10-2006 |
| Oracle Open World |
25-10-2006 |
| Oracle Open World |
26-10-2006 |
| Oracle Open World |
27-10-2006 |
| Oracle Open World |
28-10-2006 |
| Oracle Open World |
29-10-2006 |
| Oracle Open World |
30-10-2006 |
| Oracle Open World |
31-10-2006 |
Incorporation of the selection into the calendar definition in APEX turns into a nicely filled calendar. Unfortunately the calendar definition within APEX cannot guarantee a fixed ordering, even though our SQL statement has an order by expression. I am wondering if someone knows a proven method how to guarantee a fixed ordering for the calendar?
Finally, our calendar is completed.

I hope you liked this blog and get some benefit from it.
Posted July 19th, 2006 by Rene Wiersma | 7 Comments »
I’m these days more interested in books that try to make the Software Development Process world a better world than it is now, instead of reading books about some new programming language or framework. However, I do think the last part of books is still valuable but I’m convinced that reading only these kind of books will not improve you as a developer but only makes a kind of walking programming- wikipedia from you. This will not mean that i hate technology oriented books, I still love to dive into a the technology to gain some programming experience with it.
In this contrast, I bought Steve McConnells Rapid Development. Another reason that I have bought this book is that I was left with a great feeling after reading his classic on software engineering: Code Complete. The cover explains clearly what this book is all about:
“..In Rapid Development, Steve McConnell addresses the concern to get high pressure development schedules under control with head-on strategies, specific best practices, and valuable tips that help to shrink and control development schedules.”
Steve McConnell starts with explaining what he means with the term Rapid Development, and more important what he does not mean with it. In the first two chapters, he explains what Rapid Development is about and what concepts and kind of strategies are needed to attain Rapid Development in a project. The rest of the book is structured like code complete, you can just pick a chapter of interest and start reading it without loosing the whole story (that’s oulined in the first two chapters). The book handles topics on classic mistakes, development fundamentals, risk management and schedule-oriented practices. In the end of the book, Steve explains a large set of best practices to achieve in rapid development that may be suitable to your project.
I am convinced that this book is suitable for everyone who is involved in Software Development, because it is not a book that must be read from the beginning to the end to pick up the message. As said before, you can read the first two introduction chapters to understand the subject and goal of the book, and than select you own chapters. So the project manager will probably be interested in risk-management chapters, while the technical project leader is more interested in development fundamentals.
Despite the age of the book (1996), I think the concepts, practices and ideas in the book will help me in my daily work nowadays.
Order it and judge for yourself
Posted July 12th, 2006 by Tom Hofte | No Comments »