Friday, 21 February 2014

JDeveloper BPMN Bug: Activity Name conflict

This week in the BPM Adaptive Case Management workshop at the Oracle Fusion Middleware Community Forum I ran into a strange bug.

The background: earlier this week my own laptop broke down. So I had to borrow a laptop, what fortunately I could borrow from one of the presenters (thanks Guido). The thing is, though, that it runs on Ubuntu 12, so I ran my VM in VirtualBox 4.3 on Ubunty. Now actually that should not be of any difference, but it is really the only difference between my configuration and all the others (who all probably run on Windows).

When I create a bpmn process in Jdeveloper, I get this:
 And when I add an activity I get this.
 The generated events and activities apparently get invalid. The errors are:

So apparently jDeveloper does not like the names it generates itself. Actually it turns out not to be the names in error, but the ids of the activities and events.

I struggled half a day with this, importing a new VM, since the suggestion was that I got a corrupt one and try it there. In the end I compared the bpmn file (found in the processes sub folder of the project) with the given lab-solution. And I found out that jdeveloper in my configuration generates Id's with a dash and a number that is one digit longer that those of the bpmn files in the lab-solutions.

The simple solution for this, be it very inconvenient, is to create your process, add all the necessary activities, but don't bother the implementations or even the names. Then close the application in JDeveloper. It's not enough to just close the file, since JDeveloper apparently keeps the file as XML DOM tree in memory. Then open the bpmn file in an ascii editor like notepad++ (windows) or gedit (linux).

You'll see enties like this: 
<scriptTask isForCompensation="false" name="ScriptTask" id="ACT-10244072768044">



Search and replease all occurrences of 'ACT-' to 'ACT' and 'EVT-' to 'EVT'.

Then when you re-open the application and bpmn process, the activities are valid.

You see that the Script task gets a name according to it's Id. This is because there is another file in the root of the project, named after the process but suffixed with 'Documentation.xml'. Like 'ActIdTestDocumentation.xml'. In this file the actual names, documentation in different locales are placed. But you don't have to bother about that. When you change the name of the activity in jDeveloper the old name with id is removed of that file and the new name is added.

Wednesday, 5 February 2014

OSB scripted export: Branch target offset too large for short

The weirdest thing occurred to me yesterday. I have this OSB-project in Eclipse that is working fine and can be published to the dev-server perfectly.

However, I use a release/deployment framework that does a scripted export of the OSB-configuration-jar. It copies the osb-projects to a temp-folder and creates an configuration-jar out of it. It is based on the scripts of Edwin Biemond, that I adapted in way that it can be included in my release and deployment framework for SOA, BPM and now also OSB projects.

The thing is that when I create a release of the project using my release script, I get a vague error in the exportFromWorkspace part where a java call is done to the com.bea.alsb.core.ConfigExport application of ${eclipse.home}/plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar.

The error is:
...
     [java] Importing project located in "Aap" directory of the workspace...
     [java] Importing project located in "Noot" directory of the workspace...
     [java] Importing project located in "Mies" directory of the workspace...
     [java] com.sun.org.apache.bcel.internal.generic.ClassGenException: Branch target offset too large for short
     [java]  at com.sun.org.apache.bcel.internal.generic.BranchInstruction.dump(BranchInstruction.java:99)
     [java]  at com.sun.org.apache.bcel.internal.generic.InstructionList.getByteCode(InstructionList.java:980)
     [java]  at com.sun.org.apache.bcel.internal.generic.MethodGen.getMethod(MethodGen.java:616)
     [java]  at com.sun.org.apache.xalan.internal.xsltc.compiler.Mode.compileNamedTemplate(Mode.java:556)
     [java]  at com.sun.org.apache.xalan.internal.xsltc.compiler.Mode.compileTemplates(Mode.java:566)
     [java]  at com.sun.org.apache.xalan.internal.xsltc.compiler.Mode.compileApplyTemplates(Mode.java:818)
     [java]  at com.sun.org.apache.xalan.internal.xsltc.compiler.Stylesheet.compileModes(Stylesheet.java:615)
     [java]  at com.sun.org.apache.xalan.internal.xsltc.compiler.Stylesheet.translate(Stylesheet.java:730)
     [java]  at com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC.compile(XSLTC.java:354)
     [java]  at com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC.compile(XSLTC.java:429)
     [java]  at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:795)
     [java]  at com.bea.wli.sb.resources.xslt.XsltEntryHelper.getTemplates(XsltEntryHelper.java:818)
     [java]  at com.bea.wli.sb.resources.xslt.XsltEntryHelper.validateTree(XsltEntryHelper.java:479)
     [java]  at com.bea.wli.sb.resources.xslt.XsltEntryHelper.validate(XsltEntryHelper.java:191)
     [java]  at com.bea.wli.sb.resources.xslt.XsltTypeDef.validate(XsltTypeDef.java:65)
     [java]  at com.bea.wli.config.validation.ResourceValidator.validateContents(ResourceValidator.java:115)
     [java]  at com.bea.wli.config.validation.ResourceValidator.call(ResourceValidator.java:66)
     [java]  at com.bea.wli.config.validation.SequentialValidator.validate(SequentialValidator.java:34)
     [java]  at com.bea.wli.config.validation.ValidationService.validate(ValidationService.java:177)
     [java]  at com.bea.wli.config.impl.CoreToSessionPropagator.doValidation(CoreToSessionPropagator.java:239)
     [java]  at com.bea.wli.config.impl.CoreToSessionPropagator.handleBeforePrepare(CoreToSessionPropagator.java:118)
     [java]  at com.bea.wli.config.impl.CoreToSessionPropagator.beforePrepare(CoreToSessionPropagator.java:77)
     [java]  at com.bea.wli.config.transaction.TransactionListenerWrapper.beforePrepare(TransactionListenerWrapper.java:64)
     [java]  at com.bea.wli.config.transaction.TransactionManager.notifyBeforePrepare(TransactionManager.java:1094)
     [java]  at com.bea.wli.config.transaction.TransactionManager._prepareForCommit(TransactionManager.java:654)
     [java]  at com.bea.wli.config.transaction.TransactionManager.endTransaction(TransactionManager.java:782)
...
I found this error on serveral places related to the Xalan parser, for instance: https://issues.apache.org/jira/i#browse/XALANJ-2064. I saw that SAP's Netweaver suffers from this issue as well.

Apparently the XSL is compiled into java methods, wich in byte codes have a branch limitation of 32K. So the solution is to break-down the XSL into multiple smaller sub-templates. This makes the XSLT more modular, but unfortunately the XSLT mapper of JDeveloper can't do mappings in those sub-templates. It would be nice if Oracle Development think of something smart to do mappings using sub-templates. I have some thoughts for that...

So I split up my template into smaller bits and now my release works perfectly.

Now you could ask "OSB and XSL: why not XQuery?". Well, maybe a bit to my embarrasment: I'm not too familiar yet with XQuery, where through my SOASuite background, I'm quite loose on XSLT. And I found that the XQuery mapper in Eclipse has some limitations in the use of some simpletypes. I have xsd's with definitions that are based on simple type, with length restrictions. But the XQuery mapper did not let me map those on a simple xsd:string target-element...
And to be honest: I find XSL "cleaner" then XQuery, since it is completely XML based. But that is more a  purist-finding and maybe due to a lack of XQuery-experience...