Thursday, 26 June 2008

Testing XSL and Xpath with Java Swing

This week I finished a first version of a little java application that I created to build and test xpath expressions and xslt stylesheets.

I was very charmed with the little tool XTrans( http://www.simxtech.com/users/zc2/xtrans/). This smart tool is extreemly small (only a few KB) and enables you to edit xslt's, load xml files and transform them with the created xslt. Unfortunately for me is that it is a windows application, based on the MSXML parser. And I've not found a counterpart on Linux yet. Oh, of course you could do a lot of that with jDeveloper or XMLSpy. Maybe even better. But XTrans is so small and if you're working with xslt's, sometimes the only thing you need is a good ascii-editor and an xmlparser. And a little driver application that helps you with driving your xml and xslt trough the xmlparser.

So I found it usefull to create my own Xsl and xpath tester application.

Besides the arguments above it was also a nice excersise to play a little with the xmlparser (I used the Oracle parser shipped with jDeveloper). Although I have experience with xml, xslt and xpath, I mainly used it from Xtrans, jDeveloper or the Oracle Database (from Pl/Sql). Not directly in Java. And it is very usefull to be able do that. For example when you need to create a custom method within an ADF application, embedded Java or Java WSIF binding in BPEL.

Last year I created two little applications to test-drive messages into Integration B2b and into Axway Cyclone (another B2B product). These little applications help you to send messages with these products based on their configuration (repository or cpa). For these applications I had to parse a CPA (Collaboration Protocol Agreement) to populate the different pop-lists. Back then I did it just by browsing through the NodeLists. I created a few wrapper classes to help me with that. But I couldn't find the proper method to execute a xpath-expression. Also that turns out to be simple, when you know how:

...
private XMLDocument xmlDoc;
...
public NodeList selectNodes(String xpath) throws XSLException {
NodeList nl = this.xmlDoc.selectNodes(xpath);
return nl;
}


Another nice side effect of these little apps is that I got me to play a little with Java Swing. Nowadays people create enterprise applications using frameworks like Oracle Java ADF, JSF, JSP, ADF Components for Java, etc. But for lots of things you don't need and thus don't want the large footprint of a Application Server. And then Java Swing is very nice. It brought me back memories of Oracle Forms, with it's triggers and so on. Also it looked very familiar, thinking back, to Borland Delphi. But that's not strange: jDeveloper originated years ago from Borland jBuilder. Back then Borland used to create smart IDE's for Turbo Pascal/Delphi, C/C++ and Java. And they were in fact all the same. Oh, how much fun I had with Turbo Pascal 5.5. You could build the world with an IDE that fitted on a single floppy.

jDeveloper enables you to 'paint' your frames and panels. And double clicking on a button creates an ActionListener that you only have to fill with a call to an appropriate method.

The two B2B-applications I created last year were my first Swing apps after years. I had to re-invent how to build up an application using Swing-components and containers. When you create a Swing project in jDeveloper it gives you an application and a class that is an extension of JFrame. That's fine if you're building a one-screen application. But if you want a multi-screen application with the different screens changeable from a menu from the same main-frame, that turns out to be unhandy.

What I did was to abstract the menu and the toolbar to separate classes to maintain. In Oracle Forms the menu is also a separate module. It's a pity that there is no graphical method to build up the menu.

Also the panels became separate classes that are extensions of JPanel. I created a little method in the main-frame, that replaces the central-content-pane with one of these panels. This method I can call from the menu.

Then I created a "resize sub-components" method in the main frame class:
private void resizeSubComponents() {
int width = this.getWidth();
int height = this.getHeight();
xmlFilePanel.resizeComponents(width, height);
xpathTestPanel.resizeComponents(width, height);
xsltTestPanel.resizeComponents(width, height);
}

that is called from the Frame's component-listener:
this.addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent componentEvent) {
resizeSubComponents();
}

public void componentMoved(ComponentEvent componentEvent) {
}

public void componentShown(ComponentEvent componentEvent) {
}

public void componentHidden(ComponentEvent componentEvent) {
}
});

