During a recent project we encountered a strange problem. When invoking a Partner Link that is defined towards a Web Service that has both SOAP 1.1 and SOAP 1.2 endpoints defined we got a Version Mismatch fault back. This was quite unexpected, and I assumed that doing some searches on the famous search engine using terms like 'VersionMismatch Oracle BPEL' would yield some relevant hits, but it didn't.
Suppose that you have created a Web Service that have multiple ports and bindings, for example, you have both a SOAP 1.1 and a SOAP 1.2 endpoint defined for the Web service. You have also tested the Web Service using a plain Java Client and that works fine. However, when you try to invoke the Web Service as a Partner Link from BPEL you get the following exception instead of the (expected) result:
<fault>
<remoteFault xmlns="http://schemas.oracle.com/bpel/extension">
<part name="code">
<code>VersionMismatch</code>
</part>
<part name="summary">
<summary>Version Mismatch</summary>
</part>
<part name="detail">
<detail>null</detail>
</part>
</remoteFault>
</fault>
It doesn't matter which endpoint (the SOAP 1.1 or the SOAP 1.2) you define the Partner Link to use. You end up with the exception in both cases. At a first glance it looks like BPEL is either sending a SOAP 1.1 message to the SOAP 1.2 port or sending a SOAP 1.1 message to the SOAP 1.2 port. If this occurs then the SOAP spec requires that a "Version Mismatching" fault is raised for such usage; but if this was the case - why does the error occurs regardless of which endpoint that is chosen???
Also, if you remove either of the ports & bindings from the Web Service WSDL (it doesn't matter which one) and then configures the Partner Link to use the other one, all works fine.
I do not have an explanation for this error, and have only tested it on Oracle SOA Suite 10.1.3.3.
However, there is an easy workaround to the problem:
- Download 2 local copies to your project of the WSDL for the Web Service.
- Remove one port & binding (not the same...) from each of the local WSDL copies.
- Define 2 Partner Links in your BPEL project, one based on each of the local WSDL copies.
- Implement a Switch to invoke the appropriate Partner Link in your BPEL process.
If you just have the need to invoke either of the endpoints, you of course just need to create one local copy, remove one of the ports & bindings and use this local copy of the WSDL for the Partner Link.
A common problem that occurs when working with Web Services is how-to maintaining changes to the WSDL and/or XSD files that are used by the service. The problem occurs when performing changes to the WSDL (or XSD) files like removing operations, renaming operations, changing the structure of data types etc. As you might always not be aware of which clients that are using your service(s); you want to make sure that they continues to work even after you have implemented changes to your service. As support for dealing with this has not been built into the Web services architecture / standards; it is basically left to each implementer to deal with this problem.
One way of dealing with this problem is to use Namespaces versions. The approach for this is as:
1. Use different XML namespaces for different version of the service.
2. Send a specific namespace value along with every SOAP message and result.
3. Based on this value a Web Service implementation (mediator) can then correctly determine what to do with the incoming message.
You first need to ensure that the namespace for the XML elements resulting from that document is unique, for example, suppose that you now are using a namespace like:
targetNamespace="http://example.com/mySchema.xsd".
You then need to change this to:
targetNamespace="http://example.com/2007/11/01/mySchema.xsd"
Where the numbers are year, month and date (it is not likely that you will alter the namespace more than once a day...).
Now each request will be accompanied with a reference to a namespace thus leaving it up to the Web Services to deal with what to do with requests that come in for any particular namespace.
Next thing is to decide what to do with the various types of incoming requests. One approach here is to generate an error if a request for an older namespace is received, and leave it up to the client to deal with this. Another approach is to use a mediator, as mentioned earlier in the post. The task of the mediator is to determine what to do with Web service requests that come in for any particular namespace. This is done by examination of the date stamp on the namespace (introduced in the previous steps) and then route requests from the older namespace to the older version of the Web service, while routing requests from the newer namespace to the new version of the Web service. This means that the URL to the Web Service (the mediator) will always be the same to your external clients, while you are routing it to different services internally.
As a mediator you could either use a Web Service that you write the code yourself for to handle this, or you could look into using our ESB (Enterprise Service Bus) product for this task.
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:
- Create a new WSDL
- Put the XSD somewhere nearby in the project
- Tile the editors
- 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.
- Pick up and drop the portType on the binding, then the new binding on the services column. You should now have a valid WSDL
- 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'.
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+.
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
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.
"Cluster - a number of things of the same kind, growing or held together; a bunch: a cluster of grapes.".
This is how a cluster is defined in the dictionary (http://dictionary.reference.com). Not a particularly exact definition, at least not to me. Then, one often hears that a SOA Suite installation runs in a 'cluster'. But what does this actually means? The definition did not give a particularly good definition. Also, as there are several ways to connect instances together to form a cluster it could be good to know exactly which way that is used in each case. There are (at least) four different ways to form a cluster in Oracle SOA Suite 10.1.3.1+ ; these are:
- ONS Topology
- OC4J Group
- BPEL JGroup Config
- OC4J Session Replication
Let's now discuss them more in detail.
ONS Topology
This is a group of Oracle Notification Server (ONS) in a farm configured to run in same topology. Basically; two or more loosely connected Oracle Application Server nodes. You can create this by using either of the 4 methods Dynamic node discovery, Static hubs, Connection via gateways or Manual configuration. You can read more about these methods in:
http://download-uk.oracle.com/docs/cd/B32110_01/web.1013/b28950/topology.htm#CHDCAIFD
I assume that this is the way most people refer to when they are talking about an Oracle SOA Suite cluster.
OC4J Group
This is a management concept, which is a set of OC4J instances that belong to the same group. Groups enable you to perform common configuration, administration, and deployment tasks simultaneously on all OC4J instances in a group. Some people might argue that this is not a cluster, but is certainly "a number of things of the same kind held together", so according to the dictionary it would be a cluster.
Read more about OC4J Groups in:
http://download-uk.oracle.com/docs/cd/B32110_01/web.1013/b28950/topology.htm#BIHGICBJ
BPEL JGroup Config
This clustering concept allows defining a topology for BPEL instances, for example new processes. This concept uses an Active / Passive model (for the concerned process). In case of a server failure, another Oracle BPEL Server running on another server resumes the process from the last dehydration point.
Read more about this in:
http://download-uk.oracle.com/docs/cd/B31017_01/integrate.1013/b28980/clusteringsoa.htm
OC4J Session Replication
This is a way to replicate sessions in state across applications. This can also be referred to as an application cluster and is the same set of applications hosted by two or more OC4J instances. It can be enabled either globally for all applications running within an OC4J instance or on application basis. There are three ways to do this: multicast, peer-to-peer or database replication. Read more about these in:
http://download.oracle.com/docs/cd/B31017_01/web.1013/b28950/cluster.htm
To summarize, there are (at least) 4 different ways of creating an Oracle SOA Suite 10.1.3.1 cluster. These are the methods and also the intended purpose of them:
- ONS Topology: To connect two or more loosely connected Oracle Application Server nodes.
- OC4J Group: To create a group with a set of OC4J instances.
- BPEL JGroup Config: A set of BPEL Servers that shares the same dehydration store and listens on the same JGroup channels.
- OC4J Session Replication: Used to replicate state across an application deployed on two or more OC4J instances.
So, what do you mean when talking about clusters?
Sometimes you need a small database within your JDeveloper project, but you don't want to install any of the usual suspects like Oracle Database 10g Express Edition or Oracle Lite. If so, Oracle Berkeley DB is an ideal candidate. It's very easy to get started with it inside JDeveloper; just follow the steps below, and you will be up and running in just 15 minutes. Start by downloading the Oracle Berkeley DB Java Edition from the OTN:
http://www.oracle.com/technology/software/products/berkeley-db/je/index.html
- Create a new Project in JDeveloper
- Create a new Library in the JDeveloper project that contains the lib/je-3.2.44.jar file from the Berkeley DB distribution.
- Save the Project.
- Create a new folder in the file system under the newly created JDeveloper project named: src/collections/hello
- In the file system, copy the file examples/collections/hello/HelloDatabaseWorld.java from the Berkeley DB distribution and put it into the src/collections/hello folder.
- In JDeveloper, refresh the project. The copied file should now appear in the JDeveloper project under Application Sources.
- Create a new directory under your project directory called tmp. This is were the database will reside. If you want to place the database somewhere else, change the line in the HelloDatabaseWorld.java that says:
String dir = "./tmp";
- Run the project inside JDeveloper, the result should be similar to:
Writing data
Reading data
0 Hello
1 Database
2 World
If you want to read more about Oracle Berkeley DB Java Edition, please refer to this URL:
http://www.oracle.com/technology/products/berkeley-db/je/index.html
When talking about rule based programming one often hear that it enables business users and developers to work together. The business users can focus on the business rules part and the developers on the code writing part. This sounds good the first times you hear it, but after a while (at least for me) this sounds perhaps a bit too good to be true. Let me tell you why I believe this to be too good to be true.
If we start to look at the role of the developer; he or she should write the underlying code for the application, and not have to focus on the actual business rules that should be implemented in the system, i.e., should a certain threshold be above or below a certain level, and what should the level be? He should just know that based on this and that data that comes from these and those sources some rules should be applied and then this and that should happen. He should not have to care about exactly what the rules are, how many they are, what thresholds that should be set etc. These things should be left to the business analyst.
The business analyst should on the other hand not have to worry about how to get the data etc, he should just work on the business rules and set the right thresholds that should trigger certain things, for example a discount should be applied for certain customers, but not for others. He should just decide which customers the discount should be applied for and when it should be applied.
Now, don't get me wrong here, I firmly believe that this distinction is good, but I do not believe that it is enough, here are some reasons why:
- The tools requires the business user to be aware of technical issue that he or should not have to be aware of.
- I have not yet seen a tool that is easy enough for a business user to use.
There are further points on my list, but I will stick with these two for the rest of the discussion. This is not just only for our product in this area; this also goes for our competitors.
Normally the rules are stored in a repository, this requires from the end user to be aware of the location, how to open it, how to navigate to right screen, how to alter the rules and/or variables, how to add the syntax for new rules etc. I believe that any business analyst could learn these things, but is this really things that he/she should be focusing his time on? If I would run a business I would rather see them spend time on doing what they to best; not being a part time developer.
I would instead like to see that these things are handled by just a handful of people; I'll call them Business Rules Maintainers. These are the ones who should be working with the deeper maintenance of the rule repository; they could have a Business Analysts background but also needs to be aware of the technical parts of your rule product.
Now, the business analysts still needs to be there, and they need to be able to quickly adapt the rule system to the business, for example, one of you analysts suddenly discovers that a competitor has lowered the levels for being eligible for a discount and you think that this will impact your business if you do not do the same, so the analyst needs to quickly adjust your current discount levels in the system. At this point he should not have to open a full blown rule administration tool for this, he should just have to open a custom GUI in where he could quickly see what the current discount levels are and equally fast alter and save them.
So, to summarize, I believe that when you are designing the system, you should also start to think if your standard rule administration tool is easy enough to use for all your business analysts. If you come to this conclusion, fine. If not, start to think in terms how you could build a custom GUI for your business analysts that they could easy use to quickly tune your business to sudden changes in the environment, and make this GUI as simple as possible to use so that you won't have to turn your analysts into part time programmers. It might not be necessary to incorporate all your rules and threshold variable in this GUI, just the ones that are most critical to your business, and leave the rest to be maintained by the subset of your analysts that are the Business Rules Maintainers.
So to finalize the discussion, I think that when talking about developing and maintaining a rule based system, it is not enough to split the roles into developers and business analysts, I believe that at least one more role is necessary. It could also be that even further roles are necessary, but that is another discussion.
I was asked the other day by a colleague who wanted to get an introduction into Oracle Business Rules if I had some tips & pointers in order to get started, so I thought I'd might put the answer here; perhaps some more people can use it as well.
For a short, but good introduction to what rule based programming is, please check:
http://www.webreference.com/programming/rule/
The article describes short and concise what rule base programming is all about.
OK, so now you know what it is, but how to get started using it? If you are using the Oracle SOA Suite, then you already have a rule engine in place, so why not start using it?
To see a viewlet on how-to use it, go to the Rules section in OTN: http://www.oracle.com/technology/products/ias/business_rules/index.html
It is available under the 'Viewlets and Tutorials' section. After that, it is time to start learning more about it.
If you have a developer's background, I would suggest that you start with the 'Oracle Business Rules Language Reference' (available at: http://download.oracle.com/docs/cd/B32110_01/web.1013/b28964/toc.htm), this will give you a feel for how the Rule language works; after all this is really the foundation. When going through this document, you will of course need the API, it's available here: http://download.oracle.com/docs/cd/B32110_01/web.1013/b28966/toc.htm.
The document contains many small examples that will help you to get started and get familiar with the language. The examples are run using a command line interface that ships with the product. An alternative is to download the RulesTools extension for JDeveloper 10.1.3.x. This will give you the option to execute script files written in the Rules Language directly in JDeveloper, as well as some other stuff that will ease programming in the Rules Language.
Once you are familiar with the Rule language, or if you are coming from a more business oriented background, you should start to have a look into the Oracle Business Rules Rule Author; it is the GUI that is used for creating the rules. The documentation for it is available here: http://download.oracle.com/docs/cd/B32110_01/web.1013/b28965/toc.htm.
In the previous given link to the Rules section on OTN you will find even more demos and tutorials to help you get started with the Oracle Business Rules.
I hope this will help you to take your first steps down the road of Oracle Business Rules and rule based programming. Good luck!