tisdag, november 27, 2007

Building a Web Service from a XSD using JDeveloper 11

A few days ago I wrote a post about building a Web Service from a XSD using JDeveloper 10.1.3.3. As a result of this I got a mail from Gerard Davison who informed me that this will be even easier in JDeveloper 11 using the WSDL editor and the top down generator:
  1. Create a new WSDL
  2. Put the XSD somewhere nearby in the project
  3. Tile the editors
  4. Pick up the country info element and drop in the empty "PortType" column. The tool will prompt you for the name of the portType, and generate a single operation that takes this types as the input and output message.
  5. Pick up and drop the portType on the binding, then the new binding on the services column. You should now have a valid WSDL
  6. Now use the generate Java web service from WSDL wizard.
This will now generate all the right code and binding classes in one step without you needing to do any JAXB work.

Thanks a lot for the information Gerard!

It also turns out that we are having a demo for this on OTN, check the one under 'WSDL Editor New Features'.

fredag, november 23, 2007

Some Notes on the XX:AppendRatio JVM Parameter

If you install the Oracle Application Server 10.1.3.1+ you will see that the JVM parameter -XX:AppendRatio=3 is set for the OC4J instance by default, however there is not much describing it in the documentation, and it might not be exactly clear from its name what it is used for.

The only entry in the Oracle documentation is found in the Oracle Application Server Performance Guide 10g Release 3 (10.1.3.1.0), Chapter 3 - Top Performance Areas where we say that:

"With the Sun 5.0 JVM, under some circumstances under heavy load, synchronization in an application can result in thread starvation. This may cause some requests for an application to appear hung or to timeout after a long time.

In 10g Release 3 (10.1.3.1.0) the parameter: -XX:AppendRatio=3 is specified by default for managed OC4J. For standalone OC4J, if you believe your installation has this problem, we recommend setting the JDK parameter: -XX:AppendRatio=3 to avoid this problem."

There is also a reference to the Sun JVM Bug Database entry 4985566 that describes the details of the problem.

However, there is a better description of the problem and the purpose in the Sun JVM Bug Database entry 6383015.

Here the purpose of the parameter is described as: "The VM option -XX:AppendRatio=N can be used to control how often an append is done rather than an append. If set to 0 then every enqueue will be an append and the observed behaviour will be 'fair' if desiring FIFO like ordering."

It then continues a bit down with: "In 1.5.0 the monitor queuing policy is 'mostly prepend', which is essentially LIFO except that every N queue additions are done as an append rather than a prepend. Prepending yields better throughput/performance by trying to allow the most recently blocked thread to run next in the expectation that it will still have a warm cache etc."

So, with this is mind we can go to the following conclusions:

  • If the XX:AppendRatio parameter is unset in JDK 1.5 then the monitor queuing policy will be LIFO. This might cause some threads to be treated unfair, and lead to starvation.
  • If the XX:AppendRatio parameter is set to 0 then the monitor queuing policy will be almost like FIFO, however 100% FIFO is not guaranteed as described in bug 4985566 above.
  • If the XX:AppendRatio parameter is set to 3 then each 3:rd queue addition is done as an append rather than a prepend. This will take some advantage of the performance benefits using LIFO, but it will better ensure fairness trying to prevent thread starvation.

So, I hope this have given you a better understanding of what the XX:AppendRatio JVM Parameter does and why it is set by default when installing the Oracle Application Server 10.1.3.1+.

torsdag, november 22, 2007

Building a Web Service from a XSD using JDeveloper

Yesterday I was asked how to create a Web Service from a XSD file using JDeveloper by a colleague, so I thought I'd might share the answer I gave to a wider audience. Hopefully someone else out there might also have some use for it.

The purpose of this example is to show how you can build a Java Web Service starting with only a single XSD file using JDeveloper.

1. Create an empty project in JDeveloper (I used version 10.1.3.3).

2. Add the XSD to your project, in this example I use an XSD that looks like:

<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/pcbpel/CountryInfo"
elementFormDefault="qualified">
<element name="CountryInfo">
<complexType>
<sequence>
<element name="Country" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="Name" type="string"/>
<element name="Capital" type="string"/>
<element name="Area" type="decimal"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>

3. Select the XSD in the Applications Navigator

4. Select Tools -> JAXB Compilation from the Menu

5. Now you have JAXB generated Java classes based on your XSD in your project. This is described more in:

http://www.oracle.com/webapps/online-help/jdeveloper/10.1.3?navId=4&navSetId=_&vtTopicFile=working_with_xml/xml_pjaxb.html

6. Create a new Java class, this is the class that will be the Web Service

7. In this class create a method (this will be exposed as a Web Service method) it has a javax.xml.soap.SOAPElement as input parameter and void as return value, like:

public void testMethod(javax.xml.soap.SOAPElement myDoc)

8. In the method body, add code to unmarshal the document and in this example just write it to System.out:

try {
JAXBContext jc = JAXBContext.newInstance("project3");
Unmarshaller u = jc.createUnmarshaller();

CountryInfo countryInfo = (CountryInfo)u.unmarshal(myDoc);
List lst = countryInfo.getCountry();

for(Iterator iter = lst.iterator(); iter.hasNext();) {
CountryInfo.CountryType country = (CountryInfo.CountryType)iter.next();
System.out.println( country.getName() + ", " + country.getCapital());
}
}
catch (JAXBException je) { je.printStackTrace(); }


9. Start the Java Web Service wizard from the New Gallery, select the newly generated class and just use the default values in the Wizard, except for SOAP Format, here use Document/Literal.

10. Before deploying the Web Service, make sure that all needed files are included in the deployment profile.

11. Once done, either deploy the Web Service to an Application Server or standalone OC4J instance and test it using XML like:

<?xml version="1.0" encoding="UTF-8" ?>
<CountryInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oracle.com/pcbpel/CountryInfo src/xsd/CountryInfo.xsd"
xmlns="http://www.oracle.com/pcbpel/CountryInfo">
<Country>
<Name>Sweden</Name>
<Capital>Stockholm</Capital>
<Area>1.0</Area>
</Country>
</CountryInfo>

this should give the following printed to System.out:

07/11/22 12:29:31 Sweden, Stockholm

fredag, november 16, 2007

Don't Forget of the Permanent Generation...

This week I was at a customer where we would install a SOA Suite server and deploy quite a lot of BPEL processes onto it. Most things went fine until the end of the deployment where we encountered a problem: java.lang.OutOfMemoryException, I was first a bit confused since we had assigned 2Gb of memory to the JVM - so how could that be?

Simple, I forgot about the Permanent Generation Size, and this post is my equivalent of writing it on the black board 100 times in order to remind myself to not forget about it again in the future...

We solved the problem by adding these 2 JVM parameters:

-XX:PermSize=256 -XX:MaxPermSize=256m

So, what do they do?

The permanent generation is allocated outside of the normal heap and holds objects of the VM itself such as class objects and method objects. If you have programs that load many classes (like deployment of many BPEL processes in a batch), you may need a larger permanent generation.

Since the sizing of this is done independently from the other generations, this means that even if you setup a heap of 2Gb, you might still encounter problems in the permanent generation cause if you do not specify this it will fallback on the defaults .

Why are they set to the same value above? Simply because we want to minimize large garbage collection here.

Once we had reconfigured the OC4J instance with these settings the deployment went fine.