This method calls the resize methods in the different panels. When the mainframe is resized or maximized the different panels get resized also. Since I have several textareas with the xml-files in it, it is handy that they grow and shrink with the main frame, maximizing the available screen area.

What I have to check out is the use of inner-frames. I read about it. I want to give each panel it's own frame within the mainframe. then you have an application that is like Oracle forms, with it's different modules within the main-window. Something like a wordprocessor that can have multiple documents open.

So Swing is very nice and very powerfull to create small applications that run everywhere. But you have to find yourself a way to split up your application in smart components that are separatly maintainable. jDeveloper does not help you much with that.

I uploaded my tool on http://www.darwin-it.nl/downloads/xmltester_v0.1.zip. Just unzip it, and then change the xmltester.sh or xmltester.bat file. In the file you see a parameter "JAVA_BASE". You should change the file path to the proper location of jour Java JRE or SDK.

OpenSuse 10.3 Kernel Update

Today the wonderfull OpenSuse Updater came with a kernel update. It's now running 2.6.22.18-0.2-default (dermined with uname -r).
Allthough that is probably great (I have no clue yet what this brings me) it got me two problems:
  • My wifi did not work any more
  • VMWare Console would not start any more
Luckily these problems turn out to have simple solutions.

Wifi
This can besolved with my former OpenSuse 10.3 post: http://darwin-it.blogspot.com/2008/05/yes-opensuse-103-on-my-laptop.html. Go to the software management in Yast. Look for the ipw???? drivers and uncheck them. Make sure that you have the corresponding iwl???? drivers checked.

VMWare
This is just as simple. Vmware is "woven" with your kernel. The command to start the console is "vmware". If you run it in the konsole, you get the message that the vmware is not configured with the current running kernel. So you have to run /usr/bin/vmware-config.pl as root.

Monday, 9 June 2008

Reverse Engineering BPEL to BPMN

As I wrote in my previous posting, I attended the Oracle BPA Suite Workshop last week in Brussels. As it goes with my thoughts, attending such a course will get my head spinning and generating all new ideas on how to use the tool, get it into propositions and where to position it in the whole IT landscape.

The last three years or so, we got into building many BPEL processes. These are mostly designed using a highly sophisticated and modern tool. It's called Microsoft Word... In about the same period a rather good alternative is developed into a great alternative: Open Office/Writer.

But what about Oracle BPA Suite. We want to use that one to do our Business Process modelling. And of course we want to have a relationship between the BPMN model and our BPEL Process. This should be great when doing impact analysis. Hey, wait a minute, this is something I missed. I hope some Oracle Product Manager reads this and puts this high on the wish-list of near-future-improvements.

To get thus far, you probably want to have your bpel-processes reverse engineered to the BPA Suite. And if possible a simple migration would be great. Well, to get the expectations right in the beginning: you can't. That is: as far as I have seen the tool. But given the current "State of the Union" I'm pretty sure I'm right.

So that's the bad side of the story. Now I probably wouldn't write this post if I have not tried it or thought further and maybe you're interested in my findings. I think it is quite possible to outline a step-approach that gives at least a connection between a BPMN model and your BPEL project. It is at leas a starting point for your reverse engineering.

I found that the step-approach consist of two phases. The bottom up-phase and then the top-down phase.

The Bottom-up phase

The bottom-up phase is, simply stated, that you create a simple BPMN model consisting of one-automated-activity surrounded by a start and an end-event. That one you'll hand over to the IT-Department and the IT-Department will merge the current bpel-process into that one. Having done that you'll end up with a BPMN-model that is of course not very usefull for modelling and documentation purposes. But it is a necessary start for the reverse-engineering process.

The phase consist of the following steps:

  1. Backup the BPEL-project, by renaming the project directory and the jDeveloper-project file to another name. For example suffix the project with "_bck". Before doing that, make sure you committed the latest changes into your version control system.
  2. In BPA Architect create a BPMN-model with the same name as the BPEL project. Also it is wise to create a proper folder structure in which you put your processes, your datagrams (Technical Terms), Application system definitions, etc.
  3. In BPMN model create a Pool with a Lane and within that a Start- and an End-event . Also an Automated Task. This Task should be of type "Abstract BPEL" (not an invoke of a service). Give the Automated Activity an input document as input and a response document as output. Of course create the proper connnections
  4. Publish it to IT (using the SOA menu).
  5. Create a new BPEL-project in jDeveloper using the BPA Server connection (I assume you know how to do that) and choose the newly created BPMN-model for it.
  6. From the source of the backuped BPEL, copy the namespaces. Replace the tns and target-namespace with the one that is in the client. Also deduplicate the namespaces.
  7. Copy the partnerlinks. Make sure there is only one client partnerlink based on the one in the backuped BPEL.
  8. Copy the rest of the project including the variables to the scope of the automated activity.
  9. Place the variables to out the sequence of the scope, the rest of the BPEL code should be within the sequence. There's probably an empty activity named the same as the Automated Activity. You can remove that one.
  10. Comment out the receive client and invoke callback-client statements. In a later step we use them to replace the generated ones in the Start and End scope.
  11. Move the input and output variables to the global scope.
  12. Move the commented receive activity to the scope belonging to the BPMN-start event and move the commented invoke/callback activyt to the scope of the BPMN-end-event.
  13. Replace the generated receive/invokes by the moved/commented ones. Mark the namespaces: they should correspond to the namespaces of the original BPEL-source. The bpel generated by the BPA-Suite connection have "tns" as a namespace. The BPEL originally created by jDeveloper have "client" as a namespace. Make sure they're both equal to the original BPEL source. They should also match with the WSDL.
    Also mark that the original ones are probably empty activities and the newly generated ones have annotations. Take care that the annotations are adapted into the resulting receive/invoke activities.
  14. Probably it is convenient to just replace the WSDL files of the new BPEL project with the original one of the backuped BPEL. Also copy al the other artefacts (WSDL's of other partnerlinks/adapters, XSD's, XSL's of transformations, etc.) to the new BPEL project. Maybe this should be done upfront.
  15. Save the project in jDeveloper.
  16. Save project to the bpa server (make sure that in BPA Architect the model is not opened).
  17. Go to the naar Architect and accept the changes from IT. For that you should deselect any detail-activity by clicking somewhere on the background of the model and the Accept and Refuse changes buttons light up.
  18. Of course try to deploy your project to the development SoaSuite and adapt possible mistakes and save the correct/deployable and correctly runnable project to both BPA Suite and your Version Control System.
The Top-Down phase
As said this will deliver you a simple BPMN model but it does consist all your technical BPEL details. In jDeveloper you could add some Abstracts in the sequence of BPMN activities and move the appropriate BPEL details to the corresponding scopes. It is however not possible to add business logic on BPMN level. You could try to rename a "locked" BPMN activity by renaming the scope. But the BPA-Suite connection will notice and refresh your BPEL source. You can only do that in the BPA suite. And that is in fact what you're going to do in the Top-Down phase. There you'll add the necessary business logic.

For each Partnerlink Invocation you'll have to add Automated Tasks with the appropriate naming, Technical Terms, Input and Output documents (resembling the input and output variables of your partnerlink-invocation) and Human Workflow activities. Of course you'll provide the necessary Business Logic.

I would suggest to do this in small steps:
  1. Add one or two Automated Tasks for appropriate Partnerlink invocation
  2. Add the necessary Business Logic Plumbing
  3. Save the model and publish it to IT
  4. In jDeveloper move the appropriate logic to the corresponding scopes and get it to work in your Development SoaSuite.
  5. Save the project in jDeveloper and in your Version Control System.
  6. Save it to BPA Suite.
Repeat these steps as often as needed to get the right granularity in your BPMN-model.
Don't change your BPMN project with all the Business Logic right away. Then it is to hard to get all the technical details moved properly ending up with a BPEL process that won't work anymore and is hardly possible to get it work ever. So add one or two Automated Activities


Conclusion
Unfortunatly at this time we don't have a smart one-click approach. Especially for big models it can be a monks-job. But I think it might be worth it. It'll get you to a neatly documented Business Process that can grow with your organization.
It might turn out that some of your BPEL is just to complicated. That your technical detailing is based on some technical choices that does not resemble the thoughts of the Business Analyst. That is not necessarily wrong from functional-perspective. But then it is not possible to get the whole out of it.
Also I'm not sure yet how to handle the invoke and receive of Asynchronous Services. But that gets sorted out.
And if you need help: just contact us through www.darwin-it.nl.

BPA Suite Workshop Brussels 04-05 june 2008

Last week I was in Belgium to attend the BPA Suite Workshop, organized by Oracle Product development. My former colleague Hugo Brandt did a nice job in introducing us into the Business Process Architect, the BP Repository and the BPA Publisher.

I must say that I was pretty tiered because of a few busy days before and the long drive from home (Amersfoort the Netherlands) to the Oracle BeLux (Belgium Luxembourg) headquarters near Brussels Airport. Which is an extra compliment for both Hugo and the BPA Suite, keeping mee interested for two days.

First after an introduction we had to install the bunch of software. I downloaded the lot from edelivery.oracle.com and found that the zips are not as straight forward as you would expect. Zip 1 contained CD1 + part of CD2, Zip 2 part of CD2 and part of CD3 and Zip3, as you might expect by now, the remaining of CD3. So you had to unzip the whole into one directory and so combining the cd-parts.

For the installation you had 3 possible topologies:
1. Business Process Architect with a local repository in Oracle Lite
2. Business Process Architect with a local repository in Oracle XE
3. A "Remote" repository in a "real" database (Oracle XE/10g/11g or SQL Server) and BP Architect.

Since I'm no enthousiastic Oracle Lite user and I had the downloads in a VM with allready SoaSuite against a proper 10g database, I choose topology 3. The installation went straight forward. Just start OracleBPA.exe from the second cd and follow the arrows (Like Asterix and Obelix in "The Odyssey of Asterix" ). Then you can install the BPArchitect from cd1.
BPA Suite needs a UTF-8 database. So if you want to use Oracle XE do use the "universal" version of XE (not the standard one). If you, just like me, want to use an 10g/11g Enterprise Edition database, it have to be a database with a UTF-8 characterset.

At the end of the course I had some difficulties in getting the BPA Publisher installed and configured correctly. It turns out that it had to be installed in the same directory as the repository and the architect. And also it was "self-wise" to install against Oracle Lite (while there is no OLite service installed). So we had to reconfigure it with note 556414.1 from metalink to get Publisher configured against a standard Oracle Database.

I was quite enthusiastic about BPA Suite. It is really a great product to capture your BPMN models and also the upper levels of the ARIS House. Since Im no Business Analyst (and at the moment I've no ambitions to become one) I've no real comparison to other tools, exept for Oracle Designer perhaps. But besides that Oracle is doing a nice job in filling in the gap between BPMN and BPEL with the BPEL Blueprinting additions.

With BPA Suite it is possible to "publish the bpmn to the IT-Department". This means that you create a BPEL Blue print from the BPA suite. This blue print can be picked up by jDeveloper with the BPA Suite plugin found at the Add-on folder on the BPA Suite cd's. With that you create a BPA repository Server connection that enables you to browse through the repository for Processes that are handed over to the IT Department. Each activity in the BPMN model will become a scope in BPEL that can be detailed by the BPEL Developer. The right XSD's have to be imported, the wsdl's/services have to be detailed and the correct assignments and/or transformation between the variables have to be added.

Then after technically detailing the bpel-blueprint to a real working bpel process the BPEL specialist can upload the project again to the BPA Suite. By doing so the process may be subject to change by the Business Analyst without loosing the technical detailing. Unless ofcourse the Business Analyst removes some activities and replaces them by others. Then the detailing of the removed activities are lost and the new ones have to be detailed again. So keep in mind that the BPA Suite is by no means a replacement for a version-control system.

Publisher is by the way a nice tool that enables the rest of your enterprise browse to the published copy of the repository. In Oracle Designer we had a Repository Object Browser which enabled you to browse with a regular internet browser to the definitions in the Designer repository (it probably still works in the latest Designer). BPA Business Process Publisher however works on an own workset that is a publishment of a part of the BPA Repository.
So you have to regularly publish the latest state of your work.

I'm now philosophizing how one could migrate existing BPEL Processes to BPA suite. It should not be too hard I think. I'm thinking of the next step plan:
  1. In BPA Suite create a new model with a start and an end activity and one automated activity in between. Give it a name that resembles the name of your bpel process.
  2. Publish it to the IT Department/Create a BPEL Blueprint of it.
  3. In jDeveloper pick-up the blueprint
  4. Merge the two projects, this probably means smart copy and pasting your exisiting bpel project and additional artefacts to the new BPA Suite BPEL Project. Leave the generated scopes of the BPEL Blueprint in tact.
  5. In the BPMN View of your process add Abstracts according to the scopes and structure of your bpel project.
  6. Distribute your bpel code over the scopes that are added during step 5. Also take care of the logic between the scopes.
  7. Upload the bpel process to the BPA Repository.
  8. In BPA Architect you'll find that the BPMN proces is locked/read only and there is a copy of it with "(1)" at the end. Architect will notify you of the fact that "IT updated your model". In the new model you have to accept the changed by IT (you can do that with the accept-changes-button in the upper right corner in the toolbar).
  9. Then you could refine the model, get the conditional logic right etc. Publish again and possibly refine the technical details.
I'ts probably a tedious job when it's about a large BPEL Process. Also I don't know yet how to cater for the Data-grams (the so-called Technical Terms) that Architect keeps as input and output for each automated activity. But I probably am going to try in the near future.

By the way, I just stated I've no ambitions to become a Business Analyst. My ambitions are more in the line of being a Technical/Integration Architect. And since February (2008) I'm certified TOGAF consultant. Until now I lacked (is that the correct English saying?) in making that known.

On Firefox, Windows-Linux migration and open all in tabs

Everyone that know me know that I'm a fervent Firefox-user. I organized my bookmarks neatly in subfolders in my bookmarks-toolbar. I also regularly backup my firefox profile and it turns out that it it is highly transportable between Windows and Linux. It's a great manner to migrate someone from Windows to Linux: let him/her install thunderbird and firefox and let these packages migrate all the mail settings and favorites from Outlook and Internet Exploder (ehm, sorry, I mean Internet Explorer). Then backup the profiles (somewhere in c:\Documents and Settings\\Local Settings\Application Data if I recollect correctly) by zipping these folders. After the installation of your prefered taste of Linux and (if not pre installed) the installation of Thunderbird and Firefox you simply unzip your Firefox and Thunderbrid profiles in the respective .mozilla-firefox and .thunderbird folders in your home folder. Start the applications and all the settings are there!

I had one small annoyance in Firefox though. And that is that in Firefox I have a subfolder for my webmail-links and one for my news-links. When I right-click on my webmail-links I choose "open all in tabs" and I get all my webmail sites opened. Really time saving. When I do the same with my news-links my webmail-pages tabs get replaced!
It turns out after a little googling that there is a setting in about:config (type "about:config" in your address-field) that solves this.
It's the parameter: browser.tabs.loadFolderAndReplace that needs to be set to false. You can do this by simply double-clicking on the parameter.
See for example (amongst others): http://mozillalinks.org/wp/2007/03/prevent-firefox-from-overwriting-your-tabs/

Monday, 2 June 2008

Soap over JMS

Last week an enterprise architect of my current customer asked me about Soap over JMS. Although I had always my questions about Soap over HTTP, I never had a talk about Soap over JMS.

To answer your curiousity (I presume) about my questions about Soap over HTTP: well HTTP is an inherently unreliable protocol. It is layered in the OSI network model on the application level. Your internet-browser that brought you my article might have to wait for a long time, and even time-out, when requesting for a page. In fact this is why I started to edit this article in a text-editor, because the blog-server and my browser did not connect properly at the moment.

But puting your soap message on a queue that is also connectable by your receiving system might give you a very welcome abstraction. Your message providing application does not have to wait until your message consuming application consumes it. Your message provider can fire and forget it (unless you choose for a request-reply topology). If the remote application is unavailible for a time-being then it can pick up the messages when it comes up again.

A few years ago I had to integrate with a BSCS billing system. Back in 2002 I think it was, they builded a new Customer Access System and by then I was surprised that they used a kind of propietry command protocol with comma delimited parameters. It was not XML what was pretty much was a standard already. Also you had to connect to this CAS server using tcp. Since our integration server was in The Hague in Holland and the BSCS System and the CAS Server in Munich in Germany I stated that I wanted to have an Oracle database in Munich in the same cabinet as the CAS Server. Then I could create an AQ (nowadays called Oracle Streams - Advanced Queueing) queuing and propagation mechanism between our Oracle Hub Database in The Hague and the Oracle Adapter Database in Munich. Between this Oracle Adapter Database I used a simple external procedure that we could call from the database and that connected over a short tcp connection with the CAS server. Since it was an internal Datacenter gigabit tcp connection it was reliable enough.
But the main distance I bridged with AQ that had all the reliability and monitoring tools that you expect from a standard Queueing mechanism.

The same applies comparing Soap over HTTP and Soap over JMS, partly. The only thing is that you have to keep in mind that HTTP is a network protocol and JMS is an API on a queueing implementation. The propagation mechanism that provided my bridge between The Hague and Munich like I sketched above is not provided by JMS but the Oracle AQ implementation. Also JMS is a Java api, so it is not as technology independend as HTTP is. For example I assume it is a little hard to natively post on a JMS Queue or Topic using .Net.
Also keep in mind that although you have a wsdl (webservice description language) in a standard form that can be consumed by your development tool, the system that is "consuming" the service in runtime has to call the jms-api's to connect to the queue and publish on or consume a message from it. Because the address is not a transparent network address but a local jms-queue. If your consuming system is far-far-away from your producing system, then you have to create a local queue on both systems and implement a propagating technology between these queues (like in my AQ-story).

For more critical notes on Soap over JMS see:
There are many productivity boosters, for example in jDeveloper, to create webservices on jms queues. It is very easy to generate a webservice on a jms Queue or an existing wsdl, as it is on a pl/sql procedure. And although most of the code, if not all, is generated, the code have to be maintained, versioned and archived in a configuration management tool, like SVN. It has to be deployed to an Application Server, tested and managed independently/seperately.
For a description on how to do it on the Oracle Application Server 10.1.3 platform see the Oracle documentation on: http://download-uk.oracle.com/docs/cd/B25221_03/web.1013/b25603/transportjms.htm

Soap Over JMS is not an industry standard as Soap over HTTP is. Maybe that is the reason that it is not as natively supported by the different tools. If I'm in the BPEL or ESB Designer in jDeveloper I would expect that I could create a Partnerlink (bpel) or Adapter Service (ESB) and simply say: here is a wsdl, there is the queue, have fun with it: create me a Soap over JMS service consumer or provider.

I'm very pro-queueing. I'm very fond of AQ because of it's simplicity, reliability and maybe most of all the simple api's I have in Pl/Sql for it. But I probably would not use Soap over JMS except when the Customer has good reasons to ask for it. For example because they do not have a Integrating tool that has an adapter to post messages on a jms-queue.

Since both provider and consumer has to be able to post on or consume from the same local queue I expect that you probably be easier of using the Oracle JMS adapter. At my customer they also have Tibco and also Tibco is capable of queueing on a JMS queue. So I would suggest creating serveral queues on both Application Servers and have the Oracle JMS adapter using it. If I must I could have an jms-adapter service in Esb and create a Routing Service based on a predesigned wsdl. This provides me a service that is invocable as a "native" webservice but puts the message on a jms queue.

And if reliability is a heavy requirement I could base the jms-queue in the Oracle Application Server on a AQ queue in an Oracle 10g Database. Then each message is reliably stored in the database until it is consumed.

But if your heterogeneous platform servers are in the same datacenter and can rely on a profound network architecture then why not use the simplicity of Soap over HTTP?

Conclusion
Soap over JMS is a very good idea, I think. But there need to be some work done on the productivity and connectivity, to be really usefull. I would not dare to say that there is no future for Soap over JMS. But I think in most cases I would need the reliability over a very long distance (like my The Hague/Munich example). If you do indeed have the same requirement (reliable messaging over a long distance) I would suggest you to take a look into the ebXML/ebMS standards. Oracle Integration B2B for example could help you with that.

XSLT in Java with Oracle Parser

Last week I was struggling with the Oracle XML Parser to get it transforming XML documents with XSL. The thing is that I want to read in my own files into a String and get the results in a String too. In fact the resulting document is not XML since I'm trying to generate Pl/Sql code from an XML document.

As always everything is hard if you don't know how to do it, but if you know then it turns out to be very simple.

First you have to read in your file. For the convenience I assume you know how to do that. In my case: I read in my XML document after I have generated it by parsing an Pl/Sql package from file. But maybe in a later phase I'm going to read it from the database.

Then you have to parse it. That's done as follows:
            XMLDocument xmlDoc;
            String myXmlString = "Not a valid xml";

            DOMParser parser = new DOMParser();
            InputSource inputStream = new InputSource();
            inputStream.setCharacterStream(new StringReader(myXmlString);
            parser.parse(inputStream);
            xmlDoc = parser.getDocument();
Not to hard, is it? You have to do this for both your XML-Document and your XSL-Document.
The code is simply:
  1. Instantiate a parser
  2. Create an inputStream from the input XML String (an xsl-stylesheet is in fact also an xml-document).
  3. Execute the parser
  4. Get a DOM Document (Document Object Model) from the parser.
Then to do the transform I have the following method:
        String transform(XMLDocument xslDoc, XMLDocument xmlDoc) {
        XSLProcessor xslProcessor = new XSLProcessor();
        XSLStylesheet xslt;
        String result = "";
        try {

            xslt = xslProcessor.newXSLStylesheet(xslDoc);

            XMLDocumentFragment fragment;
            xslProcessor.setXSLTVersion(xslProcessor.XSLT20);
            xslProcessor.showWarnings(true);
            xslProcessor.setErrorStream(System.err);
            fragment = xslProcessor.processXSL(xslt, xmlDoc);
            result = fragment.getText();

        } catch (XSLException e) {
            pl(e.toString());
        } catch (IOException e) {
            pl(e.toString());
        }
        return result;
    }
This piece of code does the following:
  1. instantiates a XSL Processor;
  2. create a xslstylesheet from the stylesheet in the xmldocument (that you parsed with the previous piece of code);
  3. set some parameters of the processor: XSL-version, warnings, error-stream to output errors;
  4. process the xslstylesheet, which delivers an xmlfragment (the Oracle XML parser can also output to a URI, but I want to have a string)
  5. at the end get the String document from the xml-fragment
Maybe you'll find that the Xerces parser have more native built-in functionality. I found that although I put in the XSLT2.0 version, most XSLT2.0 functionality does not seem to work in jDeveloper. But I stick with the Oracle parser simply be cause nearly all Oracle product (including jDeveloper and the database) has it. And I might want to run my code in the database. I think I saw Xerces libraries in the SoaSuite as well, but it at this moment the Oracle parser will suffice for me.

To use the Oracle XML parser you need the following imports:
import oracle.xml.parser.v2.XMLDocument;
import oracle.xml.parser.v2.XMLDocumentFragment;
import oracle.xml.parser.v2.XSLException;
import oracle.xml.parser.v2.XSLProcessor;
import oracle.xml.parser.v2.XSLStylesheet;
And of course add the "Oracle XML Parser v2" to your jDeveloper project or add the xmlparserv2.jar and xml.jar files to your class path.