<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4533777417600103698</id><updated>2011-12-21T03:56:12.438-08:00</updated><category term='Sun Metro'/><category term='procurement'/><category term='installation'/><category term='SQL'/><category term='Subversion'/><category term='Oracle Designer'/><category term='B2B'/><category term='Oracle Application Server'/><category term='Oracle BPA Suite'/><category term='XML'/><category term='Oracle Sqldeveloper'/><category term='Oracle Weblogic'/><category term='Pl/Sql'/><category term='Java'/><category term='Oracle Forms'/><category term='Oracle BI'/><category term='SOA'/><category term='Oracle E-Business Suite'/><category term='OPN'/><category term='JDeveloper'/><category term='BEA'/><category term='Virtual Box'/><category term='SOA Suite'/><category term='Oracle BPM Suite'/><category term='Apex'/><category term='BPEL PM'/><category term='VMware'/><category term='Database 11g'/><category term='Oracle Webcenter'/><category term='Database'/><category term='Oracle Workflow'/><category term='Oracle AIA'/><category term='Linux'/><category term='supply chain'/><category term='Java ADF'/><category term='CMS'/><category term='Generic'/><category term='BPMN'/><category term='Sun GlassFish'/><category term='Tools'/><category term='project portfolio management'/><category term='Virtual Machines'/><category term='EAI'/><category term='fusion applications'/><category term='Oracle VM'/><category term='JHeadstart'/><title type='text'>Darwin-IT</title><subtitle type='html'>Darwin-IT professionals do ICT-projects based on a broad range of Oracle products and technologies. We write about our experiences and share our thoughts and tips.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default?start-index=101&amp;max-results=100'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>172</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-8105270487618783419</id><published>2011-12-13T03:19:00.000-08:00</published><updated>2011-12-13T03:20:09.099-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle BPM Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><title type='text'>SoapUI Tip 3</title><content type='html'>It was a little searching using the javadocs of SoapUI, but if you want to log the result of the script of a mockService or mockResponse step in a testCase, then that can be done using:&lt;br /&gt;&lt;pre class="brush:java"&gt;log.info("Response: "+mockResponse.getMockResult().getResponseContent())&lt;br /&gt;&lt;/pre&gt;Another nice tip I found at &lt;a href="http://developers-blog.org/blog/de/2010/03/04/SoapUI-limitations-and-workarounds-mock-response-test-step"&gt;another blog: "SoapUI limitations and workarounds : mock response test step" &lt;/a&gt;&lt;br /&gt;If you want to use mockServices in your testcase or testsuite, but don't want to implement mockResponse steps for them, you can create (of course) mockServices for them. They can handle multple responses and use xpath expressions to choose the right response for a particular request. But running the testcase you'll need to start the mockServices that you need in the test. this can be done by in the "Setup Script" of the testCase: &lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;def project = testCase.getTestSuite().getProject();&lt;br /&gt;def mockService = project.getMockServiceByName("Name of the MockService");&lt;br /&gt;mockService.start();&lt;br /&gt;&lt;/pre&gt;After running the testcase/testsuite the mockservices should be stopped neatly. This can be done in the "TearDown Script":&lt;pre class="brush:java"&gt;&lt;br /&gt;def project = testCase.getTestSuite().getProject();&lt;br /&gt;def mockService = project.getMockServiceByName("Name of the MockService");&lt;br /&gt;def mockRunner = mockService.getMockRunner();&lt;br /&gt;mockRunner.stop();&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-8105270487618783419?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/8105270487618783419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=8105270487618783419' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8105270487618783419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8105270487618783419'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/12/soapui-tip-3.html' title='SoapUI Tip 3'/><author><name>Martien van den Akker|Darwin-IT</name><uri>http://www.blogger.com/profile/08296120245673883785</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-2952541559488250888</id><published>2011-12-11T23:57:00.001-08:00</published><updated>2011-12-12T00:07:52.884-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle BPM Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><title type='text'>SoapUI: Properties from test Suite</title><content type='html'>In my previous post I showed how to get a file from a script in SoapUI. One of the parts on building the filepath of the file to load was a property from the mockService. The same thing is possible from a test suite. There are several places at which you can define properties. Amongst them is the TestSuite.&lt;br /&gt;&lt;br /&gt;To get the properties from a test suite, you have to "get" it. To get the test suite on which you defined the properties goes as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;def project = mockResponse.mockOperation.mockService.project&lt;br /&gt;def testSuite = project.testSuites["TestSupport"]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The property can then be fetched with:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;def filePath = testSuite.getPropertyValue( "responseFilePath")&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Test cases are part of the testSuite and they can be fetched from an string-based array in the same manner as getting the testSuite:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;def testCase = project.testSuites["TestSuite 1"].testCases["TestCase 1"]&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Expanding SoapUI possibilities...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-2952541559488250888?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/2952541559488250888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=2952541559488250888' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2952541559488250888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2952541559488250888'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/12/soapui-properties-from-test-suite.html' title='SoapUI: Properties from test Suite'/><author><name>Martien van den Akker|Darwin-IT</name><uri>http://www.blogger.com/profile/08296120245673883785</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-6463964307497841159</id><published>2011-12-08T13:34:00.001-08:00</published><updated>2011-12-09T05:05:17.661-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle BPM Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><title type='text'>Load Response Message File System in SoapUI</title><content type='html'>Today I figured out how to get a response from filesystem in SoapUI. I found that I could not dynamically select from multiple responses in a mockResponse-TestStep in a TestSuite. But loading from a file within a Groovy script should do the job. Advantage is also that you can have as many response files as you like. You just put a value in the filename, that you select using xpath from the request message. The folder in which you store the message can be put in a property on the mockService.I don't have the time to explain the whole lot. But the response in the mockService should be like: &lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;soapenv:envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&amp;gt;&lt;br /&gt;   &amp;lt;soapenv:header&amp;gt;&lt;br /&gt;      &amp;lt;darwinheader xmlns="http://www.darwin-it.nl/XMLHeader/10"&amp;gt;&lt;br /&gt;         &amp;lt;headerversion&amp;gt;${headerVersion}&amp;lt;/headerversion&amp;gt;&lt;br /&gt;         &amp;lt;messageid&amp;gt;${messageId}&amp;lt;/messageid&amp;gt;&lt;br /&gt;         &amp;lt;servicerequestordomain&amp;gt;${serviceRequestorDomain}&amp;lt;/servicerequestordomain&amp;gt;&lt;br /&gt;         &amp;lt;servicerequestorid&amp;gt;${serviceRequestorId}&amp;lt;/servicerequestorid&amp;gt;&lt;br /&gt;         &amp;lt;serviceproviderdomain&amp;gt;${serviceProviderDomain}&amp;lt;/serviceproviderdomain&amp;gt;&lt;br /&gt;         &amp;lt;serviceid&amp;gt;${serviceId}&amp;lt;/serviceid&amp;gt;&lt;br /&gt;         &amp;lt;serviceversion≶${serviceVersion}&amp;lt;/serviceversion&amp;gt;&lt;br /&gt;         &amp;lt;faultindication&amp;gt;${faultIndication}&amp;lt;/faultindication&amp;gt;&lt;br /&gt;         &amp;lt;messagetimestamp&amp;gt;${messageTimestamp}&amp;lt;/messagetimestamp&amp;gt;&lt;br /&gt;      &amp;lt;/darwinheader&amp;gt;&lt;br /&gt;   &amp;lt;/soapenv:header&amp;gt;&lt;br /&gt;   &amp;lt;soapenv:body&amp;gt;${responseBody}&amp;lt;/soapenv:body&amp;gt;&lt;br /&gt;&amp;lt;/soapenv:envelope&amp;gt;&lt;br /&gt;&lt;/pre&gt;Here you see that the Soapenvelope with the header is given, but the diffent values are properties, as well as the responseBody.The script to get these from the request is as follows:&lt;br /&gt;&lt;pre class="brush:java"&gt;def method = "ChangeServiceRequest.Response 1.Script"&lt;br /&gt;log.info("Start "+method)&lt;br /&gt;&lt;br /&gt;log.info(mockRequest.requestContent)&lt;br /&gt;&lt;br /&gt;def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)&lt;br /&gt;// Set Namespaces&lt;br /&gt;def holder = groovyUtils.getXmlHolder(mockRequest.requestContent)&lt;br /&gt;holder.namespaces["soapenv"] = "http://schemas.xmlsoap.org/soap/envelope/"&lt;br /&gt;holder.namespaces["ns"] = "http://www.darwin-it.nl/XMLHeader/10"&lt;br /&gt;holder.namespaces["rpy"] = "http://www.darwin-it.nl/ChangeServiceRequest/2/Rpy"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;log.info("Get Header Properties")&lt;br /&gt;context.messageId=Math.random()&lt;br /&gt;log.info("messageId: "+context.messageId)&lt;br /&gt;context.headerVersion= holder.getNodeValue("//ns:DarwinHeader/ns:HeaderVersion")&lt;br /&gt;log.info("headerVersion: "+context.headerVersion)&lt;br /&gt;context.serviceRequestorDomain= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceRequestorDomain")&lt;br /&gt;log.info("ServiceRequestorDomain: "+context.serviceRequestorDomain)&lt;br /&gt;context.serviceRequestorId= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceRequestorId")&lt;br /&gt;log.info("serviceRequestorId: "+context.serviceRequestorId)&lt;br /&gt;context.serviceProviderDomain= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceProviderDomain")&lt;br /&gt;log.info("serviceProviderDomain: "+context.serviceProviderDomain)&lt;br /&gt;context.serviceId= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceId")&lt;br /&gt;log.info("serviceId: "+context.serviceId)&lt;br /&gt;context.serviceVersion= holder.getNodeValue("//ns:DarwinHeader/ns:ServiceVersion")&lt;br /&gt;log.info("serviceVersion: "+context.serviceVersion)&lt;br /&gt;context.faultIndication= holder.getNodeValue("//ns:DarwinHeader/ns:FaultIndication")&lt;br /&gt;log.info("faultIndication: "+context.faultIndication)&lt;br /&gt;context.messageTimestamp= holder.getNodeValue("//ns:DarwinHeader/ns:MessageTimestamp")&lt;br /&gt;log.info("messageTimestamp: "+context.messageTimestamp)&lt;br /&gt;&lt;br /&gt;def serviceRequestNr= holder.getNodeValue("//req:ChangeServiceRequest_Req/req:ServiceRequestData/req:ServiceRequestNumber")&lt;br /&gt;log.info("ServiceRequestNr: "+serviceRequestNr)&lt;br /&gt;&lt;br /&gt;def mockRunner = context.getMockRunner()&lt;br /&gt;def mockService = mockRunner.mockService&lt;br /&gt;def filePath = mockService.getPropertyValue( "responseFilePath")+"/FT01_ChangeServiceRequest_"+serviceRequestNr+".xml"&lt;br /&gt;log.info("FileName: "+ filePath)&lt;br /&gt;def File file = new File( filePath )&lt;br /&gt;def fileLength = (int) file.length();&lt;br /&gt;def buffer = new char[fileLength];&lt;br /&gt;def inputReader = new FileReader(file);&lt;br /&gt;def numChar = inputReader.read(buffer);&lt;br /&gt;requestContext.responseBody = new String(buffer);&lt;br /&gt;log.info("End "+method)&lt;/pre&gt;With "def holder = groovyUtils.getXmlHolder(mockRequest.requestContent)" you get an XML object of the request. The lines "holder.namespaces["ns"] = "http://www.darwin-it.nl/XMLHeader/10" set the namespace-abbreviations, needed to select the values from the request.&lt;br /&gt;Then with "def serviceRequestNr= holder.getNodeValue("//req:ChangeServiceRequest_Req/req:ServiceRequestData/req:ServiceRequestNumber")", you can perform an xpath query, to get the serviceRequestNr from the request message in this case.&lt;br /&gt;&lt;br /&gt;The lines&lt;br /&gt;&lt;pre class="brush:java"&gt;def mockRunner = context.getMockRunner()&lt;br /&gt;def mockService = mockRunner.mockService&lt;br /&gt;def filePath = mockService.getPropertyValue( "responseFilePath")&lt;/pre&gt;&lt;br /&gt;show how to read a property from the mockService.&lt;br /&gt;&lt;br /&gt;Then the last lines are to determine the actual file path using this property and the&amp;nbsp; queried serviceRequestNr, and&amp;nbsp; to read the file.&lt;br /&gt;&lt;br /&gt;By putting the file in the requestContext using: "requestContext.responseBody = new String(buffer);" it can be put in the response using the property "${responseBody}" like in the response-skeleton above.You might notice that it is a mixture of Java and Groovy. I'm not so familiar with Groovy yet. But I found that if it works in Java it is easy to get it work in Groovy. Actually, Groovy is just more loosely typed.I hope this clears enough to get this going.Good luck.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-6463964307497841159?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/6463964307497841159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=6463964307497841159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6463964307497841159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6463964307497841159'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/12/load-response-message-file-system-in.html' title='Load Response Message File System in SoapUI'/><author><name>Martien van den Akker|Darwin-IT</name><uri>http://www.blogger.com/profile/08296120245673883785</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-7363973211598079350</id><published>2011-10-19T04:57:00.000-07:00</published><updated>2011-10-19T04:57:59.976-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Drag and drop in Gmail</title><content type='html'>&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;div style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;a href="data:image/png;base64,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" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img alt="" border="0" src="data:image/png;base64,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" /&gt;&lt;/a&gt;Well, I'm probably one of the last gmail users that see's it but I just a moment ago encountered that Gmail supports drag and drop.&amp;nbsp; One of the things I really missed. When I wanted to move mails to a label I had to do it using the 'move-to' poplist. But apparently sometime in the past months google implemented the possibility to grab one of more mails/conversations and drag them to a label. Great. By this the frontend mimics a rich-mail-client as Thunderbird., so that handling mail using Gmail is much more convenient. I love empty mailboxes... &lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-7363973211598079350?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/7363973211598079350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=7363973211598079350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7363973211598079350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7363973211598079350'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/10/drag-and-drop-in-gmail.html' title='Drag and drop in Gmail'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-3822688067923636545</id><published>2011-09-22T02:47:00.000-07:00</published><updated>2011-09-22T03:25:05.395-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Machines'/><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Box'/><title type='text'>Shared Folders in VirtualBox</title><content type='html'>Shared Folders are a big advantage in both VirtualBox and VMware Player (&amp;gt;3.0.x). However I notice that in my direct neighborhood there is a unfamiliarity with it. And how to use it. That is, it turns out that a created shared folder is not mounted right a way in a started VM. So to help this out, a little how to.&lt;br /&gt;&lt;br /&gt;To create a Shared Folder you have to go to the SharedFolders node in the VM Settings:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-oMJbLkTPpI8/TnsGFQwvw_I/AAAAAAAAACA/j2FTvRvYmB4/s1600/SharedFolders.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 233px;" src="http://2.bp.blogspot.com/-oMJbLkTPpI8/TnsGFQwvw_I/AAAAAAAAACA/j2FTvRvYmB4/s320/SharedFolders.jpg" alt="" id="BLOGGER_PHOTO_ID_5655120444562326514" border="0" /&gt;&lt;/a&gt;There you can click on the add folder button. Of course you can remove or edit existing ones.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-8qI-yq4lpWo/TnsGFUll8jI/AAAAAAAAACI/1YDyUEau2es/s1600/createSharedFolder.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 236px;" src="http://4.bp.blogspot.com/-8qI-yq4lpWo/TnsGFUll8jI/AAAAAAAAACI/1YDyUEau2es/s320/createSharedFolder.jpg" alt="" id="BLOGGER_PHOTO_ID_5655120445589287474" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Give here the path to the folder on your host. At the layout of the screen you could gues my host is a Windows 7. You can give in  a Shared Folder name.&lt;br /&gt;The other options (check boxes, I really need to do a reinstall of VB in English, however it was no option I've chosen consciously to install it in Dutch) are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Read only&lt;/li&gt;&lt;li&gt;Auto Mount&lt;/li&gt;&lt;li&gt;Make permanent&lt;/li&gt;&lt;/ul&gt;I check the the latter 2.&lt;br /&gt;Although auto mount is checked, this does not count right away for running Linux guests. Therefor you have to do a restart.&lt;br /&gt;&lt;br /&gt;Shared Folders are automounted in linux as /media/sf_&amp;lt;sharedfolder name&amp;gt;&lt;br /&gt;&lt;br /&gt;So as root you have to&lt;br /&gt;&lt;ul&gt;&lt;li&gt;create the folder&lt;/li&gt;&lt;li&gt;' change owner' it to root:vboxsf&lt;/li&gt;&lt;li&gt;set " group writable"  with chmod&lt;/li&gt;&lt;li&gt;Then mount the folder&lt;/li&gt;&lt;/ul&gt;So:&lt;br /&gt;&lt;pre class="brush:bash"&gt;makker@makker-lnx:~&amp;gt; cd /media&lt;br /&gt;makker@makker-lnx:/media&amp;gt; ls -l&lt;br /&gt;total 92&lt;br /&gt;drwxrwx--- 1 root vboxsf  4096 Aug 25 17:07 sf_Data&lt;br /&gt;drwxrwx--- 1 root vboxsf  8192 Sep 21 13:45 sf_Documents&lt;br /&gt;dr-xr-xr-x 1 root root   16384 Sep 22 09:59 sf_Downloads&lt;br /&gt;drwxrwx--- 1 root vboxsf 65536 Aug 23 14:26 sf_Music&lt;br /&gt;makker@makker-lnx:/media&amp;gt; sudo mkdir sf_Projects&lt;br /&gt;root's password:&lt;br /&gt;makker@makker-lnx:/media&amp;gt; ls -l&lt;br /&gt;total 96&lt;br /&gt;drwxrwx--- 1 root vboxsf  4096 Aug 25 17:07 sf_Data&lt;br /&gt;drwxrwx--- 1 root vboxsf  8192 Sep 21 13:45 sf_Documents&lt;br /&gt;dr-xr-xr-x 1 root root   16384 Sep 22 09:59 sf_Downloads&lt;br /&gt;drwxrwx--- 1 root vboxsf 65536 Aug 23 14:26 sf_Music&lt;br /&gt;drwxr-xr-x 2 root root    4096 Sep 22 12:06 sf_Projects&lt;br /&gt;&lt;br /&gt;makker@makker-lnx:/media&amp;gt; &lt;span style="font-weight:bold;"&gt;sudo chown root:vboxsf sf_Projects&lt;/span&gt;&lt;br /&gt;makker@makker-lnx:/media&amp;gt; &lt;span style="font-weight:bold;"&gt;sudo chmod g+w  sf_Projects&lt;/span&gt;&lt;br /&gt;makker@makker-lnx:/media&amp;gt; ls -l&lt;br /&gt;total 96&lt;br /&gt;drwxrwx--- 1 root vboxsf  4096 Aug 25 17:07 sf_Data&lt;br /&gt;drwxrwx--- 1 root vboxsf  8192 Sep 21 13:45 sf_Documents&lt;br /&gt;dr-xr-xr-x 1 root root   16384 Sep 22 09:59 sf_Downloads&lt;br /&gt;drwxrwx--- 1 root vboxsf 65536 Aug 23 14:26 sf_Music&lt;br /&gt;drwxrwxr-x 2 root vboxsf  4096 Sep 22 12:06 sf_Projects&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To mount the folder use the command &lt;span style="font-style: italic;"&gt;mount -t vboxsf &amp;lt;sharedfolder name&amp;gt; /media/sf_&amp;lt;sharedfolder name&amp;gt;&lt;/span&gt;&lt;br /&gt;So:&lt;br /&gt;&lt;pre class="brush:bash"&gt;makker@makker-lnx:/media&amp;gt; sudo mount -t vboxsf Projects /media/sf_Projects&lt;br /&gt;makker@makker-lnx:/media&amp;gt; ls -l sf_Projects/&lt;br /&gt;total 94&lt;br /&gt;-rwxrwxrwx 1 root root  9776 Oct 12  2010 AIA Project in Amsterdam&lt;br /&gt;....&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, as you'll notice to use the shared folder by another user than root, you'll need to add that user to the &lt;span style="font-style: italic;"&gt;vboxsf&lt;/span&gt; user group.&lt;br /&gt;&lt;br /&gt;The easiest way to do that is to use the user-administration tool of your linux distribution.&lt;br /&gt;&lt;br /&gt;To add it on the commandline, first list the groups you allready have:&lt;br /&gt;&lt;pre class="brush:bash"&gt;&lt;br /&gt;makker@makker-lnx:/media&amp;gt; id&lt;br /&gt;uid=1000(makker) gid=100(users) groups=100(users),6(disk),17(audio),20(cdrom),33(video),49(ftp)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or:&lt;br /&gt;&lt;pre class="brush:bash"&gt;&lt;br /&gt;makker@makker-lnx:/media&amp;gt; groups&lt;br /&gt;users disk audio cdrom video ftp&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then use usermod (as root or via sudo) to add the group:&lt;br /&gt;&lt;pre class="brush:bash"&gt;&lt;br /&gt;makker@makker-lnx:/media&amp;gt; sudo /usr/sbin/usermod -g users -G disk,audio,cdrom,video,ftp,vboxsf makker&lt;br /&gt;makker@makker-lnx:/media&amp;gt; groups&lt;br /&gt;users disk audio cdrom video ftp vboxsf&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Mind that you have always a primary group indicated with lowercase '-g', and several secondary groups indicated with capital '-G' and a comma separated list (don't use spaces).&lt;br /&gt;&lt;br /&gt;That's it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-3822688067923636545?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/3822688067923636545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=3822688067923636545' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3822688067923636545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3822688067923636545'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/09/shared-folders-in-virtualbox.html' title='Shared Folders in VirtualBox'/><author><name>Martien van den Akker|Darwin-IT</name><uri>http://www.blogger.com/profile/08296120245673883785</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-oMJbLkTPpI8/TnsGFQwvw_I/AAAAAAAAACA/j2FTvRvYmB4/s72-c/SharedFolders.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-6474792896876182426</id><published>2011-09-15T06:47:00.000-07:00</published><updated>2011-09-15T12:17:30.634-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Machines'/><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Box'/><title type='text'>Decomposing Virtual Machines</title><content type='html'>It's been a while since my last post, but here's a new one.&lt;br /&gt;This summer I got a VirtualMachine to do a Webcenter workshop. The VM turned out to be 30GB in size. This 30GB is basically one big Virtual Disk of logically 50GB. That is: it's dynamically allocated and can grow until 50GB.&lt;br /&gt;Although it is a VirtualBox VM, the disk uses VMDK format, which is the VMware virtual disk format.&lt;br /&gt;The disk contained the OS (of course), the install/setup files of the database, Weblogic Suite, Repository Creation Utillity and WebcenterSuite, and the installation itself.&lt;br /&gt;This means that after installing the OS, the setup files are copied to the VM into a staging directory, from which the installation is done. The installation is put in a /u01/app folder, but physically in the same disk after the setup files. So deleting the setup files won't decrease the VM a bit.&lt;br /&gt;&lt;br /&gt;I found it a nice project to try to split the VM getting it into a more suitable size.&lt;br /&gt;&lt;br /&gt;The project turned out to be about the following steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Add new virtual disks for the Oracle/Webcenter installation and the staging-area (the setup files)&lt;/li&gt;&lt;li&gt;Partition, format and mount the disks&lt;/li&gt;&lt;li&gt;Copy/Move the staging and installation folder to their particular disks&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Detach the staging disk&lt;/li&gt;&lt;li&gt;Transform the OS disk from VMDK to VDI&lt;/li&gt;&lt;li&gt;Shrink/Compact the OS disk&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;1. Add new virtual disks&lt;/span&gt;&lt;br /&gt;Adding a disk to the VM is pretty simple: goto VM settings and node Storage. I'm sorry the screendumps are in dutch. Some how I got a Dutch VirtualBox installation.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-GvsFF1p9dPs/TnIE_gdJ6iI/AAAAAAAAAAQ/Qtk47A9UPJM/s1600/VBAddHardDisk-1.jpg"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 233px;" src="http://4.bp.blogspot.com/-GvsFF1p9dPs/TnIE_gdJ6iI/AAAAAAAAAAQ/Qtk47A9UPJM/s320/VBAddHardDisk-1.jpg" alt="" id="BLOGGER_PHOTO_ID_5652585971393882658" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Click the add disk Icon on the Sata Controller node.&lt;br /&gt;Choose "create new disk":&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-CN7xwvp8tvA/TnIF288yTTI/AAAAAAAAAAY/h4u1Bjj-z6w/s1600/VBAddHardDisk-2-MaakNieuweSchijfAan.jpg"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 127px;" src="http://2.bp.blogspot.com/-CN7xwvp8tvA/TnIF288yTTI/AAAAAAAAAAY/h4u1Bjj-z6w/s320/VBAddHardDisk-2-MaakNieuweSchijfAan.jpg" alt="" id="BLOGGER_PHOTO_ID_5652586923935550770" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Choose VDI as disk format. VDI is the "Virtual Disk Image" format of VirtualBox. VMDK is the "Virtual Machine Disk" format of VMware. Later I'll show how to create a VDI image out of a VMDK, but it's better to choose the right format right away. Especially because VirtualBox can't compact a VMDK.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-AbzgB9SCogM/TnIF3bm4hoI/AAAAAAAAAAg/5OrCDL3qlAE/s1600/VBAddHardDisk-3-VDI.jpg"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 211px;" src="http://2.bp.blogspot.com/-AbzgB9SCogM/TnIF3bm4hoI/AAAAAAAAAAg/5OrCDL3qlAE/s320/VBAddHardDisk-3-VDI.jpg" alt="" id="BLOGGER_PHOTO_ID_5652586932165183106" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For "transportable" VM's choose the option "Dynamically Allocated". That way the Disk Image is only the size of the needed space.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-eBBSGQZa1SI/TnIF5fmDCqI/AAAAAAAAAAo/a7q0791YZCI/s1600/VBAddHardDisk-4-DynamicallyAllocated.jpg"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 211px;" src="http://1.bp.blogspot.com/-eBBSGQZa1SI/TnIF5fmDCqI/AAAAAAAAAAo/a7q0791YZCI/s320/VBAddHardDisk-4-DynamicallyAllocated.jpg" alt="" id="BLOGGER_PHOTO_ID_5652586967595158178" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Then choose a location and preferably a sensible name. Then set the (maximum) size on an appropriate value.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-IlokMibeIKA/TnIF5boPV1I/AAAAAAAAAAw/mnwF9ZipP_c/s1600/VBAddHardDisk-5-LocationAndSize.jpg"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 211px;" src="http://1.bp.blogspot.com/-IlokMibeIKA/TnIF5boPV1I/AAAAAAAAAAw/mnwF9ZipP_c/s320/VBAddHardDisk-5-LocationAndSize.jpg" alt="" id="BLOGGER_PHOTO_ID_5652586966530611026" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Now, you could add all the disks you need right a way. In my case I need two extra disks: one for the installation (disk2; disk1 one is for the OS: the root disk) and one for staging (named the stage disk here). But it is important to know which disk get's which device name. I think you can assume that the disk that is first in the list gets "/dev/sda", the second "/dev/sdb" and so this staging disk "/dev/sdc". But I don't take the risk and add a disk and format it one by one (and thus do a restart each new disk).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. Partition, Format and mount disks&lt;/span&gt;&lt;br /&gt;This can in fact in two ways:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The raw way: partition, format and mount the raw disk.&lt;/li&gt;&lt;li&gt;Use Logical Volume Manager to create a Logical Volume in a Volume Group&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;2.1 the raw way:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;First check with fdisk -l the disk devices:&lt;br /&gt;&lt;pre class="brush:bash"&gt;[root@server1 ~]# fdisk -l&lt;br /&gt;&lt;br /&gt;Disk /dev/sda: 53.6 GB, 53687091200 bytes&lt;br /&gt;255 heads, 63 sectors/track, 6527 cylinders&lt;br /&gt;Units = cylinders of 16065 * 512 = 8225280 bytes&lt;br /&gt;&lt;br /&gt;Device Boot      Start         End      Blocks   Id  System&lt;br /&gt;/dev/sda1   *           1          13      104391   83  Linux&lt;br /&gt;/dev/sda2              14        6527    52323705   8e  Linux LVM&lt;br /&gt;&lt;br /&gt;Disk /dev/sdb: 21.4 GB, 21474836480 bytes&lt;br /&gt;255 heads, 63 sectors/track, 2610 cylinders&lt;br /&gt;Units = cylinders of 16065 * 512 = 8225280 bytes&lt;br /&gt;&lt;br /&gt;Device Boot      Start         End      Blocks   Id  System&lt;br /&gt;/dev/sdb1               1        2611    20971519+  8e  Linux LVM&lt;br /&gt;&lt;br /&gt;Disk /dev/sdc: 10.7 GB, 10737418240 bytes&lt;br /&gt;255 heads, 63 sectors/track, 1305 cylinders&lt;br /&gt;Units = cylinders of 16065 * 512 = 8225280 bytes&lt;br /&gt;&lt;br /&gt;Disk /dev/sdc doesn't contain a valid partition table&lt;br /&gt;&lt;br /&gt;Disk /dev/dm-0: 47.7 GB, 47747956736 bytes&lt;br /&gt;255 heads, 63 sectors/track, 5805 cylinders&lt;br /&gt;Units = cylinders of 16065 * 512 = 8225280 bytes&lt;br /&gt;&lt;br /&gt;Disk /dev/dm-0 doesn't contain a valid partition table&lt;br /&gt;&lt;br /&gt;Disk /dev/dm-1: 5804 MB, 5804916736 bytes&lt;br /&gt;255 heads, 63 sectors/track, 705 cylinders&lt;br /&gt;Units = cylinders of 16065 * 512 = 8225280 bytes&lt;br /&gt;&lt;br /&gt;Disk /dev/dm-1 doesn't contain a valid partition table&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here  you see that /dev/sdc does not contain  a partition table (ignore /dev/dm-0 and /dev/dm-1).&lt;br /&gt;Then partition it with fdisk /dev/sdc (the device that you want to partition) and enter the following commands:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;n (new partition)&lt;/li&gt;&lt;li&gt;p (for primary)&lt;/li&gt;&lt;li&gt;1 (first partition)&lt;/li&gt;&lt;li&gt;2 x enter, accepting the defaults for first and last cylinder&lt;/li&gt;&lt;li&gt;w (write partition table to disk)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;pre class="brush:bash"&gt;[root@server1 ~]# fdisk /dev/sdc&lt;br /&gt;Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel&lt;br /&gt;Building a new DOS disklabel. Changes will remain in memory only,&lt;br /&gt;until you decide to write them. After that, of course, the previous&lt;br /&gt;content won't be recoverable.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The number of cylinders for this disk is set to 1305.&lt;br /&gt;There is nothing wrong with that, but this is larger than 1024,&lt;br /&gt;and could in certain setups cause problems with:&lt;br /&gt;1) software that runs at boot time (e.g., old versions of LILO)&lt;br /&gt;2) booting and partitioning software from other OSs&lt;br /&gt;(e.g., DOS FDISK, OS/2 FDISK)&lt;br /&gt;Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)&lt;br /&gt;&lt;br /&gt;Command (m for help): n&lt;br /&gt;Command action&lt;br /&gt;e   extended&lt;br /&gt;p   primary partition (1-4)&lt;br /&gt;p&lt;br /&gt;Partition number (1-4): 1&lt;br /&gt;First cylinder (1-1305, default 1):&lt;br /&gt;Using default value 1&lt;br /&gt;Last cylinder or +size or +sizeM or +sizeK (1-1305, default 1305):&lt;br /&gt;Using default value 1305&lt;br /&gt;&lt;br /&gt;Command (m for help): w&lt;br /&gt;The partition table has been altered!&lt;br /&gt;&lt;br /&gt;Calling ioctl() to re-read partition table.&lt;br /&gt;Syncing disks.&lt;br /&gt;&lt;/pre&gt;Then you can create a filesystem on it (format). Based on the version of the Linux distro you can choose for ext3 or ext4 (older systems have ext2). You can do this by issueing the command mkfs.ext4 and ofcourse choose y(es) at the question to proceed anyway:&lt;br /&gt;&lt;pre class="brush:bash"&gt;[root@server1 ~]# mkfs.ext4 /dev/sdc&lt;br /&gt;mke4fs 1.41.12 (17-May-2010)&lt;br /&gt;/dev/sdc is entire device, not just one partition!&lt;br /&gt;Proceed anyway? (y,n) y&lt;br /&gt;Filesystem label=&lt;br /&gt;OS type: Linux&lt;br /&gt;Block size=4096 (log=2)&lt;br /&gt;Fragment size=4096 (log=2)&lt;br /&gt;Stride=0 blocks, Stripe width=0 blocks&lt;br /&gt;655360 inodes, 2621440 blocks&lt;br /&gt;131072 blocks (5.00%) reserved for the super user&lt;br /&gt;First data block=0&lt;br /&gt;Maximum filesystem blocks=2684354560&lt;br /&gt;80 block groups&lt;br /&gt;32768 blocks per group, 32768 fragments per group&lt;br /&gt;8192 inodes per group&lt;br /&gt;Superblock backups stored on blocks:&lt;br /&gt;32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632&lt;br /&gt;&lt;br /&gt;Writing inode tables: done        &lt;br /&gt;Creating journal (32768 blocks): done&lt;br /&gt;Writing superblocks and filesystem accounting information: done&lt;br /&gt;&lt;br /&gt;This filesystem will be automatically checked every 37 mounts or&lt;br /&gt;180 days, whichever comes first.  Use tune4fs -c or -i to override.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then the disk is usable but you need to mount it. Since it in this case is a staging disk I want to mount it as such. So I create a directory /stage in the root:&lt;br /&gt;&lt;pre&gt;[root@server1 /]# mkdir stage&lt;br /&gt;[root@server1 /]# ls -l&lt;br /&gt;total 186&lt;br /&gt;...&lt;br /&gt;drwxr-xr-x   2 root   root      4096 Sep  9 17:43 stage&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then create an entry in the /etc/fstab:&lt;br /&gt;&lt;pre class="brush:bash"&gt;...&lt;br /&gt;/dev/sdc                 /stage                  ext4    defaults        1 2&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Of course it is most convenient to copy an existing row and edit it in the above way. Take care of editing the file system correctly  (ext4 in this case).&lt;br /&gt;You can mount the disk with mount /stage.&lt;br /&gt;Then the owner is automatically root:root. To enable another user (eg. oracle) to use it you can create a directory oracle in it and change the owner to oracle:&lt;br /&gt;&lt;pre class="brush:bash"&gt;[root@server1 ~]# cd /stage&lt;br /&gt;[root@server1 stage]# mkdir oracle&lt;br /&gt;[root@server1 stage]# chown oracle:oinstall oracle&lt;br /&gt;[root@server1 stage]# ls -l&lt;br /&gt;total 20&lt;br /&gt;drwx------ 2 root   root     16384 Sep 15 17:51 lost+found&lt;br /&gt;drwxr-xr-x 2 oracle oinstall  4096 Sep 15 18:05 oracle&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;2.2 Logical Volume Manager&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Using a Logical Volume Group with a Logical Volume gives you a little more flexibility in extending your disk. Also, using the Logical Volume manager is a little simpeler. Since there is a nice gui for it in Gnome.&lt;br /&gt;Start it using the administration menu:&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-po-o_mv05sU/TnIVoeyQOmI/AAAAAAAAAA4/m9dgpZ0_oJU/s1600/VBLVMgr1-Start.jpg"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 243px; height: 320px;" src="http://2.bp.blogspot.com/-po-o_mv05sU/TnIVoeyQOmI/AAAAAAAAAA4/m9dgpZ0_oJU/s320/VBLVMgr1-Start.jpg" alt="" id="BLOGGER_PHOTO_ID_5652604267506186850" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;You need to provide the root password.&lt;br /&gt;Then you get in the following screen:&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-HAox7Pnm7ks/TnIVonH4PXI/AAAAAAAAABA/AEWFYxrlHus/s1600/Screenshot-Logical%2BVolume%2BManagement.png"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 189px;" src="http://3.bp.blogspot.com/-HAox7Pnm7ks/TnIVonH4PXI/AAAAAAAAABA/AEWFYxrlHus/s320/Screenshot-Logical%2BVolume%2BManagement.png" alt="" id="BLOGGER_PHOTO_ID_5652604269744373106" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Here you see an uninitialized disk. Actually it is the disk that I used in my previous example. So it is (in my case at least) already partitioned and formated. That would not be the case with new disk of course.&lt;br /&gt;So first you have to initialize it and then it asks to partition it.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-jd_OqhXzS3w/TnIVopioebI/AAAAAAAAABI/e1Ha9yRRXoM/s1600/Screenshot-Format.png"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 129px;" src="http://3.bp.blogspot.com/-jd_OqhXzS3w/TnIVopioebI/AAAAAAAAABI/e1Ha9yRRXoM/s320/Screenshot-Format.png" alt="" id="BLOGGER_PHOTO_ID_5652604270393457074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;It gives an error and suggests a reboot. That I did and I just re-initalized it. Which went ok.&lt;br /&gt;After it is initialized you'll find it in the Unallocated Volumes node. You can add it to an existing volume group. That is handy if you want to extend it. Especially in an enterprise environment that needs to extend a volume with more space (for a growing database or something).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-KnCmFsJVluA/TnIYCtgEe6I/AAAAAAAAABQ/YV-FULA3LZM/s1600/Screenshot-Logical%2BVolume%2BManagement-1.png"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 189px;" src="http://3.bp.blogspot.com/-KnCmFsJVluA/TnIYCtgEe6I/AAAAAAAAABQ/YV-FULA3LZM/s320/Screenshot-Logical%2BVolume%2BManagement-1.png" alt="" id="BLOGGER_PHOTO_ID_5652606917156305826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;In this case we choose to create a new Volume Group.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-1XBfuPD5uE0/TnIYC7Mu5SI/AAAAAAAAABg/CJpqHzw7zOc/s1600/Screenshot-New%2BVolume%2BGroup.png"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 201px;" src="http://2.bp.blogspot.com/-1XBfuPD5uE0/TnIYC7Mu5SI/AAAAAAAAABg/CJpqHzw7zOc/s320/Screenshot-New%2BVolume%2BGroup.png" alt="" id="BLOGGER_PHOTO_ID_5652606920833295650" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Give it an appropriate name. You can choose an extent size. You'll probably don't want to create it too small, since that would probably cause an extend quite often.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-g4XaNDDQKz0/TnIYC3tPQ7I/AAAAAAAAABY/aNK9aASFKOM/s1600/Screenshot-Logical%2BVolume%2BManagement-2.png"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 189px;" src="http://3.bp.blogspot.com/-g4XaNDDQKz0/TnIYC3tPQ7I/AAAAAAAAABY/aNK9aASFKOM/s320/Screenshot-Logical%2BVolume%2BManagement-2.png" alt="" id="BLOGGER_PHOTO_ID_5652606919895892914" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Then you can create a Logical Volume in it:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-s0hnCyIQaVk/TnIYDew0NbI/AAAAAAAAABw/dOxdfZNof1c/s1600/Screenshot-Create%2BNew%2BLogical%2BVolume.png"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 239px; height: 320px;" src="http://2.bp.blogspot.com/-s0hnCyIQaVk/TnIYDew0NbI/AAAAAAAAABw/dOxdfZNof1c/s320/Screenshot-Create%2BNew%2BLogical%2BVolume.png" alt="" id="BLOGGER_PHOTO_ID_5652606930379879858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Choose Ext4 for the filesystem. Click on "Use Remaining" to span the complete partion.&lt;br /&gt;You can check "Mount" and "Mount when rebooted".&lt;br /&gt;After pressing "Ok" you get the following dialog:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-XFQgj_UaK_E/TnIYDNeYDwI/AAAAAAAAABo/FHG1KQx49Wc/s1600/Screenshot-system-config-lvm.png"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 122px;" src="http://1.bp.blogspot.com/-XFQgj_UaK_E/TnIYDNeYDwI/AAAAAAAAABo/FHG1KQx49Wc/s320/Screenshot-system-config-lvm.png" alt="" id="BLOGGER_PHOTO_ID_5652606925739134722" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Of course you choose "Yes". If you check the /etc/fstab you'll find an entry like:&lt;br /&gt;&lt;pre class="brush:bash"&gt;/dev/VolGroup02/LogVol00                /stage          ext4    defaults        1 2&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;3. Copy/Move the files to the new disk&lt;/span&gt;&lt;br /&gt;Well, I assume I don't have to explain this. Fortunately in my case the installation is done in /u01/app/oracle. So I could name my mount point /u01. It's important to choose the mount point precisely as the first directory of the directory path (see step 2). To do so, you'd probably rename the directory with the installation first. The result should be that the mount point and the rest of the directory structure matches the original path. Otherwise the installation would break and the whole exercise is quite needless.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4. Detach the staging disk&lt;/span&gt;&lt;br /&gt;You probably don't want to ship the staging disk with the VM. In this decomposition project we created it to get the staging files out of the root disk. Normally when creating a VM you create an empty staging disk and copy the setup files into it. After doing the installation you don't need the stage disk anymore. But it can be handy to refine an installation later on or redo an installation in an other VM. In those cases you'll want to backup the disk.&lt;br /&gt;&lt;br /&gt;But anyway, at this point you can detach it from your VM. But before you do that it is &lt;span style="font-weight: bold;"&gt;extremely important &lt;/span&gt;to remove or comment the corresponding line (see the line above) from the /etc/fstab. If you don't you'll not be able to restart the VM again. Because Linux tries to mount the disk that can't be found when removed from the storage.&lt;br /&gt;&lt;br /&gt;Then you can shutdown the machine, go to the storage settings of the machine and remove the disk from the sata controller.&lt;br /&gt;&lt;br /&gt;If you removed the disk from the /etc/fstab then you can safely startup the VM again.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;5. Transform the OS disk from VMDK to VDI&lt;/span&gt;&lt;br /&gt;To be able to compact the disk, you'll neet to transform it to VDI. VirtualBox can't convert it in one go. You'll need to convert from VMDK to Raw format first and then from Raw to VDI.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;5.1 Convert from VMDK to Raw&lt;/span&gt;&lt;br /&gt;Open a command window or terminal/console session and cd to your VirtualBox installation. My host is a Windows 7 laptop and my VirtualBox Installation is in c:\Program Files\Oracle\VirtualBox&amp;gt;. In that directory you'll find the Vboxmanage tool. To convert the disk to raw you issue the command:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:plain"&gt;VboxManage internalcommands converttoraw  -format vmdk &amp;lt;path to vmdk disk&amp;gt; &amp;lt;path to new raw disk&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Spaces in folders are not so convenient, since it can break the option list in the command line. Enclose the path's to the input (vmdk) and output (raw) disk with quotes.&lt;br /&gt;For example:&lt;br /&gt;&lt;pre class="brush:plain"&gt;c:\Program Files\Oracle\VirtualBox&amp;gt;VboxManage internalcommands converttoraw -format vmdk "c:\Users\makker\VirtualBox VMs\PTS_WebCenter_PS4\PTS_DWN_Webcenter_PS4-disk1.vmdk" "d:\VirtualMachines\VirtualBox\Webcenter11g\PTS_Webcenter_PS4-disk1.raw"&lt;br /&gt;Converting image "c:\Users\makker\VirtualBox VMs\PTS_WebCenter_PS4\PTS_DWN_Webcenter_PS4-disk1.vmdk" with size 536870912&lt;br /&gt;00 bytes (51200MB) to raw...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It should be needles to say that it is not so wise to do this while running the Virtual Machine. Make sure it is down before running the conversion.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;5.2 Convert from Raw to VDI&lt;/span&gt;&lt;br /&gt;The command to convert it from raw to VDI is quite similar. Remarkably the conversion to raw is apparently an "internal command" to virtual box, but the conversion from raw to another disk format is not. The command is:&lt;br /&gt;&lt;pre class="brush:plain"&gt;VboxManage convertfromraw &amp;lt;path to raw disk&amp;gt; &amp;lt;path to (new) VDI disk&amp;gt; --format vdi --variant Standard&lt;br /&gt;&lt;/pre&gt;For example:&lt;br /&gt;&lt;pre class="brush:plain"&gt;c:\Program Files\Oracle\VirtualBox&amp;gt;VboxManage convertfromraw d:\VirtualMachines\VirtualBox\Webcenter11g\PTS_Webcenter_PS&lt;br /&gt;4-disk1.raw "c:\Users\makker\VirtualBox VMs\PTS_WebCenter_PS4\PTS_Webcenter_PS4-disk1.vdi" --format vdi --variant Standard&lt;br /&gt;Converting from raw image file="d:\VirtualMachines\VirtualBox\Webcenter11g\PTS_Webcenter_PS4-disk1.raw" to file="c:\Users\makker\VirtualBox VMs\PTS_WebCenter_PS4\PTS_Webcenter_PS4-disk1.vdi"...&lt;br /&gt;Creating dynamic image with size 53687091200 bytes (51200MB)...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For a big disk, this can take quite an amount of time. In my case it took about 20 minutes per conversion.&lt;br /&gt;&lt;br /&gt;Having done this, you can remove the VMDK from the storage in the Virtual Machine settings and add the VDI disk. You can do that in the same way as shown above with creating a new disk, except in stead choose "existing disk".&lt;br /&gt;Make sure you put the disk on the correct sata port. For the root disk this should be port 0:&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-FHUD318lJNE/TnIrKqHzM-I/AAAAAAAAAB4/cC1FLqdDqQ4/s1600/VBAddHardDisk-Sata-Port.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 233px;" src="http://2.bp.blogspot.com/-FHUD318lJNE/TnIrKqHzM-I/AAAAAAAAAB4/cC1FLqdDqQ4/s320/VBAddHardDisk-Sata-Port.jpg" alt="" id="BLOGGER_PHOTO_ID_5652627944409084898" border="0" /&gt;&lt;/a&gt;The root disk is of course the first one to be found by Linux and should get /dev/sda as device name. If it is your second it should get port 1 and thus named /dev/sdb by Linux, and so on.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;6. Shrink/Compact the OS disk&lt;/span&gt;&lt;br /&gt;Now, the disks are VDI, the root disk only contains the OS by now, since we moved the staging and installation in step 3. However: the disk is still huge: 30GB while the OS would only take about 5 to 6 GB (OS plus swap space). So it needs to shrink.&lt;br /&gt;But for the compact tool, this 25GB remaining space is written and thus data. We first have to zero out the space. There is a tool for that: zerofree. Unfortunately it is not in the Oracle Enterprise Linux distribution. But OEL 5 is compatible with RedHat5. So I found my rpm &lt;a href="http://rpm.pbone.net/index.php3/stat/4/idpl/15269589/dir/redhat_el_5/com/zerofree-1.0.1-5.el5.i386.rpm.html"&gt;here&lt;/a&gt;. Be sure you download the correct one (i386 or x86_64). Install it as root with&lt;br /&gt;&lt;pre class="brush:bash"&gt;rpm -ihv zerofree-1.0.1-5.el5.i386.rpm&lt;/pre&gt;Well and then we have a problem. Zerofree only works on a readonly filesystem.&lt;br /&gt;So we have to mount the rootdisk read only. That's not so easy since there are several processes that runs against the root disk.&lt;br /&gt;Most of them are ruledout when booting the system in single user mode.&lt;br /&gt;To do so login as root and issue:&lt;br /&gt;&lt;pre class="brush:bash"&gt;[root@server1 ~]# telinit 1&lt;/pre&gt;&lt;br /&gt;This causes the system into single user mode and doing so terminating most of the services. You'll find yourself logged on as root.&lt;br /&gt;However, probably there will be still some services running.&lt;br /&gt;To check them out:&lt;br /&gt;&lt;pre class="brush:bash"&gt;sh-3.2# service --status-all|grep runnnig&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This will list all possibly running (or explictly stated "not running"  services.&lt;br /&gt;You can stop services by:&lt;br /&gt;&lt;pre class="brush:bash"&gt;sh-3.2# service iscsid stop&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Stop all running services and kill all p&lt;br /&gt;Then you can try to remount the root volume rewritable:&lt;br /&gt;&lt;pre class="brush:bash"&gt;sh-3.2# mount -n -o remount,ro -t ext3 /dev/VolGroup00/LogVol00 /&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If that succeeds then you can zerofree the filesystem by:&lt;br /&gt;&lt;pre class="brush:bash"&gt;zerofree /dev/VolGroup00/LogVol00&lt;br /&gt;&lt;/pre&gt;After this we're ready to compact the disk. You can shutdown the system by issueing the command:&lt;br /&gt;&lt;pre class="brush:bash"&gt;sh-3.2# init 0&lt;/pre&gt;&lt;br /&gt;Go to the VirtualBox install directory again in a command window.&lt;br /&gt;To compact the disk, VitualBox has the command:&lt;br /&gt;&lt;pre class="brush:plain"&gt;VboxManage modifyhd &amp;lt;path to the VDI disk file&amp;gt; --compact&lt;/pre&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;pre class="brush:plain"&gt;c:\Program Files\Oracle\VirtualBox&amp;gt;VboxManage modifyhd "c:\Users\makker\VirtualBox VMs\PTS_WebCenter_PS4\PTS_Webcenter_PS4-disk1.vdi" --compact&lt;/pre&gt;&lt;br /&gt;After a while the file is probaly a lot smaller.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;A first blog in a long time and it became quite a story. I feel like it looks like a little VirtualBox and Oracle Enterprise Linux administration course.&lt;br /&gt;&lt;br /&gt;The last few months I created several VM's with environments to do courses (Virtual Course Environments I call them). And several of these tasks help me with this. In fact, see it as a toolbox of VCE creation. And the 30GB VM? Exported to an OVA file it is only 11GB now...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-6474792896876182426?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/6474792896876182426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=6474792896876182426' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6474792896876182426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6474792896876182426'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/09/decomposing-virtual-machines.html' title='Decomposing Virtual Machines'/><author><name>Martien van den Akker|Darwin-IT</name><uri>http://www.blogger.com/profile/08296120245673883785</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-GvsFF1p9dPs/TnIE_gdJ6iI/AAAAAAAAAAQ/Qtk47A9UPJM/s72-c/VBAddHardDisk-1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-2774645894544879395</id><published>2011-06-30T06:17:00.000-07:00</published><updated>2011-06-30T06:17:33.445-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle BPM Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><title type='text'>BPM 11g Advanced Workshop</title><content type='html'>Last week I was on a trip to Lissabon for a &lt;a href="http://soacommunity.wordpress.com/2011/06/01/summer-camps-adf-bpm-webcenter/"&gt;BPM 11g Advanced Workshop&lt;/a&gt;. In the same event there were also advanced courses on ADF and Webcenter.&lt;br /&gt;&lt;br /&gt;It was a pleasant week since there were showers all over the place in the Netherlands. Since the pentacost weekend there nearly wasn't a dry moment over here. Portugal was cloudless and the ocean was really refreshing.&lt;br /&gt;&lt;br /&gt;The BPM workshop was actually about building a POC on the process of handling a request on increasing the credit limit on a credit card of a fictive bank. You had to create an application with a team of 3 or 4 members involving:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ADF Web application for initiating the process using either Webservice or (better) EDN.&lt;/li&gt;&lt;li&gt;Advanced Business Rules for determining the allowed increase&lt;/li&gt;&lt;li&gt;ADF Human Task for approval screens&lt;/li&gt;&lt;li&gt;Implementing Conversation/Correlation constructs using BPEL to be able to have cancel or fraud-detection messages influencing the running process. BPM currently lacks functionality to handle multiple conversations/correlations.&lt;/li&gt;&lt;li&gt;BAM, BAM, BAM (seen as highly convincing in a POC)&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;Although it was not required, I for myself was so stubborn to insist on creating a Custom ADF Human Task screen to initiate the BPM Process. Since I've ran in to that problem in an earlier BPM11g try-out. I started on an investigation on what to do to rebuild an BPM10R3 project into BPM11g.&lt;br /&gt;&lt;br /&gt;BPM11g is a real new product. The way I see it, there is little from the old BPM10 product. You could find a significant part from BPM10 in the modeller (studio). But the engine part is replaced by the one used by BPEL Process Manager as a base. On top of that all the parts needed to run BPM processes are added.&lt;br /&gt;BPM10 projects tend to have loads of PBL code, snippets of program code or sometimes larger amounts of code to implement a specific automatic action. For most it is used to build up request messages to call (web)services and process the response messages. But it is not unusual to have script-tasks to calculate outcomes of business rules, or other business values. Often this is done on methods of objects in object model in the Business Category. It is the part of BPM10 I was suprised of the most. Since you would not find this in BPEL (if you would left out embedded java tasks) and it should not be needed in a tool that is targeted to Business Users. In BPM11g it is not needed, because you can use XSLT and XPath (or alike) expressions to process messages. And ADF BC to display corresponding data in your Human Task Screens.&lt;br /&gt;I learned that Oracle is going to support scripting in the BPM12c release. But it will be deprecated upon introduction. Since you would not need it and should not use it. Only to be able to migrate your projects to 12c. But from there onwards you should replace your code with Data associations and Transformations. Also as a best practice: only keep the data in your project that is really needed, for example Primary/Foreign key values. All relating data needed to display in the screens you can query along using ADF BC. And that's basically what I wanted to learn about.&lt;br /&gt;&lt;br /&gt;Another neat subject we've got presented was about the upcoming feature pack that is scheduled for the summer. It is explicitly stated as not being a Patch Set. Because it's not primarily focused on bugfixing but on adding new features. To name a few:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Business Rules made simpeler&lt;/li&gt;&lt;li&gt;Support for conversation/correlation on message exchanges with multiple external systems. As you can and&amp;nbsp; should do now with BPEL&lt;/li&gt;&lt;li&gt;Migration from Oracle Workflow!&lt;/li&gt;&lt;/ul&gt;The latter I found very surprising. It has been for years stated that Oracle ends with Oracle Workflow from the end of support of the 10g product-line. A very big pity if you're asking me. I would very much support the idea that Oracle should give Oracle Workflow over to the Open Source community. But that aside. Since in 2004 Collaxa was acquired because of the BPEL PM, it was thought to be the replacement for OWF. Although until SOASuite11g there was no alternative foreseen for OWF's Business Event System. With SOASuite11g there is an alternative in ways of EDN (Event Delivery Network). But because of this migration tool apparently BPM is rightly seen as the replacement of OWF. Although it is kind of late. Because I suppose there are not yet so many OWF Customers left. Oracle should have already convinced them all over to BPEL. Particularly Oracle EBusiness Suite customers could still have complex custom workflows. For those customers the migration to BPM11g would be very interesting.&lt;br /&gt;&lt;br /&gt;After all it was a very good and recommendable course. Having worked and talked and dined with more or less Oracle SOA/BPM Specialist all over Europe and the people from Oracle Product Mgt. I hope I have been able to give you a glimpse on the week to get tasty for another round of this event. I hope I can get into the ADF or Webcenter class... Not only because Lissabon is nice...&lt;br /&gt;&lt;br /&gt;And now we wait ... , for&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The sun breaking through in Holland&lt;/li&gt;&lt;li&gt;A nice vacation in France&lt;/li&gt;&lt;li&gt;ehm, oh yes: the SOA/BPM feature pack to be released this summer&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-2774645894544879395?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/2774645894544879395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=2774645894544879395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2774645894544879395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2774645894544879395'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/06/bpm-11g-advanced-workshop.html' title='BPM 11g Advanced Workshop'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-3629478239096970611</id><published>2011-06-29T00:37:00.000-07:00</published><updated>2011-06-29T22:12:14.357-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project portfolio management'/><category scheme='http://www.blogger.com/atom/ns#' term='fusion applications'/><category scheme='http://www.blogger.com/atom/ns#' term='supply chain'/><category scheme='http://www.blogger.com/atom/ns#' term='installation'/><category scheme='http://www.blogger.com/atom/ns#' term='procurement'/><title type='text'>Oracle Fusion Applications 11g Release 1 (11.1.1.5.0)</title><content type='html'>&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;div&gt;Since June 7 Oracle has quietly released Fusion Applications v1.0&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It can be downloaded from http://edelivery.oracle.com at this moment from it's own Fusion Application section.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;div&gt;If you have 64-bit Linux available you may even install it, without to many hurdles:&lt;/div&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;a href="http://onlineappsdba.com/index.php/2011/06/15/install-oracle-fusion-applications-in-10-steps/" target="_blank" style="color: rgb(0, 0, 204); "&gt;http://onlineappsdba.com/&lt;wbr&gt;index.php/2011/06/15/install-&lt;wbr&gt;oracle-fusion-applications-in-&lt;wbr&gt;10-steps/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;div&gt;Official information about the available 'modules' can be found here &lt;a href="http://www.oracle.com/us/products/applications/fusion/index.html" target="_blank" style="color: rgb(0, 0, 204); "&gt;http://www.oracle.com/us/&lt;wbr&gt;products/applications/fusion/&lt;wbr&gt;index.html&lt;/a&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The official pricing is available (since June 27th) from:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.oracle.com/us/corporate/pricing/fusion-applications-price-list-418746.pdf"&gt;http://www.oracle.com/us/corporate/pricing/fusion-applications-price-list-418746.pdf&lt;/a&gt; see also &lt;/div&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;a href="http://www.cio.com/article/685156/Oracle_Fusion_Applications_Pricing_Revealed" target="_blank" style="color: rgb(0, 0, 204); "&gt;http://www.cio.com/&lt;wbr&gt;article/685156/Oracle_Fusion_&lt;wbr&gt;Applications_Pricing_Revealed&lt;/a&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;div&gt;for a discussion.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;An overview can be found on &lt;/span&gt;&lt;span style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;a href="http://www.oracleappshub.com/fusion/oracle-fusion-and-oracle-fusion-applications-overview/" target="_blank" style="color: rgb(0, 0, 204); "&gt;http://www.oracleappshub.&lt;wbr&gt;com/fusion/oracle-fusion-and-&lt;wbr&gt;oracle-fusion-applications-&lt;wbr&gt;overview/&lt;/a&gt;&lt;/span&gt;&lt;span style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt; where you can also find a short description of Fusion Applications Supply Chain, Procurement and Project Portfolio Management.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The documentation can also be downloaded from edelivery.oracle.com or may be viewed more easily at&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;a href="http://www.orastudy.com/oradoc/selfstu/fusion/index.htm" target="_blank" style="color: rgb(0, 0, 204); "&gt;http://www.orastudy.com/&lt;wbr&gt;oradoc/selfstu/fusion/index.&lt;wbr&gt;htm&lt;/a&gt; &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;or &lt;a href="http://www.orastudy.com/oradoc/selfstu/fusion/sysint_role.htm" target="_blank" style="color: rgb(0, 0, 204); "&gt;http://www.orastudy.com/&lt;wbr&gt;oradoc/selfstu/fusion/sysint_&lt;wbr&gt;role.htm&lt;/a&gt; for the documentation for the System Implementor/ntegrator job role.&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;div&gt;&lt;div&gt;&lt;span style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="gmail_quote"&gt;&lt;div&gt;The first Fusion Application book by Richard Bingham can be pre-viewed (and ordered) from McGraw-Hill:&lt;/div&gt;&lt;div&gt;TOC &lt;a href="http://www.mhprofessional.com/downloads/products/0071750339/0071750339_toc.pdf" target="_blank" style="color: rgb(0, 0, 204); "&gt;http://www.mhprofessional.&lt;wbr&gt;com/downloads/products/&lt;wbr&gt;0071750339/0071750339_toc.pdf&lt;/a&gt; &lt;/div&gt;&lt;div&gt;Chapter 1 &lt;a href="http://www.mhprofessional.com/downloads/products/0071750339/0071750339-ch01.pdf" target="_blank" style="color: rgb(0, 0, 204); "&gt;http://www.mhprofessional.&lt;wbr&gt;com/downloads/products/&lt;wbr&gt;0071750339/0071750339-ch01.pdf&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Chapter 2 &lt;a href="http://www.oracle.com/technetwork/articles/managing-fusion-apps-418611.pdf" target="_blank" style="color: rgb(0, 0, 204); "&gt;http://www.oracle.com/&lt;wbr&gt;technetwork/articles/managing-&lt;wbr&gt;fusion-apps-418611.pdf&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ofcourse I will probably not be able to &lt;i&gt;not &lt;/i&gt;discuss this this afternoon while delivering another Oracle Product &lt;/div&gt;&lt;div&gt;Portfolio Overview training. If you are interested, check out:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.darwin-it.nl/training/training/oracle-overview/"&gt;http://www.darwin-it.nl/training/training/oracle-overview/&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-3629478239096970611?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/3629478239096970611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=3629478239096970611' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3629478239096970611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3629478239096970611'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/06/oracle-fusion-applications-11g-release.html' title='Oracle Fusion Applications 11g Release 1 (11.1.1.5.0)'/><author><name>Sander Rekveld</name><uri>http://www.blogger.com/profile/02397907702680007903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-6308778986388052625</id><published>2011-06-15T11:55:00.000-07:00</published><updated>2011-06-15T11:58:28.862-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Machines'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Weblogic'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Webcenter'/><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Box'/><title type='text'>Webcenter 11g VM: Add Spaces</title><content type='html'>As mentioned in my &lt;a href="http://darwin-it.blogspot.com/2011/06/webcenter-11g-vm.html"&gt;earlier posts&lt;/a&gt;, there is a Oracle Virtual Box VM for Webcenter. But it is a VM with Webcenter Portal (11gPS3: 11.1.1.4). It turns out that Webcenter Spaces is not installed.&amp;nbsp; And since I needed just that for my course-preperations I went looking for a VM that contains spaces. I was directed to the Pre-built Appliances page &lt;a href="http://www.oracle.com/technetwork/middleware/webcenter/downloads/owcs-spaces-vbox-352174.html"&gt;for the spaces VM&lt;/a&gt; but it turns out that the links to download the files were removed, because "in the near future" a new version will be made&amp;nbsp; available.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So that leaves me with the Webcenter Portal VM. On OTN there is only one download to install Webcenter. So the software of webcenter including spaces is on the VM. The database just does not contain the repository schema's for spaces. So what to do? Well apparently the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Run RCU (Repository Creation Utility) for Spaces against the database&lt;/li&gt;&lt;li&gt;Extend the webcenter weblogic domain&lt;/li&gt;&lt;li&gt;Fiddle around somewhat to make things actually working (I found that necessary)&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;Run the RCU&lt;/b&gt;&lt;br /&gt;To be able to run the RCU you have to download the right version (11.1.1.4) and unzip it. You can download it from &lt;a href="http://it%20does%20however%20contain%20ucm%20for%20document%20management%20purposes.%20/"&gt;here&lt;/a&gt;. &lt;a href="http://www.yonaweb.be/run_rcu_webcenter"&gt;Yannick Ogena's blog &lt;/a&gt;was a good starting point here, by the way. Expand the nodes under "Prerequisites &amp;amp; Recommended Install Process" of the 11.1.1.4.0 version. Look for "4 Repository Creation Utility (11.1.1.4.0) for Linux" and download that one. Unzip it somewhere so that you can reach it from inside the VM. A shared folder would be helpful. You could of course FTP/SCP it to the VM, but I don't like that idea since it will unnecessarly expand the vitual disks.&lt;br /&gt;Then start "rcu" from the bin folder. &lt;br /&gt;If you shrunk the database like I did following my &lt;a href="http://darwin-it.blogspot.com/2011/06/webcenter-11g-vm.html"&gt;previous post on this&lt;/a&gt;, you'll hit the error that your processes parameter is too small. It has to be at least 200.&lt;br /&gt;If so increase it like:&lt;br /&gt;&lt;pre class="brush:sql"&gt;SQL&amp;gt; alter system set processes=200 scope=spfile;&lt;br /&gt;System altered.&lt;br /&gt;SQL&amp;gt; shutdown immediate;&lt;br /&gt;...&lt;br /&gt;SQL&amp;gt; startup&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the "Database Connection Details"  screen enter:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Hostname: localhost&lt;/li&gt;&lt;li&gt;Port: 1521&lt;/li&gt;&lt;li&gt;Service name: orcl&lt;/li&gt;&lt;li&gt;username: sys&lt;/li&gt;&lt;li&gt;password: welcome1 (all database passwords in the Webcenter Portal VM are "welcome1" so it might be handy to use that for all other schema's too)&lt;/li&gt;&lt;/ul&gt;Then you'll see a screen like:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_1HRXkme9PDI/TURecx1UqEI/AAAAAAAAALc/0yi_pYYUQZY/install12.png.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/_1HRXkme9PDI/TURecx1UqEI/AAAAAAAAALc/0yi_pYYUQZY/install12.png.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Check the boxes like above. It will suggest however to create a new prefix "DEV1". Instead&amp;nbsp; select the existing prefix "DEV". Then you'll mention that some of the schema's allready exist and won't be created. That's fine. Then finish the wizard keeping the defaults and confirm with "OK" after the checks. It will ask for creating non existent Tablespaces. Just confirm with OK.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;At the end you can press close to close the RCU.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Extend the domain&lt;/b&gt;&lt;br /&gt;Now the repository is ready, to extend the domain. To do so, start the domain configurator. You can find it in "/u01/app/oracle/product/Middleware/wlserver_10.3/common/bin". Start the script "config.sh".&lt;br /&gt;&lt;br /&gt;It starts with the screen:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-L7EoACYk2I0/Tfj1FBd52XI/AAAAAAAACVA/JDQFTUjjiBo/s1600/Screenshot-Fusion+Middleware+Configuration+Wizard-0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="229" src="http://3.bp.blogspot.com/-L7EoACYk2I0/Tfj1FBd52XI/AAAAAAAACVA/JDQFTUjjiBo/s320/Screenshot-Fusion+Middleware+Configuration+Wizard-0.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Choose Extend existing Weblogic domain and look for the webcenter domain. It is the folder "/u01/app/oracle/product/Middleware/user_projects/domains/webcenter":&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-dXsqzh2UgbE/Tfj1-INwPmI/AAAAAAAACVE/pgE4gncy0SY/s1600/Screenshot-Fusion+Middleware+Configuration+Wizard-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="229" src="http://4.bp.blogspot.com/-dXsqzh2UgbE/Tfj1-INwPmI/AAAAAAAACVE/pgE4gncy0SY/s320/Screenshot-Fusion+Middleware+Configuration+Wizard-3.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;When choosing next you'll be able to select the options to add to the domain. Check the Webcenter options following the next example screendumps:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-YD_w5_8QoTQ/Tfjtvt9eMLI/AAAAAAAACU0/Mx8q3zK3mU8/s1600/Screenshot-Fusion+Middleware+Configuration+Wizard.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="229" src="http://1.bp.blogspot.com/-YD_w5_8QoTQ/Tfjtvt9eMLI/AAAAAAAACU0/Mx8q3zK3mU8/s320/Screenshot-Fusion+Middleware+Configuration+Wizard.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-RJ-QpZy_bdQ/TfjtxnH3OdI/AAAAAAAACU4/gxcGNwX0BUA/s1600/Screenshot-Fusion+Middleware+Configuration+Wizard-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="229" src="http://3.bp.blogspot.com/-RJ-QpZy_bdQ/TfjtxnH3OdI/AAAAAAAACU4/gxcGNwX0BUA/s320/Screenshot-Fusion+Middleware+Configuration+Wizard-1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Then, you'll have to add the connection properties of the different repository schemas. What you can do is select every schema that does not have orcl.localdomain as service and localhost as Host Name. Then enter in the fields in the top of the screen orcl.localdomain as service (just "orcl" is not enough, you have to add "localdomain" as a domain name). Since all the schema's have "welcome1" as a password, you can enter that in the Schema password field. Do not touch the Schema owner field. That won't be changed.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-oxJmHCe30O8/TfjtyEhwXAI/AAAAAAAACU8/dK_Xj1h3LAo/s1600/Screenshot-Fusion+Middleware+Configuration+Wizard-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="229" src="http://4.bp.blogspot.com/-oxJmHCe30O8/TfjtyEhwXAI/AAAAAAAACU8/dK_Xj1h3LAo/s320/Screenshot-Fusion+Middleware+Configuration+Wizard-2.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Then finish the wizard. After finishing up the wizard the domain has got some new Manged Servers added. You can start the Admin Server using the "startWeblogic.sh" command in "$DOMAIN_HOME/bin" (in our case: "/u01/app/oracle/product/Middleware/user_projects/domains/webcenter/bin").&lt;br /&gt;After having started the admin server you can browse to http://localhost:7001/console. Log in as:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;user name: weblogic&lt;/li&gt;&lt;li&gt;password: welcome1&lt;/li&gt;&lt;/ul&gt;At the left you'll see a portlet called "Domain Structure". Open up the "Environment" node and click on servers.&lt;br /&gt;A table with the mananged servers is given:&lt;br /&gt;&lt;table class="datatable" id="genericTableFormtable" summary="        Servers      "&gt;&lt;tbody&gt;&lt;tr class="rowEven"&gt;&lt;td&gt;&lt;input class="radioAndCheckbox" id="CoreServerServerTablePortletchosenContents" name="CoreServerServerTablePortletchosenContents" title="Select AdminServer(admin)" type="checkbox" value="com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DAdminServer%2CType%3DServer%22%29" /&gt;&lt;/td&gt;&lt;td id="name1" scope="row"&gt;&lt;a href="http://oel50wc:7001/console/console.portal?_nfpb=true&amp;amp;DispatcherPortletperspective=configuration-page&amp;amp;_pageLabel=DispatcherPage&amp;amp;DispatcherPortlethandle=com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DAdminServer%2CType%3DServer%22%29"&gt;AdminServer(admin)&lt;/a&gt;&lt;/td&gt;&lt;td id="clusterName1"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="machineName1"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="state1"&gt;RUNNING&lt;/td&gt;&lt;td id="health1"&gt;&lt;img alt="" src="http://oel50wc:7001/console/images/checkmark_status.gif" /&gt;&amp;nbsp;OK&lt;/td&gt;&lt;td id="listenPort1" nowrap="true"&gt;7001&lt;/td&gt;&lt;/tr&gt;&lt;tr class="rowOdd"&gt;&lt;td&gt;&lt;input class="radioAndCheckbox" id="CoreServerServerTablePortletchosenContents" name="CoreServerServerTablePortletchosenContents" title="Select UCM_server1" type="checkbox" value="com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DUCM_server1%2CType%3DServer%22%29" /&gt;&lt;/td&gt;&lt;td id="name2" scope="row"&gt;&lt;a href="http://oel50wc:7001/console/console.portal?_nfpb=true&amp;amp;DispatcherPortletperspective=configuration-page&amp;amp;_pageLabel=DispatcherPage&amp;amp;DispatcherPortlethandle=com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DUCM_server1%2CType%3DServer%22%29"&gt;UCM_server1&lt;/a&gt;&lt;/td&gt;&lt;td id="clusterName2"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="machineName2"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="state2"&gt;SHUTDOWN&lt;/td&gt;&lt;td id="health2"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="listenPort2" nowrap="true"&gt;16200&lt;/td&gt;&lt;/tr&gt;&lt;tr class="rowEven"&gt;&lt;td&gt;&lt;input class="radioAndCheckbox" id="CoreServerServerTablePortletchosenContents" name="CoreServerServerTablePortletchosenContents" title="Select WC_Collaboration" type="checkbox" value="com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_Collaboration%2CType%3DServer%22%29" /&gt;&lt;/td&gt;&lt;td id="name3" scope="row"&gt;&lt;a href="http://oel50wc:7001/console/console.portal?_nfpb=true&amp;amp;DispatcherPortletperspective=configuration-page&amp;amp;_pageLabel=DispatcherPage&amp;amp;DispatcherPortlethandle=com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_Collaboration%2CType%3DServer%22%29"&gt;WC_Collaboration&lt;/a&gt;&lt;/td&gt;&lt;td id="clusterName3"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="machineName3"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="state3"&gt;SHUTDOWN&lt;/td&gt;&lt;td id="health3"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="listenPort3" nowrap="true"&gt;8890&lt;/td&gt;&lt;/tr&gt;&lt;tr class="rowOdd"&gt;&lt;td&gt;&lt;input class="radioAndCheckbox" id="CoreServerServerTablePortletchosenContents" name="CoreServerServerTablePortletchosenContents" title="Select WC_CustomPortal" type="checkbox" value="com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_CustomPortal%2CType%3DServer%22%29" /&gt;&lt;/td&gt;&lt;td id="name4" scope="row"&gt;&lt;a href="http://oel50wc:7001/console/console.portal?_nfpb=true&amp;amp;DispatcherPortletperspective=configuration-page&amp;amp;_pageLabel=DispatcherPage&amp;amp;DispatcherPortlethandle=com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_CustomPortal%2CType%3DServer%22%29"&gt;WC_CustomPortal&lt;/a&gt;&lt;/td&gt;&lt;td id="clusterName4"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="machineName4"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="state4"&gt;SHUTDOWN&lt;/td&gt;&lt;td id="health4"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="listenPort4" nowrap="true"&gt;8892&lt;/td&gt;&lt;/tr&gt;&lt;tr class="rowEven"&gt;&lt;td&gt;&lt;input class="radioAndCheckbox" id="CoreServerServerTablePortletchosenContents" name="CoreServerServerTablePortletchosenContents" title="Select WC_Portlet" type="checkbox" value="com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_Portlet%2CType%3DServer%22%29" /&gt;&lt;/td&gt;&lt;td id="name5" scope="row"&gt;&lt;a href="http://oel50wc:7001/console/console.portal?_nfpb=true&amp;amp;DispatcherPortletperspective=configuration-page&amp;amp;_pageLabel=DispatcherPage&amp;amp;DispatcherPortlethandle=com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_Portlet%2CType%3DServer%22%29"&gt;WC_Portlet&lt;/a&gt;&lt;/td&gt;&lt;td id="clusterName5"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="machineName5"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="state5"&gt;SHUTDOWN&lt;/td&gt;&lt;td id="health5"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="listenPort5" nowrap="true"&gt;8889&lt;/td&gt;&lt;/tr&gt;&lt;tr class="rowOdd"&gt;&lt;td&gt;&lt;input class="radioAndCheckbox" id="CoreServerServerTablePortletchosenContents" name="CoreServerServerTablePortletchosenContents" title="Select WC_Spaces" type="checkbox" value="com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_Spaces%2CType%3DServer%22%29" /&gt;&lt;/td&gt;&lt;td id="name6" scope="row"&gt;&lt;a href="http://oel50wc:7001/console/console.portal?_nfpb=true&amp;amp;DispatcherPortletperspective=configuration-page&amp;amp;_pageLabel=DispatcherPage&amp;amp;DispatcherPortlethandle=com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_Spaces%2CType%3DServer%22%29"&gt;WC_Spaces&lt;/a&gt;&lt;/td&gt;&lt;td id="clusterName6"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="machineName6"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="state6"&gt;SHUTDOWN&lt;/td&gt;&lt;td id="health6"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="listenPort6" nowrap="true"&gt;8888&lt;/td&gt;&lt;/tr&gt;&lt;tr class="rowEven"&gt;&lt;td&gt;&lt;input class="radioAndCheckbox" id="CoreServerServerTablePortletchosenContents" name="CoreServerServerTablePortletchosenContents" title="Select WC_Utilities" type="checkbox" value="com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_Utilities%2CType%3DServer%22%29" /&gt;&lt;/td&gt;&lt;td id="name7" scope="row"&gt;&lt;a href="http://oel50wc:7001/console/console.portal?_nfpb=true&amp;amp;DispatcherPortletperspective=configuration-page&amp;amp;_pageLabel=DispatcherPage&amp;amp;DispatcherPortlethandle=com.bea.console.handles.JMXHandle%28%22com.bea%3AName%3DWC_Utilities%2CType%3DServer%22%29"&gt;WC_Utilities&lt;/a&gt;&lt;/td&gt;&lt;td id="clusterName7"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="machineName7"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="state7"&gt;SHUTDOWN&lt;/td&gt;&lt;td id="health7"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td id="listenPort7" nowrap="true"&gt;8891&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Except for "WC_Collaboration" all the WC_% servers are added. Each with it's own port number.&lt;br /&gt;&lt;br /&gt;A managed server can be started with the "startManagedWebLogic.sh"&amp;nbsp; command with as an extra parameter the name of the managed server like:&lt;br /&gt;&lt;pre class="brush:bash"&gt;startManagedWebLogic.sh WC_Spaces&lt;br /&gt;&lt;/pre&gt;You can start just the managed servers you'll need. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Tuning the domain&lt;/b&gt;&lt;br /&gt;However, when you start the added managed servers, you'll find the error: " &amp;lt;Getting boot identity from user.&amp;gt; " in the log. It seems you can enter the weblogic user but it will fail. &lt;br /&gt;I tried to add the info using the weblogic Admin Server console. But that did not work. &lt;br /&gt;&lt;br /&gt;When you start the managed server for the first time, it will add a folder with the name of the managed server in the servers folder within the domain folder, like:&lt;br /&gt;&lt;pre class="brush:bash"&gt;[oel50wc oracle /u01/app/oracle/product/Middleware/user_projects/domains/webcenter/servers]$ ls&lt;br /&gt;AdminServer     domain_bak   WC_Collaboration  WC_Portlet  WC_Utilities&lt;br /&gt;AdminServerTag  UCM_server1  WC_CustomPortal   WC_Spaces&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That is: when it is not started for the first time, it will not be there.&lt;br /&gt;To solve the boot-identity problem, add a folder called "security" to the managed-server folder. In that folder a file called "boot.properties" is expected. You can copy the security folder from for example the "UCM_server1" or "WC_CustomPortal" managed servers. Edit the boot.properties file with the following values:&lt;br /&gt;&lt;pre class="brush:plain"&gt;username=weblogic&lt;br /&gt;password=welcome1&lt;br /&gt;&lt;/pre&gt;At startup of the managed server both values will be encripted.&lt;br /&gt;&lt;br /&gt;To start the managed servers you can adapt the script vmctl.sh that is provided in the VM. I did not like that, since it has lot's of double code. I like a more modular approach. &lt;br /&gt;&lt;br /&gt;When you start all of the managed servers after some time the VM will be very busy with ... swapping! Each of the managed server is started with it's own JVM session. And it turns out that each VM gets an initial heap of 512MB and a max of 1024MB. I think that is somewhat oversized for a demo VM. You can see it in the output of the startup script. Since the first thing it does is to log the memory properties:&lt;br /&gt;&lt;pre class="brush:plain"&gt;JAVA Memory arguments: -Xms512m -Xmx1024m -XX:CompileThreshold=8000 -XX:PermSize=128m  -XX:MaxPermSize=512m &lt;br /&gt;&lt;/pre&gt;The settings can be adapted in the "setDomainEnv.sh" script in the bin folder of the webcenter domain. &lt;br /&gt;There you'll find the following values: &lt;br /&gt;&lt;pre class="brush:plain"&gt;XMS_SUN_64BIT="256"&lt;br /&gt;export XMS_SUN_64BIT&lt;br /&gt;XMS_SUN_32BIT="512"&lt;br /&gt;export XMS_SUN_32BIT&lt;br /&gt;XMX_SUN_64BIT="512"&lt;br /&gt;export XMX_SUN_64BIT&lt;br /&gt;XMX_SUN_32BIT="1024"&lt;br /&gt;export XMX_SUN_32BIT&lt;br /&gt;XMS_JROCKIT_64BIT="256"&lt;br /&gt;export XMS_JROCKIT_64BIT&lt;br /&gt;XMS_JROCKIT_32BIT="256"&lt;br /&gt;export XMS_JROCKIT_32BIT&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The VM uses 32-bit Linux and the Sun JVM. So the values to change are "XMS_SUN_32BIT" and "XMX_SUN_32BIT" for the min and max heap size respectively. I changed them to "256" and "512". Since each managed server, including the admin server uses the same script, these values are the same for each server. If you might need to adapt for just one managed server then you probably have to copy the scripts specificly for that particular managed server. Or install a node manager...&lt;br /&gt;&lt;br /&gt;Together with a downsized database, it has to make to run the VM better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-6308778986388052625?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/6308778986388052625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=6308778986388052625' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6308778986388052625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6308778986388052625'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/06/webcenter-11g-vm-add-spaces.html' title='Webcenter 11g VM: Add Spaces'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_1HRXkme9PDI/TURecx1UqEI/AAAAAAAAALc/0yi_pYYUQZY/s72-c/install12.png.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-4823189388209081985</id><published>2011-06-09T08:14:00.000-07:00</published><updated>2011-06-09T08:14:00.114-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Webcenter'/><title type='text'>Webcenter 11g VM: JDeveloper project location</title><content type='html'>The Webcenter VM on OTN contains a tutorial. The tutorial let you do some excersises with Jdeveloper. I put my projects under /home/oracle/Jdeveloper/mywork. But then it lets you unzip a package into $JDEV_USER_DIR/mywork. It turns out that it the environment variable points to: /u01/JDevApps. I found that it is set in the ".bashrc" script.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-4823189388209081985?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/4823189388209081985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=4823189388209081985' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4823189388209081985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4823189388209081985'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/06/webcenter-11g-vm-jdeveloper-project.html' title='Webcenter 11g VM: JDeveloper project location'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-7842886494581554253</id><published>2011-06-09T05:27:00.000-07:00</published><updated>2011-06-09T05:31:52.814-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database 11g'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Webcenter'/><title type='text'>Webcenter 11g VM: downsizing the database</title><content type='html'>This week I started with Webcenter 11g, using the Oracle VirtualBox VM that can be downloaded &lt;a href="http://www.oracle.com/technetwork/middleware/webcenter/downloads/owcs-portalfw-vbox-284132.html"&gt;here&lt;/a&gt;.&lt;br /&gt;One of the tips upfront was that the NAT network adapter should be "Internal Network" or "Host Only". Because otherwise the UCM part of the hands-on would not work.&lt;br /&gt;&lt;br /&gt;I also changed the memory settings to 3GB at first. But that caused my Windows 7 to stutter. Aparently Windows has became very memory consumptive. On my Linux (Open Suse) it would not have be too much of a problem to raise the VM to 3GB. An 8GB laptop would be nice. So I brought the settings back to a more modest 2,5 GB.&lt;br /&gt;&lt;br /&gt;But then I encountered that the install of Oracle DB 11g was pretty basic. And that means&amp;nbsp; a memory consumption of 700GB only the lonely for the database. I remembered my earlier &lt;a href="http://darwin-it.blogspot.com/2008/09/tuning-soasuite-10133-and-11gdb-under.html"&gt;post &lt;/a&gt;to tune Oracle DB11g together with SoaSuite10g on a OEL5 VM. &lt;br /&gt;&lt;br /&gt;It was basically about resizing the memory. What I did was to startup an XE database. There I looked at the basic memory settings. For convenience I created a plain init.ora.&lt;br /&gt;&lt;br /&gt;For the non-dba's amongst you, you can do that by loging on as internal with:&lt;br /&gt;&lt;pre class="brush:bash"&gt;sqlplus "/ as sysdba"&lt;/pre&gt;having set the ORACLE_HOME and ORACLE_SID:&lt;br /&gt;&lt;pre class="brush:bash"&gt;ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1&lt;br /&gt;ORACLE_SID=orcl&lt;/pre&gt;When you logged on as internal you can create an init.ora (also called a pfile) with:&lt;br /&gt;&lt;pre class="brush:sql"&gt;create pfile from spfile;&lt;/pre&gt;Then you'll find an init.ora in the $ORACLE_HOME/dbs folder.&lt;br /&gt;&lt;br /&gt;For an Oracle XE database the most interesting settings I found were:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:plain"&gt;java_pool_size=4194304&lt;br /&gt;    large_pool_size=4194304&lt;br /&gt;    shared_pool_size=67108864&lt;br /&gt;    open_cursors=300&lt;br /&gt;    sessions=20&lt;br /&gt;    pga_aggregate_target=70M&lt;br /&gt;    sga_target=210M&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The sga_max_size was not set.&lt;br /&gt;So I changed the 11g database with these settings, created a spfile from the pfile again (create spfile from pfile) started it again.&lt;br /&gt;&lt;br /&gt;My initorcl.ora:&lt;br /&gt;&lt;pre class="brush:plain"&gt;#orcl.__db_cache_size=222298112&lt;br /&gt;#orcl.__java_pool_size=12582912&lt;br /&gt;orcl.__java_pool_size=10M&lt;br /&gt;orcl.__large_pool_size=4194304&lt;br /&gt;....&lt;br /&gt;#orcl.__pga_aggregate_target=159383552&lt;br /&gt;orcl.__pga_aggregate_target=70M&lt;br /&gt;#orcl.__sga_target=478150656&lt;br /&gt;orcl.__sga_target=210M&lt;br /&gt;orcl.__shared_io_pool_size=0&lt;br /&gt;#orcl.__shared_pool_size=234881024&lt;br /&gt;orcl.__shared_pool_size=100M&lt;br /&gt;orcl.__streams_pool_size=0&lt;br /&gt;...&lt;br /&gt;#*.memory_target=635437056&lt;br /&gt;*.open_cursors=300&lt;br /&gt;#*.processes=150&lt;br /&gt;*.sessions=20&lt;br /&gt;...&lt;br /&gt;*.sga_max_size=250&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Mark that I unset the db_cache_size and memory_target. I also replaced the processes parameter with the sessions parameter being 20. These two parameters relate to eachother, one computed from the other.&lt;br /&gt;&lt;br /&gt;I found that I had a database of 145MB!But that's some what too small, especially the shared-poolsize being about 64M, while the sga_max_size was 145M.&lt;br /&gt;&lt;br /&gt;I changed my sga_max_size to explicitly 250M and the large_pool_size to 100M:&lt;br /&gt;&lt;pre class="brush:sql"&gt;SQL&gt; alter system set sga_max_size=250M scope=spfile;&lt;br /&gt;System altered.&lt;br /&gt;SQL&gt; alter system set shared_pool_size=100M scope=spfile;&lt;br /&gt;System altered.&lt;br /&gt;&lt;/pre&gt;Then restarting the database resulted in a database of 250M:&lt;br /&gt;&lt;pre class="brush:plain"&gt;Total System Global Area 263639040 bytes&lt;br /&gt;Fixed Size 1299284 bytes&lt;br /&gt;Variable Size 209718444 bytes&lt;br /&gt;Database Buffers 50331648 bytes&lt;br /&gt;Redo Buffers 2289664 bytes&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That looks better to me. And having it posted again refreshes it for me.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update: &lt;/b&gt; I now see that in the initorcl.ora I had a sga_max_size of 250. But that should be 250M... Maybe that caused the shared_pool_size and sga_max_size too small.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-7842886494581554253?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/7842886494581554253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=7842886494581554253' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7842886494581554253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7842886494581554253'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/06/webcenter-11g-vm.html' title='Webcenter 11g VM: downsizing the database'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-2355723833731138375</id><published>2011-05-09T04:36:00.000-07:00</published><updated>2011-05-09T04:36:50.342-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle BPM Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><title type='text'>Oracle Fusion Middleware PS4 (11.1.1.5)</title><content type='html'>This morning I talked with a few coleagues about BPM 11g. And the current patch set.&lt;br /&gt;Back to my PC and Google Reader I found out that Oracle released PS4 (11.1.1.5) last friday.&lt;br /&gt;&lt;br /&gt;So I'm very curious what this release brings for SoaSuite 11g. I found that the announcment is made in note &lt;a href="https://support.oracle.com/CSP/ui/flash.html#tab=KBHome%28page=KBHome&amp;amp;id=%28%29%29,%28page=KBNavigator&amp;amp;id=%28from=BOOKMARK&amp;amp;bmDocType=ANNOUNCEMENT&amp;amp;viewingMode=1143&amp;amp;bmDocID=1316076.1&amp;amp;bmDocDsrc=KB&amp;amp;bmDocTitle=Announcing%20Oracle%20Fusion%20Middleware%2011g%20Release%201%20%2811.1.1.5.0%29%29%29"&gt;1316076.1 at My Oracle Support&lt;/a&gt;. There is a link to a bug fix link: "&lt;a href="https://support.oracle.com/CSP/ui/flash.html#tab=KBHome%28page=KBHome&amp;amp;id=%28%29%29,%28page=KBNavigator&amp;amp;id=%28from=BOOKMARK&amp;amp;bmDocType=BULLETIN&amp;amp;viewingMode=1143&amp;amp;bmDocID=1316062.1&amp;amp;bmDocDsrc=KB&amp;amp;bmDocTitle=Fixed%20Bugs%20List%20-%20Patch%20Set%204%20%2811.1.1.5.0%29%20for%20Oracle%20Fusion%20Middleware%2011g%29%29"&gt;Fixed Bugs List - Patch Set 4 (11.1.1.5.0) for Oracle Fusion Middleware 11g [ID 1316062.1]&lt;/a&gt;". But this list suggest that there was no need for a Patch Set... Or it must be that Weblogic increased a version number to 10.3.5.&lt;br /&gt;&lt;br /&gt;The list of product included in the Patch set are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Oracle WebLogic Server 11g R1 (10.3.5)&lt;/li&gt;&lt;li&gt;Oracle Fusion Middleware Repository Creation Utility 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle SOA Suite 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle WebCenter 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle Identity Management 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle Fusion Middleware Web-Tier Utilities 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle JDeveloper 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle Application Development Runtime 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle Application Development Framework 11g R1(11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle Enterprise Content Management 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle Enterprise Repository 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle Business Process Management Suite11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle Application Integration Architecture Foundation Pack 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;li&gt;Oracle Service Bus 11g R1 (11.1.1.5.0)&lt;/li&gt;&lt;/ul&gt;But I'm so curious on the enhancements in SoaSuite en BPM Suite.&lt;br /&gt;&lt;br /&gt;SoaSuite including BPM Suite can be downloaded &lt;a href="http://www.oracle.com/technetwork/middleware/bpm/downloads/index.html"&gt;here&lt;/a&gt;. But I hope Oracle comes with a Soa/BPM VirtualBox appliance for this version soon (currently it's 11.1.1.3).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-2355723833731138375?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/2355723833731138375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=2355723833731138375' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2355723833731138375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2355723833731138375'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/05/oracle-fusion-middleware-ps4-11115.html' title='Oracle Fusion Middleware PS4 (11.1.1.5)'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-2329692115133917991</id><published>2011-04-13T02:36:00.000-07:00</published><updated>2011-04-13T02:46:56.175-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle E-Business Suite'/><title type='text'>SOA Gateway  Service Invocation Framework: Test Service</title><content type='html'>This week I'm delivering a workshop on SOA Gateway of E-Business Suite 12.1. &lt;br /&gt;On implementing the Service Invocation Framework there is a good blog-article &lt;a href="http://convergence.satpathy.org/2009/05/06/oracle/ebusiness-suite/oracle-e-business-suite-r121-integrated-soa-gateway-service-invocation-framework/"&gt;here&lt;/a&gt;.&lt;br /&gt;I found myself running into an error using the "raise in java" button from the test screen. And I was pretty sure that my values were ok.&lt;br /&gt;The error was:&lt;br /&gt;&lt;pre class="brush:plain"&gt;Exception occured in Java Raise - Exception when Invoking Web Service -&amp;gt; oracle.apps.fnd.wf.bes.InvokerException: HTTP transport error: &lt;br /&gt;javax.xml.soap.SOAPException: java.security.PrivilegedActionException: &lt;br /&gt;javax.xml.soap.SOAPException: Message send failed: For input string: &amp;quot;&amp;quot;&lt;br /&gt;&lt;/pre&gt;Since I have a background in Pl/Sql and using the Oracle Workflow Business Event system in Pl/Sql, I got some of my BES-example code from the shelf and build a package to invoke the event from Pl/Sql.&lt;br /&gt;&lt;br /&gt;Here is the package specification of my example code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;create or replace package xxx_soa_events is&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Package with functionality to support SOA Gateway Service Invocation Framework Events&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker, Darwin-IT Professionals&lt;br /&gt;    #Usage    Methods to get system_parameters&lt;br /&gt;  &lt;br /&gt;    &amp;lt;b&amp;gt;Change History&amp;lt;/b&amp;gt;&lt;br /&gt;  &lt;br /&gt;    When Who: What&lt;br /&gt;    &amp;lt;ul&amp;gt;&lt;br /&gt;     &amp;lt;li&amp;gt;07-apr-2011 Martien van den Akker: Initial Creation&amp;lt;/li&amp;gt;&lt;br /&gt;    &amp;lt;/ul&amp;gt;&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;&lt;br /&gt;  /* Name create person event */&lt;br /&gt;  c_evt_create_person constant varchar2(100) := &amp;apos;darwin.apps.soa.create_person&amp;apos;;&lt;br /&gt;  /* Event Rule result Error */&lt;br /&gt;  c_rst_error constant varchar2(10) := &amp;apos;ERROR&amp;apos;;&lt;br /&gt;  /* Event Rule result Success */&lt;br /&gt;  c_rst_success constant varchar2(10) := &amp;apos;SUCCESS&amp;apos;;&lt;br /&gt;  /* Event Rule result Warning */&lt;br /&gt;  c_rst_warning constant varchar2(10) := &amp;apos;WARNING&amp;apos;;&lt;br /&gt;  /* HZ Namespace declaration*/&lt;br /&gt;  c_hz_ns_decl   constant varchar2(150) := &amp;apos;xmlns:hz=&amp;quot;http://xmlns.oracle.com/apps/hz/soaprovider/plsql/hz_party_v2pub/&amp;quot;&amp;apos;;&lt;br /&gt;  c_hz_ns_abbrev constant varchar2(10) := &amp;apos;hz&amp;apos;;&lt;br /&gt;  c_tag_soahdr   constant varchar2(20) := &amp;apos;SOAHeader&amp;apos;;&lt;br /&gt;  c_tag_Resp     constant varchar2(20) := &amp;apos;Responsibility&amp;apos;;&lt;br /&gt;  c_tag_Respapp  constant varchar2(20) := &amp;apos;RespApplication&amp;apos;;&lt;br /&gt;  c_tag_secgrp   constant varchar2(20) := &amp;apos;SecurityGroup&amp;apos;;&lt;br /&gt;  c_tag_nlslang  constant varchar2(20) := &amp;apos;NLSLanguage&amp;apos;;&lt;br /&gt;  c_tag_orgid    constant varchar2(20) := &amp;apos;Org_Id&amp;apos;;&lt;br /&gt;  c_val_Resp     constant varchar2(20) := &amp;apos;HZ_TCA_MANAGER&amp;apos;;&lt;br /&gt;  c_val_Respapp  constant varchar2(20) := &amp;apos;AR&amp;apos;;&lt;br /&gt;  c_val_secgrp   constant varchar2(20) := &amp;apos;STANDARD&amp;apos;;&lt;br /&gt;  c_val_nlslang  constant varchar2(20) := &amp;apos;AMERICAN&amp;apos;;&lt;br /&gt;  c_val_orgid    constant varchar2(20) := &amp;apos;&amp;apos;;&lt;br /&gt;  c_par_inp_hdr  constant varchar2(20) := &amp;apos;WFBES_INPUT_HEADER&amp;apos;;&lt;br /&gt;&lt;br /&gt;  c_hz_crepers_ns_decl   constant varchar2(150) := &amp;apos;xmlns:cre=&amp;quot;http://xmlns.oracle.com/apps/hz/soaprovider/plsql/hz_party_v2pub/create_person/&amp;quot;&amp;apos;;&lt;br /&gt;  c_hz_crepers_ns_abbrev constant varchar2(10) := &amp;apos;cre&amp;apos;;&lt;br /&gt;  c_tag_inppar           constant varchar2(20) := &amp;apos;InputParameters&amp;apos;;&lt;br /&gt;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Default Rule&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Default Rule function as an example implementation for a pl/sql subscription&lt;br /&gt;  &lt;br /&gt;    #param    p_subscription_guid    Guid of the subscription of which this rule function is &lt;br /&gt;                                     the implementation&lt;br /&gt;    #param    p_event                event object&lt;br /&gt;    #return   status code&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function default_rule(p_subscription_guid in raw,&lt;br /&gt;                        p_event             in out wf_event_t)&lt;br /&gt;    return varchar2;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Default Rule&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Rule function to save events as a response in Service Invocation Framework&lt;br /&gt;  &lt;br /&gt;    #param    p_subscription_guid    Guid of the subscription of which this rule function is &lt;br /&gt;                                     the implementation&lt;br /&gt;    #param    p_event                event object&lt;br /&gt;    #return   status code&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function save_response_events(p_subscription_guid in raw, p_event in out wf_event_t)&lt;br /&gt;&lt;br /&gt;    return varchar2;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create a xml element&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Raise Event to Create a Person via SIF&lt;br /&gt;    &lt;br /&gt;    #param    p_ns_abbrev               optional namespace abbreviation&lt;br /&gt;    #param    p_tag_name                name of the tag&lt;br /&gt;    #param    p_value                   element value&lt;br /&gt;    #param    p_attrib                  optional attribute/value pair&lt;br /&gt;    #return   element&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function create_element(p_ns_abbrev in varchar2,&lt;br /&gt;                          p_tag_name  in varchar2,&lt;br /&gt;                          p_value     in varchar2,&lt;br /&gt;                          p_attrib    in varchar2) return varchar2;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create a hz SOA Header&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage   Create the HZ SOA Header denoting the responsibility&lt;br /&gt;  &lt;br /&gt;    #return   element&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function create_hz_soaheader return varchar2;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create a create person data object&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage   Create the HZ SOA Header denoting the responsibility&lt;br /&gt;    &lt;br /&gt;    #param p_person_first_name           in varchar2&lt;br /&gt;    #param p_person_middle_name          in varchar2&lt;br /&gt;    #param p_person_last_name            in varchar2&lt;br /&gt;    #param p_person_initials             in varchar2&lt;br /&gt;    #param p_person_name_phonetic        in varchar2&lt;br /&gt;    #param p_person_first_name_phonetic  in varchar2&lt;br /&gt;    #param p_person_last_name_phonetic   in varchar2&lt;br /&gt;    #param p_middle_name_phonetic        in varchar2&lt;br /&gt;    #param p_date_of_birth               in varchar2&lt;br /&gt;    #param p_place_of_birth              in varchar2&lt;br /&gt;    #param p_gender                      in varchar2&lt;br /&gt;    #param p_declared_ethnicity          in varchar2&lt;br /&gt;    #param p_created_by_module           in varchar2&lt;br /&gt;    #return   element&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function create_hz_createperson_data(p_person_first_name          in varchar2,&lt;br /&gt;                                       p_person_middle_name         in varchar2,&lt;br /&gt;                                       p_person_last_name           in varchar2,&lt;br /&gt;                                       p_person_initials            in varchar2,&lt;br /&gt;                                       p_person_name_phonetic       in varchar2,&lt;br /&gt;                                       p_person_first_name_phonetic in varchar2,&lt;br /&gt;                                       p_person_last_name_phonetic  in varchar2,&lt;br /&gt;                                       p_middle_name_phonetic       in varchar2,&lt;br /&gt;                                       p_date_of_birth              in varchar2,&lt;br /&gt;                                       p_place_of_birth             in varchar2,&lt;br /&gt;                                       p_gender                     in varchar2,&lt;br /&gt;                                       p_declared_ethnicity         in varchar2,&lt;br /&gt;                                       p_created_by_module          in varchar2)&lt;br /&gt;    return clob;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Raise Create Person Event&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Raise Event to Create a Person via SIF&lt;br /&gt;  &lt;br /&gt;    #param p_event_key                   event key&lt;br /&gt;    #param p_person_first_name           in varchar2&lt;br /&gt;    #param p_person_middle_name          in varchar2&lt;br /&gt;    #param p_person_last_name            in varchar2&lt;br /&gt;    #param p_person_initials             in varchar2&lt;br /&gt;    #param p_person_name_phonetic        in varchar2&lt;br /&gt;    #param p_person_first_name_phonetic  in varchar2&lt;br /&gt;    #param p_person_last_name_phonetic   in varchar2&lt;br /&gt;    #param p_middle_name_phonetic        in varchar2&lt;br /&gt;    #param p_date_of_birth               in varchar2&lt;br /&gt;    #param p_place_of_birth              in varchar2&lt;br /&gt;    #param p_gender                      in varchar2&lt;br /&gt;    #param p_declared_ethnicity          in varchar2&lt;br /&gt;    #param p_created_by_module           in varchar2&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  procedure raise_create_person_event(p_event_key                  in varchar2,&lt;br /&gt;                                      p_person_first_name          in varchar2,&lt;br /&gt;                                      p_person_middle_name         in varchar2,&lt;br /&gt;                                      p_person_last_name           in varchar2,&lt;br /&gt;                                      p_person_initials            in varchar2,&lt;br /&gt;                                      p_person_name_phonetic       in varchar2,&lt;br /&gt;                                      p_person_first_name_phonetic in varchar2,&lt;br /&gt;                                      p_person_last_name_phonetic  in varchar2,&lt;br /&gt;                                      p_middle_name_phonetic       in varchar2,&lt;br /&gt;                                      p_date_of_birth              in varchar2,&lt;br /&gt;                                      p_place_of_birth             in varchar2,&lt;br /&gt;                                      p_gender                     in varchar2,&lt;br /&gt;                                      p_declared_ethnicity         in varchar2,&lt;br /&gt;                                      p_created_by_module          in varchar2);&lt;br /&gt;end xxx_soa_events;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And below the body of the example package:&lt;br /&gt;&lt;pre class="brush:sql"&gt;create or replace package body xxx_soa_events is&lt;br /&gt;  c_package_name constant varchar2(30) := &amp;apos;xxx_soa_events&amp;apos;;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create an xml open tag&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    String XML Handling&lt;br /&gt;  &lt;br /&gt;    #param    p_tag_name                name of the tag&lt;br /&gt;    #param    p_attrib                  optional attribute/value pair&lt;br /&gt;    #return   tag&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function open_tag(p_tag_name in varchar2, p_attrib in varchar2)&lt;br /&gt;    return varchar2 is&lt;br /&gt;    l_tag varchar2(2000);&lt;br /&gt;  begin&lt;br /&gt;    if p_attrib is null then&lt;br /&gt;      l_tag := &amp;apos;&amp;lt;&amp;apos; || p_tag_name || &amp;apos;&amp;gt;&amp;apos;;&lt;br /&gt;    else&lt;br /&gt;      l_tag := &amp;apos;&amp;lt;&amp;apos; || p_tag_name || &amp;apos; &amp;apos; || p_attrib || &amp;apos; &amp;gt;&amp;apos;;&lt;br /&gt;    end if;&lt;br /&gt;    return l_tag;&lt;br /&gt;  end;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create a xml close tag&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    String XML Handling&lt;br /&gt;  &lt;br /&gt;    #param    p_tag_name                name of the tag&lt;br /&gt;    #return   tag&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function close_tag(p_tag_name in varchar2) return varchar2 is&lt;br /&gt;    l_tag varchar2(2000);&lt;br /&gt;  begin&lt;br /&gt;    l_tag := &amp;apos;&amp;lt;/&amp;apos; || p_tag_name || &amp;apos;&amp;gt;&amp;apos;;&lt;br /&gt;    return l_tag;&lt;br /&gt;  end;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create a xml element&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    String XML Handling&lt;br /&gt;    &lt;br /&gt;    #param    p_ns_abbrev               optional namespace abbreviation&lt;br /&gt;    #param    p_tag_name                name of the tag&lt;br /&gt;    #param    p_value                   element value&lt;br /&gt;    #param    p_attrib                  optional attribute/value pair&lt;br /&gt;    #return   element&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function create_element(p_ns_abbrev in varchar2,&lt;br /&gt;                          p_tag_name  in varchar2,&lt;br /&gt;                          p_value     in varchar2,&lt;br /&gt;                          p_attrib    in varchar2) return varchar2 is&lt;br /&gt;    l_return varchar2(32767);&lt;br /&gt;    l_tag    varchar2(2000);&lt;br /&gt;  begin&lt;br /&gt;    if p_ns_abbrev is not null then&lt;br /&gt;      l_tag := p_ns_abbrev || &amp;apos;:&amp;apos; || p_tag_name;&lt;br /&gt;    else&lt;br /&gt;      l_tag := p_tag_name;&lt;br /&gt;    end if;&lt;br /&gt;    l_return := open_tag(l_tag, p_attrib) || p_value || close_tag(l_tag);&lt;br /&gt;    return l_return;&lt;br /&gt;  end;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create a xml element&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Create an XML element&lt;br /&gt;    &lt;br /&gt;    #param    p_ns_abbrev               optional namespace abbreviation&lt;br /&gt;    #param    p_tag_name                name of the tag&lt;br /&gt;    #param    p_value                   element value&lt;br /&gt;    #return   element&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function create_element(p_ns_abbrev in varchar2,&lt;br /&gt;                          p_tag_name  in varchar2,&lt;br /&gt;                          p_value     in varchar2) return varchar2 is&lt;br /&gt;    l_return varchar2(32767);&lt;br /&gt;  begin&lt;br /&gt;    l_return := create_element(p_ns_abbrev =&amp;gt; p_ns_abbrev,&lt;br /&gt;                               p_tag_name  =&amp;gt; p_tag_name,&lt;br /&gt;                               p_attrib    =&amp;gt; null,&lt;br /&gt;                               p_value     =&amp;gt; p_value);&lt;br /&gt;    return l_return;&lt;br /&gt;  end;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create a hz SOA Header&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage   Create the HZ SOA Header denoting the responsibility&lt;br /&gt;  &lt;br /&gt;    #return   element&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function create_hz_soaheader return varchar2 is&lt;br /&gt;    l_return varchar2(2000);&lt;br /&gt;  begin&lt;br /&gt;    l_return := create_element(p_ns_abbrev =&amp;gt; c_hz_ns_abbrev,&lt;br /&gt;                               p_tag_name  =&amp;gt; c_tag_soahdr,&lt;br /&gt;                               p_attrib    =&amp;gt; c_hz_ns_decl,&lt;br /&gt;                               p_value     =&amp;gt; create_element(p_ns_abbrev =&amp;gt; c_hz_ns_abbrev,&lt;br /&gt;                                                             p_tag_name  =&amp;gt; c_tag_Resp,&lt;br /&gt;                                                             p_value     =&amp;gt; c_val_Resp) ||&lt;br /&gt;                                              create_element(p_ns_abbrev =&amp;gt; c_hz_ns_abbrev,&lt;br /&gt;                                                             p_tag_name  =&amp;gt; c_tag_Respapp,&lt;br /&gt;                                                             p_value     =&amp;gt; c_val_Respapp) ||&lt;br /&gt;                                              create_element(p_ns_abbrev =&amp;gt; c_hz_ns_abbrev,&lt;br /&gt;                                                             p_tag_name  =&amp;gt; c_tag_secgrp,&lt;br /&gt;                                                             p_value     =&amp;gt; c_val_secgrp) ||&lt;br /&gt;                                              create_element(p_ns_abbrev =&amp;gt; c_hz_ns_abbrev,&lt;br /&gt;                                                             p_tag_name  =&amp;gt; c_tag_nlslang,&lt;br /&gt;                                                             p_value     =&amp;gt; c_val_nlslang) ||&lt;br /&gt;                                              create_element(p_ns_abbrev =&amp;gt; c_hz_ns_abbrev,&lt;br /&gt;                                                             p_tag_name  =&amp;gt; c_tag_orgid,&lt;br /&gt;                                                             p_value     =&amp;gt; c_val_orgid));&lt;br /&gt;  &lt;br /&gt;    return l_return;&lt;br /&gt;  end;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Varchar2 To Clob&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Convert a clob to a varchar2&lt;br /&gt;  &lt;br /&gt;    #param    p_varchar2         varchar2&lt;br /&gt;    #return   clob&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function varchar_to_clob(p_varchar2 varchar2) return clob is&lt;br /&gt;    l_clob clob;&lt;br /&gt;  begin&lt;br /&gt;    -- Open clob&lt;br /&gt;    -- create the temporary CLOB&amp;apos;s to store the xml data that is sent to and received from the xml open gateway&lt;br /&gt;    dbms_lob.createtemporary(l_clob, false, dbms_lob.session);&lt;br /&gt;    dbms_lob.open(l_clob, dbms_lob.lob_readwrite);&lt;br /&gt;    -- Convert the input to clob&lt;br /&gt;    dbms_lob.writeappend(l_clob, length(p_varchar2), p_varchar2);&lt;br /&gt;    -- Close the Clobs&lt;br /&gt;    dbms_lob.close(l_clob);&lt;br /&gt;    -- Return&lt;br /&gt;    return l_clob;&lt;br /&gt;  end varchar_to_clob;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Clob To Varchar2&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Convert a clob to a varchar2&lt;br /&gt;  &lt;br /&gt;    #param    p_clob         clob&lt;br /&gt;    #return   varchar2&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function clob_to_varchar2(p_clob in clob) return varchar2 is&lt;br /&gt;    l_length  number;&lt;br /&gt;    l_message varchar2(32767);&lt;br /&gt;  begin&lt;br /&gt;    l_length := dbms_lob.getlength(p_clob);&lt;br /&gt;    l_length := greatest(l_length, 32767);&lt;br /&gt;    if l_length &amp;gt; 32767 then&lt;br /&gt;      l_length := 32767;&lt;br /&gt;    end if;&lt;br /&gt;    l_message := dbms_lob.substr(p_clob, l_length, 1);&lt;br /&gt;    return l_message;&lt;br /&gt;  exception&lt;br /&gt;    when others then&lt;br /&gt;      raise;&lt;br /&gt;  end clob_to_varchar2;&lt;br /&gt;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create a hz SOA Header&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage   Create the HZ SOA Header denoting the responsibility&lt;br /&gt;  &lt;br /&gt;    #return   element&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function create_hz_crepers_inp_elt(p_value varchar2) return varchar2 is&lt;br /&gt;    l_person_elt varchar2(32767);&lt;br /&gt;  begin&lt;br /&gt;    l_person_elt := create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                   p_tag_name  =&amp;gt; c_tag_inppar,&lt;br /&gt;                                   p_attrib    =&amp;gt; c_hz_crepers_ns_decl,&lt;br /&gt;                                   p_value     =&amp;gt; p_value);&lt;br /&gt;  &lt;br /&gt;    return l_person_elt;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Create a create person data object&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage   Create the HZ SOA Header denoting the responsibility&lt;br /&gt;    &lt;br /&gt;    #param p_person_first_name           in varchar2&lt;br /&gt;    #param p_person_middle_name          in varchar2&lt;br /&gt;    #param p_person_last_name            in varchar2&lt;br /&gt;    #param p_person_initials             in varchar2&lt;br /&gt;    #param p_person_name_phonetic        in varchar2&lt;br /&gt;    #param p_person_first_name_phonetic  in varchar2&lt;br /&gt;    #param p_person_last_name_phonetic   in varchar2&lt;br /&gt;    #param p_middle_name_phonetic        in varchar2&lt;br /&gt;    #param p_date_of_birth               in varchar2&lt;br /&gt;    #param p_place_of_birth              in varchar2&lt;br /&gt;    #param p_gender                      in varchar2&lt;br /&gt;    #param p_declared_ethnicity          in varchar2&lt;br /&gt;    #param p_created_by_module           in varchar2&lt;br /&gt;    #return   element&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function create_hz_createperson_data(p_person_first_name          in varchar2,&lt;br /&gt;                                       p_person_middle_name         in varchar2,&lt;br /&gt;                                       p_person_last_name           in varchar2,&lt;br /&gt;                                       p_person_initials            in varchar2,&lt;br /&gt;                                       p_person_name_phonetic       in varchar2,&lt;br /&gt;                                       p_person_first_name_phonetic in varchar2,&lt;br /&gt;                                       p_person_last_name_phonetic  in varchar2,&lt;br /&gt;                                       p_middle_name_phonetic       in varchar2,&lt;br /&gt;                                       p_date_of_birth              in varchar2,&lt;br /&gt;                                       p_place_of_birth             in varchar2,&lt;br /&gt;                                       p_gender                     in varchar2,&lt;br /&gt;                                       p_declared_ethnicity         in varchar2,&lt;br /&gt;                                       p_created_by_module          in varchar2)&lt;br /&gt;    return clob is&lt;br /&gt;    l_input_pars    varchar2(32767);&lt;br /&gt;    l_person_data   varchar2(32767);&lt;br /&gt;    l_person_rec    varchar2(32767);&lt;br /&gt;    l_init_msg_list varchar2(200);&lt;br /&gt;    l_clob          clob;&lt;br /&gt;  &lt;br /&gt;  begin&lt;br /&gt;    l_init_msg_list := create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;P_INIT_MSG_LIST&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; &amp;apos;T&amp;apos;);&lt;br /&gt;    l_person_rec    := create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;PERSON_FIRST_NAME&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_person_first_name) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;PERSON_MIDDLE_NAME&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_person_middle_name) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;PERSON_LAST_NAME&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_person_last_name) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;PERSON_INITIALS&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_person_initials) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;PERSON_NAME_PHONETIC&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_person_name_phonetic) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;PERSON_FIRST_NAME_PHONETIC&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_person_first_name_phonetic) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;PERSON_LAST_NAME_PHONETIC&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_person_last_name_phonetic) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;MIDDLE_NAME_PHONETIC&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_middle_name_phonetic) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;DATE_OF_BIRTH&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_date_of_birth) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;PLACE_OF_BIRTH&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_place_of_birth) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;GENDER&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_gender) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;DECLARED_ETHNICITY&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_declared_ethnicity) ||&lt;br /&gt;                       create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                      p_tag_name  =&amp;gt; &amp;apos;CREATED_BY_MODULE&amp;apos;,&lt;br /&gt;                                      p_value     =&amp;gt; p_created_by_module);&lt;br /&gt;  &lt;br /&gt;    l_person_data := create_element(p_ns_abbrev =&amp;gt; c_hz_crepers_ns_abbrev,&lt;br /&gt;                                    p_tag_name  =&amp;gt; &amp;apos;P_PERSON_REC&amp;apos;,&lt;br /&gt;                                    p_value     =&amp;gt; l_person_rec);&lt;br /&gt;    l_input_pars  := create_hz_crepers_inp_elt(l_init_msg_list ||&lt;br /&gt;                                               l_person_data);&lt;br /&gt;    l_clob        := varchar_to_clob(l_input_pars);&lt;br /&gt;    return l_clob;&lt;br /&gt;  end;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Raise Create Person Event&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Raise Event to Create a Person via SIF&lt;br /&gt;  &lt;br /&gt;    #param p_event_key                   event key&lt;br /&gt;    #param p_person_first_name           in varchar2&lt;br /&gt;    #param p_person_middle_name          in varchar2&lt;br /&gt;    #param p_person_last_name            in varchar2&lt;br /&gt;    #param p_person_initials             in varchar2&lt;br /&gt;    #param p_person_name_phonetic        in varchar2&lt;br /&gt;    #param p_person_first_name_phonetic  in varchar2&lt;br /&gt;    #param p_person_last_name_phonetic   in varchar2&lt;br /&gt;    #param p_middle_name_phonetic        in varchar2&lt;br /&gt;    #param p_date_of_birth               in varchar2&lt;br /&gt;    #param p_place_of_birth              in varchar2&lt;br /&gt;    #param p_gender                      in varchar2&lt;br /&gt;    #param p_declared_ethnicity          in varchar2&lt;br /&gt;    #param p_created_by_module           in varchar2&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  procedure raise_create_person_event(p_event_key                  in varchar2,&lt;br /&gt;                                      p_person_first_name          in varchar2,&lt;br /&gt;                                      p_person_middle_name         in varchar2,&lt;br /&gt;                                      p_person_last_name           in varchar2,&lt;br /&gt;                                      p_person_initials            in varchar2,&lt;br /&gt;                                      p_person_name_phonetic       in varchar2,&lt;br /&gt;                                      p_person_first_name_phonetic in varchar2,&lt;br /&gt;                                      p_person_last_name_phonetic  in varchar2,&lt;br /&gt;                                      p_middle_name_phonetic       in varchar2,&lt;br /&gt;                                      p_date_of_birth              in varchar2,&lt;br /&gt;                                      p_place_of_birth             in varchar2,&lt;br /&gt;                                      p_gender                     in varchar2,&lt;br /&gt;                                      p_declared_ethnicity         in varchar2,&lt;br /&gt;                                      p_created_by_module          in varchar2) is&lt;br /&gt;    l_data             clob;&lt;br /&gt;    l_parameters       wf_parameter_list_t := wf_parameter_list_t();&lt;br /&gt;    l_header_parameter wf_parameter_t;&lt;br /&gt;  begin&lt;br /&gt;    l_header_parameter := wf_parameter_t(name  =&amp;gt; c_par_inp_hdr,&lt;br /&gt;                                         value =&amp;gt; create_hz_soaheader);&lt;br /&gt;    l_data             := create_hz_createperson_data(p_person_first_name          =&amp;gt; p_person_first_name,&lt;br /&gt;                                                      p_person_middle_name         =&amp;gt; p_person_middle_name,&lt;br /&gt;                                                      p_person_last_name           =&amp;gt; p_person_last_name,&lt;br /&gt;                                                      p_person_initials            =&amp;gt; p_person_initials,&lt;br /&gt;                                                      p_person_name_phonetic       =&amp;gt; p_person_name_phonetic,&lt;br /&gt;                                                      p_person_first_name_phonetic =&amp;gt; p_person_first_name_phonetic,&lt;br /&gt;                                                      p_person_last_name_phonetic  =&amp;gt; p_person_last_name_phonetic,&lt;br /&gt;                                                      p_middle_name_phonetic       =&amp;gt; p_middle_name_phonetic,&lt;br /&gt;                                                      p_date_of_birth              =&amp;gt; p_date_of_birth,&lt;br /&gt;                                                      p_place_of_birth             =&amp;gt; p_place_of_birth,&lt;br /&gt;                                                      p_gender                     =&amp;gt; p_gender,&lt;br /&gt;                                                      p_declared_ethnicity         =&amp;gt; p_declared_ethnicity,&lt;br /&gt;                                                      p_created_by_module          =&amp;gt; p_created_by_module);&lt;br /&gt;    l_parameters.extend;&lt;br /&gt;    l_parameters(l_parameters.count) := l_header_parameter;&lt;br /&gt;    wf_event.raise(p_event_name =&amp;gt; c_evt_create_person,&lt;br /&gt;                   p_event_key  =&amp;gt; p_event_key,&lt;br /&gt;                   p_event_data =&amp;gt; l_data,&lt;br /&gt;                   p_parameters =&amp;gt; l_parameters);&lt;br /&gt;  end;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Default Rule&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Default Rule function as an example implementation for a pl/sql subscription&lt;br /&gt;  &lt;br /&gt;    #param    p_subscription_guid    Guid of the subscription of which this rule function is &lt;br /&gt;                                     the implementation&lt;br /&gt;    #param    p_event                event object&lt;br /&gt;    #return   status code&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function default_rule(p_subscription_guid in raw,&lt;br /&gt;                        p_event             in out wf_event_t)&lt;br /&gt;    return varchar2 is&lt;br /&gt;    c_module_name constant varchar2(30) := &amp;apos;default_rule&amp;apos;;&lt;br /&gt;   -- l_event_name varchar2(240);&lt;br /&gt;   -- l_event_key  varchar2(240);&lt;br /&gt;  begin&lt;br /&gt;    /* l_event_name := p_event.getEventName;&lt;br /&gt;    l_event_key  := p_event.getEventKey;&lt;br /&gt;     xxx_logging.log(p_message =&amp;gt;  c_module_name&lt;br /&gt;                              || &amp;apos;.&amp;apos;|| c_package_name&lt;br /&gt;                              || &amp;apos;: &amp;apos;|| l_event_name&lt;br /&gt;                              || &amp;apos;, &amp;apos;|| l_event_key&lt;br /&gt;                   , p_log_level =&amp;gt; xxx_logging.c_debug_level);&lt;br /&gt;    if  p_event.parameter_list.count &amp;gt; 0&lt;br /&gt;    then&lt;br /&gt;      for l_idx in p_event.parameter_list.first..p_event.parameter_list.last&lt;br /&gt;      loop&lt;br /&gt;        xxx_tca_api.log( p_module_name  =&amp;gt; c_module_name&lt;br /&gt;                       , p_package_name =&amp;gt; c_package_name&lt;br /&gt;                       , p_text         =&amp;gt; l_event_name&lt;br /&gt;                       , p_parameter1   =&amp;gt; p_event.parameter_list(l_idx).getname&lt;br /&gt;                                        ||&amp;apos;: &amp;apos;||p_event.parameter_list(l_idx).getvalue);&lt;br /&gt;      end loop;&lt;br /&gt;    end if;*/&lt;br /&gt;    /*  &amp;lt;optional code for WARNING&amp;gt;&lt;br /&gt;    wf_core.context( pkg_name  =&amp;gt; c_package_name&lt;br /&gt;                   , proc_name =&amp;gt; c_module_name&lt;br /&gt;                   , arg1      =&amp;gt; p_event.geteventname( )&lt;br /&gt;                   , arg2      =&amp;gt;  p_subscription_guid);&lt;br /&gt;    wf_event.seterrorinfo( p_event =&amp;gt; p_event&lt;br /&gt;                         , p_type  =&amp;gt; c_rst_warning);&lt;br /&gt;    return c_rst_warning;*/&lt;br /&gt;    return c_rst_success;&lt;br /&gt;  exception&lt;br /&gt;    when others then&lt;br /&gt;      wf_core.context(pkg_name  =&amp;gt; c_package_name,&lt;br /&gt;                      proc_name =&amp;gt; c_module_name,&lt;br /&gt;                      arg1      =&amp;gt; p_event.geteventname,&lt;br /&gt;                      arg2      =&amp;gt; p_subscription_guid,&lt;br /&gt;                      arg3      =&amp;gt; p_event.getEventKey);&lt;br /&gt;      wf_event.seterrorinfo(p_event =&amp;gt; p_event, p_type =&amp;gt; c_rst_error);&lt;br /&gt;      return c_rst_error;&lt;br /&gt;  end default_rule;&lt;br /&gt;  /*******************************************************************************************&lt;br /&gt;    Default Rule&lt;br /&gt;  &lt;br /&gt;    #Version  0.1&lt;br /&gt;    #Author   Martien van den Akker&lt;br /&gt;    #usage    Rule function to save events as a response in Service Invocation Framework&lt;br /&gt;  &lt;br /&gt;    #param    p_subscription_guid    Guid of the subscription of which this rule function is &lt;br /&gt;                                     the implementation&lt;br /&gt;    #param    p_event                event object&lt;br /&gt;    #return   status code&lt;br /&gt;  ********************************************************************************************/&lt;br /&gt;  function save_response_events(p_subscription_guid in raw, p_event in out wf_event_t)&lt;br /&gt;    return varchar2 is&lt;br /&gt;    c_module_name constant varchar2(30) := &amp;apos;default_rule&amp;apos;;&lt;br /&gt;    l_event_name varchar2(240);&lt;br /&gt;    l_event_key  varchar2(240);&lt;br /&gt;  begin&lt;br /&gt;    l_event_name := p_event.getEventName;&lt;br /&gt;    l_event_key  := p_event.getEventKey;&lt;br /&gt;    insert into xxx_soa_response_events&lt;br /&gt;      (event_key, event_name, event)&lt;br /&gt;    values&lt;br /&gt;      (l_event_key, l_event_name, p_event);&lt;br /&gt;    return c_rst_success;&lt;br /&gt;  exception&lt;br /&gt;    when others then&lt;br /&gt;      wf_core.context(pkg_name  =&amp;gt; c_package_name,&lt;br /&gt;                      proc_name =&amp;gt; c_module_name,&lt;br /&gt;                      arg1      =&amp;gt; p_event.geteventname,&lt;br /&gt;                      arg2      =&amp;gt; p_subscription_guid,&lt;br /&gt;                      arg3      =&amp;gt; p_event.getEventKey);&lt;br /&gt;      wf_event.seterrorinfo(p_event =&amp;gt; p_event, p_type =&amp;gt; c_rst_error);&lt;br /&gt;      return c_rst_error;&lt;br /&gt;  end save_response_events;&lt;br /&gt;begin&lt;br /&gt;  -- Initialization&lt;br /&gt;  Null;&lt;br /&gt;end xxx_soa_events;&lt;br /&gt;&lt;/pre&gt;The main method here is raise_create_person_event. It get's the parameters that are needed for the call to the Create Person API. It uses some varchar2-based functions to build up an xml request message and the Apps Soa-Header.&lt;br /&gt;With this method I managed to raise an event that called the service. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The methods &lt;i&gt;default_rule &lt;/i&gt;and &lt;i&gt;save_response_events&lt;/i&gt; show examples of a pl/sql rulefunction that you can use to subscribe on a business event.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-2329692115133917991?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/2329692115133917991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=2329692115133917991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2329692115133917991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2329692115133917991'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/04/soa-gateway-service-invocation.html' title='SOA Gateway  Service Invocation Framework: Test Service'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-5325962236962927842</id><published>2011-04-12T05:48:00.000-07:00</published><updated>2011-04-12T05:48:37.429-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pl/Sql'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle E-Business Suite'/><title type='text'>Script for testing TCA Api's</title><content type='html'>If you try to test a service generated and deployed using the Service Provider in SOA Gateway, you might run into problems while the response message does not provide the appropriate messages on the functional errors.&lt;br /&gt;You passed the security authentication and the apps-authorisation and the in the SOA Monitor the webservice shows a succesful execution. But there might be fnctional errors like a lookup violation that are not shown in the response message.&lt;br /&gt;&lt;br /&gt;Then it might be usefull to just call the corresponding pl/sql api from a test script.&lt;br /&gt;&lt;br /&gt;Below you'll find a script to test the Create Person of the Public Party API. It's a Pl/Sql Developer test script that you might adapt to an sql plus or sqldeveloper script.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;declare&lt;br /&gt;  -- FND UserName&lt;br /&gt;  c_user_name          constant varchar2(30) := 'ASADMIN';&lt;br /&gt;  c_responsibility_key constant varchar2(30) := 'HZ_TCA_MANAGER';&lt;br /&gt;  -- Type for repsonsibility record&lt;br /&gt;  type t_responsibility_rec is record(&lt;br /&gt;    user_id            fnd_user.user_id%type,&lt;br /&gt;    user_name          fnd_user.user_name%type,&lt;br /&gt;    responsibility_key fnd_responsibility.responsibility_key%type,&lt;br /&gt;    responsibility_id  fnd_responsibility.responsibility_id%type,&lt;br /&gt;    appplication_id    fnd_responsibility.application_id%type);&lt;br /&gt;  g_responsibility xxx_profile.t_responsibility_rec;&lt;br /&gt;  -- Person Record&lt;br /&gt;  p_person_rec hz_party_v2pub.person_rec_type;&lt;br /&gt;  -- Error Message Fields&lt;br /&gt;  l_error_text varchar2(32767);&lt;br /&gt;  l_msg_count  number;&lt;br /&gt;  cursor c_usr(b_user_name in fnd_user.user_name%type) is&lt;br /&gt;    select usr.user_id, usr.user_name&lt;br /&gt;      from fnd_user usr&lt;br /&gt;     where usr.user_name = b_user_name;&lt;br /&gt;  r_usr c_usr%rowtype;&lt;br /&gt;  cursor c_rsp(b_responsibility_key in fnd_responsibility.responsibility_key%type) is&lt;br /&gt;    select rsp.application_id,&lt;br /&gt;           rsp.responsibility_id,&lt;br /&gt;           rsp.responsibility_key&lt;br /&gt;      from fnd_responsibility rsp&lt;br /&gt;     where rsp.responsibility_key = b_responsibility_key;&lt;br /&gt;  r_rsp            c_rsp%rowtype;&lt;br /&gt;begin&lt;br /&gt;  -- Query Responsibility Id's&lt;br /&gt;  open c_usr(b_user_name =&gt; c_user_name);&lt;br /&gt;  fetch c_usr&lt;br /&gt;    into r_usr;&lt;br /&gt;  if c_usr%found then&lt;br /&gt;    g_responsibility.user_id   := r_usr.user_id;&lt;br /&gt;    g_responsibility.user_name := r_usr.user_name;&lt;br /&gt;    open c_rsp(b_responsibility_key =&gt; c_responsibility_key);&lt;br /&gt;    fetch c_rsp&lt;br /&gt;      into r_rsp;&lt;br /&gt;    if c_rsp%found then&lt;br /&gt;      g_responsibility.responsibility_key := r_rsp.responsibility_key;&lt;br /&gt;      g_responsibility.responsibility_id  := r_rsp.responsibility_id;&lt;br /&gt;      g_responsibility.appplication_id    := r_rsp.application_id;&lt;br /&gt;    end if;&lt;br /&gt;    close c_rsp;&lt;br /&gt;  end if;&lt;br /&gt;  close c_usr;&lt;br /&gt;  -- Set Apps context&lt;br /&gt;  fnd_global.apps_initialize(user_id      =&gt; g_responsibility.user_id,&lt;br /&gt;                             resp_id      =&gt; g_responsibility.responsibility_id,&lt;br /&gt;                             resp_appl_id =&gt; g_responsibility.appplication_id);&lt;br /&gt;  -- Set Person Record&lt;br /&gt;  p_person_rec.PERSON_FIRST_NAME          := 'Jean';&lt;br /&gt;  p_person_rec.PERSON_MIDDLE_NAME         := 'Michel';&lt;br /&gt;  p_person_rec.PERSON_LAST_NAME           := 'Jarre';&lt;br /&gt;  p_person_rec.PERSON_INITIALS            := 'JM';&lt;br /&gt;  p_person_rec.PERSON_NAME_PHONETIC       := 'sjan misjel sjar';&lt;br /&gt;  p_person_rec.PERSON_FIRST_NAME_PHONETIC := 'sjan';&lt;br /&gt;  p_person_rec.PERSON_LAST_NAME_PHONETIC  := 'sjar';&lt;br /&gt;  p_person_rec.MIDDLE_NAME_PHONETIC       := 'misjel';&lt;br /&gt;  p_person_rec.DATE_OF_BIRTH              := to_date('1948-08-26',&lt;br /&gt;                                                     'yyyy-mm-dd');&lt;br /&gt;  p_person_rec.PLACE_OF_BIRTH             := 'Lyon';&lt;br /&gt;  p_person_rec.GENDER                     := 'MALE';&lt;br /&gt;  p_person_rec.DECLARED_ETHNICITY         := 'French';&lt;br /&gt;  p_person_rec.created_by_module          := 'HZ_WS';&lt;br /&gt;  -- Call the procedure&lt;br /&gt;  hz_party_v2pub.create_person(p_init_msg_list    =&gt; :p_init_msg_list,&lt;br /&gt;                               p_person_rec       =&gt; p_person_rec,&lt;br /&gt;                               p_party_usage_code =&gt; :p_party_usage_code,&lt;br /&gt;                               x_party_id         =&gt; :x_party_id,&lt;br /&gt;                               x_party_number     =&gt; :x_party_number,&lt;br /&gt;                               x_profile_id       =&gt; :x_profile_id,&lt;br /&gt;                               x_return_status    =&gt; :x_return_status,&lt;br /&gt;                               x_msg_count        =&gt; :x_msg_count,&lt;br /&gt;                               x_msg_data         =&gt; :x_msg_data);&lt;br /&gt;  l_msg_count  := fnd_msg_pub.Count_Msg;&lt;br /&gt;  l_error_text := '';&lt;br /&gt;  if l_msg_count = 1 then&lt;br /&gt;    l_error_text := 'API Error: ';&lt;br /&gt;  end if;&lt;br /&gt;  if l_msg_count &gt;= 1 then&lt;br /&gt;    for i in 1 .. l_msg_count loop&lt;br /&gt;      l_error_text := nvl(l_error_text, ' ') || chr(10) || i || '. ' ||&lt;br /&gt;                      fnd_msg_pub.get(p_encoded =&gt; fnd_api.g_false);&lt;br /&gt;    end loop;&lt;br /&gt;  &lt;br /&gt;  end if;&lt;br /&gt;  :error := l_error_text;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-5325962236962927842?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/5325962236962927842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=5325962236962927842' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5325962236962927842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5325962236962927842'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/04/script-for-testing-tca-apis.html' title='Script for testing TCA Api&apos;s'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-5398564003367980228</id><published>2011-04-12T04:56:00.000-07:00</published><updated>2011-04-12T04:56:10.452-07:00</updated><title type='text'>SOA Gateway wsse security username token</title><content type='html'>When you want to use a service generated with the EBS 12.1 SOA Gateway you'll need a wsse:security block in the soap header to authenticated against the Username token. That is when you choose to use Username-token as authentication method.&lt;br /&gt;The block that you need to add to the soap header looks like:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;wsse:Security&amp;gt;&lt;br /&gt;  &amp;lt;wsse:UsernameToken&amp;gt; &lt;br /&gt;    &amp;lt;wsse:Username&amp;gt;ASADMIN&amp;lt;/wsse:Username&amp;gt;&lt;br /&gt;    &amp;lt;wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"&amp;gt;AsAdminPassword&amp;lt;/wsse:Password&amp;gt;&lt;br /&gt;  &amp;lt;/wsse:UsernameToken&amp;gt; &lt;br /&gt;&amp;lt;/wsse:Security&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The namespace that the abbreviation wsse: points to is:&lt;br /&gt;&lt;pre class="brush:xml"&gt;xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-5398564003367980228?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/5398564003367980228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=5398564003367980228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5398564003367980228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5398564003367980228'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/04/soa-gateway-wsse-security-username.html' title='SOA Gateway wsse security username token'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-7438734968319596494</id><published>2011-03-29T05:32:00.000-07:00</published><updated>2011-03-29T05:34:42.050-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>XML to HTML through XSL</title><content type='html'>I think it was about 2005 or 2006 that we at Oracle had so-called Mudwrestle sessions. Colleagues organized workshops for each other on the latest technologies. We started at 14:00 and after some introduction we did some exercises to get familiar with the subject. Amongst subjects as Integration (InterConnect), java, linux, we had also XML. And there I got to know XSLT for the first time.&lt;br /&gt;&lt;br /&gt;To get it "in the fingers", I thought it might be handy to have all my browser links in an xml file and have an xsl attached to have it transformed into html providing them in pop-lists and a button. With a little java script it is then possible to have the link loaded after choosing a link and pressing the button. So I created my first version of the XML and XSL. It was in the time that Internet Explorer 6 was pretty new or at least the current release. I think I was into Firefox already. IE6 and Firefox were able to load and process the xsl file when it was attached to the xml file. To do so you have to add the following tag to the top of your xml file:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml-stylesheet href="links.xsl" type="text/xsl"?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Like;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;?xml-stylesheet href="links.xsl" type="text/xsl"?&amp;gt;&lt;br /&gt;&amp;lt;link-lists&lt;br /&gt;  name="Links"&lt;br /&gt;  title="Internet Links"&lt;br /&gt;  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&amp;gt;Begin van de Lists!&lt;br /&gt;  &amp;lt;lists&amp;gt;&lt;br /&gt;    &amp;lt;list&lt;br /&gt;      name="DarwinApps"&lt;br /&gt;      title="Darwin Links"&amp;gt;&lt;br /&gt;      &amp;lt;link&lt;br /&gt;        description="Darwin-IT"&lt;br /&gt;        link="http://www.darwin-it.nl"&lt;br /&gt;        name="Darwin-IT" /&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The XSL that I created for it is given at the bottom of this post.&lt;br /&gt;Last week I enhanced it a little to have a button to load all the links of a list at once. That is particularly handy for a list of webmail-urls to load at the start of your day.&lt;br /&gt;&lt;br /&gt;I'm very fond of this xml/xsl combi. It is so simple, since it consist of three ascii files (xml, xsl and css). The xml file is easy to extend and after a reload in the browser the link-lists are renewed. The xsl is simple to enhance to add extra functionality. And the css makes it possible to have it a layout that complies with your taste or desktop. Skinning was never so easy. And it works in both Windows and Linux. And probably Mac OS. On Windows XP I even had it on my Active Desktop.&amp;nbsp; But I can't find how to do it on Windows 7 or Linux.&lt;br /&gt;&lt;br /&gt;Later in history, also a few years ago (2009) I created a tool in java to edit the xml file. Also this one is enhanced a few times and last week I posted a blog on this tool. See &lt;a href="http://darwin-it.blogspot.com/2011/03/vendor-independent-xml-processing.html"&gt;here&lt;/a&gt;. I made it xml-parser-vendor-independent. And it's opensource thus you might take a look at the source.&lt;br /&gt;&lt;br /&gt;To try the xml/xsl you can open the xml-links file from &lt;a href="http://www.darwin-it.nl/fileadmin/darwin/LinkLists/DarwinLinks.xml"&gt;here&lt;/a&gt;. Of course you can download it to your laptop and edit it to add your own links and remove the ones not needed. The xsl is for download &lt;a href="http://www.darwin-it.nl/fileadmin/darwin/LinkLists/links.xsl"&gt;here &lt;/a&gt;and the css-file &lt;a href="http://www.darwin-it.nl/fileadmin/darwin/LinkLists/style/style.css"&gt;here&lt;/a&gt;. Place the xml and the xsl in the same folder, the css is expected in a subfolder called "style".&lt;br /&gt;&lt;br /&gt;Below is the source of the XSL for investigation. As you can see I set it up in a modular way. I'm used to have a template for every hierarchical level of XML. And for particular functionalities, such as the generation of the java script for each poplist. You can use the xml-tool set in the  &lt;a href="http://darwin-it.blogspot.com/2011/03/vendor-independent-xml-processing.html"&gt;the earlier post&lt;/a&gt; to perform a transform of the XML with the XSL to see the resulting HTML. Have fun with it. &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;!--  (c) 2008-2011, by Martien van den Akker  &lt;br /&gt;Darwin-IT Professionals&lt;br /&gt;--&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;xsl:stylesheet&lt;br /&gt;  version="1.0"&lt;br /&gt;  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&amp;gt;&lt;br /&gt;  &amp;lt;xsl:output&lt;br /&gt;    method="html" /&amp;gt;  &amp;lt;!--  Variables  --&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:variable&lt;br /&gt;    name="newline"&amp;gt;&lt;br /&gt;    &amp;lt;xsl:text&amp;gt;&amp;lt;/xsl:text&amp;gt;&amp;lt;/xsl:variable&amp;gt;  &amp;lt;!--  main  --&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:template&lt;br /&gt;    match="/"&amp;gt;&lt;br /&gt;    &amp;lt;html&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;xsl:call-template&lt;br /&gt;        name="heading" /&amp;gt;&lt;br /&gt;      &amp;lt;body&amp;gt;&lt;br /&gt;        &amp;lt;xsl:call-template&lt;br /&gt;          name="body" /&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;  &amp;lt;xsl:template&lt;br /&gt;    name="heading"&amp;gt;    &amp;lt;!--  Heading  --&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;head&amp;gt;&lt;br /&gt;      &amp;lt;title&amp;gt;Links&amp;lt;/title&amp;gt;&lt;br /&gt;      &amp;lt;LINK&lt;br /&gt;        HREF="style/style.css"&lt;br /&gt;        REL="STYLESHEET"&lt;br /&gt;        TYPE="text/css" /&amp;gt;&amp;lt;/head&amp;gt;    &amp;lt;!--  Script to load a page  --&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;script&lt;br /&gt;      language="javascript"&amp;gt;&lt;br /&gt;      &amp;lt;xsl:text&amp;gt;function loadPage(link)&lt;br /&gt;{&lt;br /&gt;  newWdw=window.open(link,"_blank","");&lt;br /&gt;}&amp;lt;/xsl:text&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;  &amp;lt;xsl:template&lt;br /&gt;    name="body"&amp;gt;    &amp;lt;!--  Body  --&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;body&amp;gt;&lt;br /&gt;      &amp;lt;xsl:apply-templates&lt;br /&gt;        select="/link-lists" /&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/xsl:template&amp;gt;  &amp;lt;!--  /link-lists  --&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:template&lt;br /&gt;    match="link-lists"&lt;br /&gt;    name="link-lists"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;h1&amp;gt;&lt;br /&gt;      &amp;lt;xsl:value-of&lt;br /&gt;        select="@title" /&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;    &amp;lt;table&amp;gt;&lt;br /&gt;      &amp;lt;xsl:apply-templates&lt;br /&gt;        select="lists/list" /&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/xsl:template&amp;gt;  &amp;lt;!--  /link-lists/lists/list  --&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:template&lt;br /&gt;    match="lists/list"&lt;br /&gt;    name="lists-list"&amp;gt;&lt;br /&gt;    &amp;lt;tr&amp;gt;&lt;br /&gt;      &amp;lt;td&amp;gt;&lt;br /&gt;        &amp;lt;xsl:value-of&lt;br /&gt;          select="@title" /&amp;gt;&amp;lt;/td&amp;gt;      &amp;lt;!--  generate javascript for loading a link  --&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;xsl:call-template&lt;br /&gt;        name="loadLink" /&amp;gt;      &amp;lt;!--  generate javascript for loading a links  --&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;xsl:call-template&lt;br /&gt;        name="loadAllLinks" /&amp;gt;      &amp;lt;!--  generate a poplist and a button  --&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;xsl:call-template&lt;br /&gt;        name="writePopList" /&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/xsl:template&amp;gt;  &amp;lt;!--  loadLink: generate a javascript that loads a link  --&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:template&lt;br /&gt;    name="loadLink"&amp;gt;&lt;br /&gt;    &amp;lt;xsl:text&lt;br /&gt;      disable-output-escaping="yes"&amp;gt;      &amp;lt;!--  script to load a link  --&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;    &amp;lt;script&lt;br /&gt;      language="javascript"&amp;gt;&lt;br /&gt;      &amp;lt;xsl:value-of&lt;br /&gt;        select="concat($newline,'      function load', @name,'Link()')" /&amp;gt;&lt;br /&gt;      &amp;lt;xsl:text&lt;br /&gt;        disable-output-escaping="yes"&amp;gt;{&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;      &amp;lt;xsl:value-of&lt;br /&gt;        select="concat('        var l_idx = document.', @name, 'LinkSelector.select.selectedIndex;',$newline)" /&amp;gt;&lt;br /&gt;      &amp;lt;xsl:value-of&lt;br /&gt;        select="concat('        var l_value = document.', @name, 'LinkSelector.select.options[l_idx].value;')" /&amp;gt;&lt;br /&gt;      &amp;lt;xsl:text&lt;br /&gt;        disable-output-escaping="yes"&amp;gt;if (l_value != "none")&lt;br /&gt;        {&lt;br /&gt;           loadPage(l_value);&lt;br /&gt;        }&lt;br /&gt;      }&amp;lt;/xsl:text&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/xsl:template&amp;gt;  &amp;lt;!--  loadAllLinks: generate a javascript that loads all links of a poplist  --&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:template&lt;br /&gt;    name="loadAllLinks"&amp;gt;&lt;br /&gt;    &amp;lt;xsl:text&lt;br /&gt;      disable-output-escaping="yes"&amp;gt;      &amp;lt;!--  script to load a link  --&amp;gt;&lt;br /&gt;&amp;lt;/xsl:text&amp;gt; &lt;br /&gt;    &amp;lt;script&lt;br /&gt;      language="javascript"&amp;gt;&lt;br /&gt;      &amp;lt;xsl:value-of&lt;br /&gt;        select="concat($newline,'      function loadAll', @name,'Links()')" /&amp;gt;&lt;br /&gt;      &amp;lt;xsl:text&lt;br /&gt;        disable-output-escaping="yes"&amp;gt;{&lt;br /&gt;        var l_idx;&lt;br /&gt;        var l_value;&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;      &amp;lt;xsl:value-of select="concat('        for(l_idx=0; l_idx&amp;amp;lt;document.', @name, 'LinkSelector.select.length; l_idx++)')"/&amp;gt;&lt;br /&gt;   &amp;lt;xsl:value-of select="concat($newline,'        {',$newline)"/&amp;gt;&lt;br /&gt;      &amp;lt;xsl:value-of select="concat('           l_value=document.', @name, 'LinkSelector.select.options[l_idx].value;')"/&amp;gt; &lt;br /&gt;      &amp;lt;xsl:text&lt;br /&gt;        disable-output-escaping="yes"&amp;gt;&lt;br /&gt;&lt;br /&gt;    if (l_value != "none")&lt;br /&gt;    {&lt;br /&gt;            loadPage(l_value);&lt;br /&gt;    }&lt;br /&gt;        }&lt;br /&gt;      }&amp;lt;/xsl:text&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;  &amp;lt;xsl:template&lt;br /&gt;    name="writePopList"&amp;gt;&lt;br /&gt;    &amp;lt;td&amp;gt;&lt;br /&gt;      &amp;lt;form&lt;br /&gt;        name="{concat(@name, 'LinkSelector')}"&amp;gt;&lt;br /&gt;        &amp;lt;table&lt;br /&gt;          border="0"&lt;br /&gt;          cellspacing="0"&amp;gt;&lt;br /&gt;          &amp;lt;tr&amp;gt;&lt;br /&gt;            &amp;lt;td&lt;br /&gt;              width="250px"&amp;gt;              &amp;lt;!-- Select  --&amp;gt;&lt;br /&gt;&lt;br /&gt;              &amp;lt;select&lt;br /&gt;                name="select"&amp;gt;&lt;br /&gt;                &amp;lt;option&lt;br /&gt;                  value="none"&amp;gt;Kies een link:&amp;lt;/option&amp;gt;&lt;br /&gt;                &amp;lt;xsl:for-each&lt;br /&gt;                  select="link"&amp;gt;&lt;br /&gt;                  &amp;lt;option&lt;br /&gt;                    value="{@link}"&amp;gt;&lt;br /&gt;                    &amp;lt;xsl:value-of&lt;br /&gt;                      select="@name" /&amp;gt;&amp;lt;/option&amp;gt;&amp;lt;/xsl:for-each&amp;gt;&amp;lt;/select&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;            &amp;lt;td&amp;gt;              &amp;lt;!--  Button  --&amp;gt;&lt;br /&gt;&lt;br /&gt;              &amp;lt;input&lt;br /&gt;                onclick="{concat('load',@name,'Link()')}"&lt;br /&gt;                type="button"&lt;br /&gt;                value="Toon" /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;&lt;br /&gt;            &amp;lt;td&amp;gt;              &amp;lt;!--  Button Load All --&amp;gt;&lt;br /&gt;&lt;br /&gt;              &amp;lt;input&lt;br /&gt;                onclick="{concat('loadAll',@name,'Links()')}"&lt;br /&gt;                type="button"&lt;br /&gt;                value="Toon alles" /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/form&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-7438734968319596494?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/7438734968319596494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=7438734968319596494' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7438734968319596494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7438734968319596494'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/03/xml-to-html-through-xsl.html' title='XML to HTML through XSL'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-157374502362478905</id><published>2011-03-22T03:44:00.000-07:00</published><updated>2011-03-22T03:53:09.550-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>Vendor independent XML processing</title><content type='html'>A few years ago, when I was "low in work" at the particular customer, I created a little tool set on XML processing. I called it Darwin XML Editor and XML Tester. The latter name I now find not so well choosen. So I would now call it XML Tools.&lt;br /&gt;&lt;br /&gt;The purpose of the tool set was to figure out how to process XML in java. I already had a private xml based solution to gather my frequently used browser links into an xml file and convert it using an attached xslt stylesheet to an html page. This html page provided the links in poplists and using java script it could load the link.&lt;br /&gt;It would be nice to have a hierarchical editor that showed my xml in an explorer and let me edit particular attributes in a table format.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-auqIhv0mKm4/TYhvqXHbTAI/AAAAAAAACT4/Xi1O8ZuNhig/s1600/xmleditor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="187" src="https://lh5.googleusercontent.com/-auqIhv0mKm4/TYhvqXHbTAI/AAAAAAAACT4/Xi1O8ZuNhig/s320/xmleditor.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;It turned out handy for me. But the most I had a toolkit that allowed me to easily load XML as a text file and parse it, perform xpath queries and just traverse through nodes, etc. In several projects I used it to read xml-based config files. Many of those cases I probably&amp;nbsp; could have done using Apache-commons.&lt;br /&gt;But it is handy to have your own toolkit. Especially in cases when you have repetitive lists of entities with properties.&lt;br /&gt;&lt;br /&gt;My project originally was written using the Oracle XMLParser. Handy, because I use JDeveloper and that comes with the parser. For some time now I had plans to look if I could make it vendor independent.&lt;br /&gt;&lt;br /&gt;The results can be found &lt;a href="http://sourceforge.net/projects/darwinxmltester/files/"&gt;here&lt;/a&gt;. It's open source, whatever that may mean. But it would be nice to leave the credit-references in place or refer to the credits. That would be nice for my ego...&lt;br /&gt;&lt;br /&gt;I will provide here some highlights of the changes.&lt;br /&gt;I used the following sites as my references:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/library/x-javaxpathapi.html"&gt;http://www.ibm.com/developerworks/library/x-javaxpathapi.html&lt;/a&gt; for xpath processing. .&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ling.helsinki.fi/kit/2004k/ctl257/JavaXSLT/Ch05.html%20"&gt;http://www.ling.helsinki.fi/kit/2004k/ctl257/JavaXSLT/Ch05.html &lt;/a&gt;for xslt processing&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Parsing&lt;/h4&gt;It starts with parsing. The "Oracle way" I did it was:&lt;br /&gt;&lt;pre class="brush: java"&gt;public void parse() {&lt;br /&gt;&lt;br /&gt;        try {&lt;br /&gt;            String text = super.getText();&lt;br /&gt;            if (text != null) {&lt;br /&gt;                resetError();&lt;br /&gt;                DOMParser parser = new DOMParser();&lt;br /&gt;                InputSource inputStream = new InputSource();&lt;br /&gt;                inputStream.setCharacterStream(new StringReader(text));&lt;br /&gt;                parser.parse(inputStream);&lt;br /&gt;                xmlDoc = parser.getDocument();&lt;br /&gt;&lt;br /&gt;                xmlRoot = xmlDoc.getDocumentElement();&lt;br /&gt;                nodeSelected = new NodeSelected((Node)xmlRoot);&lt;br /&gt;                parsed = true;&lt;br /&gt;                log("File: " + super.getFilePath() + " is succesfully parsed");&lt;br /&gt;            } else {&lt;br /&gt;                log("File: " + super.getFilePath() + " empty or not loaded!");&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        } catch (SAXException e) {&lt;br /&gt;            setErrorCode(EC_ERROR);&lt;br /&gt;            setError("Error parsing XML: " + e.toString());&lt;br /&gt;            error(e);&lt;br /&gt;        } catch (IOException e) {&lt;br /&gt;            setErrorCode(EC_ERROR);&lt;br /&gt;            setError("Error reading XML: " + e.toString());&lt;br /&gt;            error(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With the following oracle imports:&lt;br /&gt;&lt;pre class="brush: java"&gt;import oracle.xml.parser.v2.DOMParser;&lt;br /&gt;import oracle.xml.parser.v2.XMLDocument;&lt;br /&gt;import oracle.xml.parser.v2.XMLNode;&lt;br /&gt;import oracle.xml.parser.v2.XSLException;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The vendor independent way I used is:&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;     * Create a new DocumentBuilder.&lt;br /&gt;     * @return&lt;br /&gt;     * @throws ParserConfigurationException&lt;br /&gt;     */&lt;br /&gt;    private DocumentBuilder newDocBuilder() throws ParserConfigurationException {&lt;br /&gt;        DocumentBuilderFactory domFactory = &lt;br /&gt;            DocumentBuilderFactory.newInstance();&lt;br /&gt;        domFactory.setNamespaceAware(true); // never forget this!&lt;br /&gt;        DocumentBuilder docBuilder;&lt;br /&gt;        docBuilder = domFactory.newDocumentBuilder();&lt;br /&gt;        return docBuilder;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Create an InputSource from the xml-text&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    public InputSource getInputSource() {&lt;br /&gt;        String text = super.getText();&lt;br /&gt;        InputSource inputStream = null;&lt;br /&gt;        if (text != null) {&lt;br /&gt;            inputStream = new InputSource();&lt;br /&gt;            inputStream.setCharacterStream(new StringReader(text));&lt;br /&gt;        }&lt;br /&gt;        return inputStream;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Parse the XML in the file&lt;br /&gt;     */&lt;br /&gt;    public void parse() {&lt;br /&gt;        try {&lt;br /&gt;            InputSource inputSource = getInputSource();&lt;br /&gt;            if (inputSource != null) {&lt;br /&gt;                resetError();&lt;br /&gt;                DocumentBuilder docBuilder = newDocBuilder();&lt;br /&gt;                Document doc = docBuilder.parse(inputSource);&lt;br /&gt;                setDoc(doc);&lt;br /&gt;                parsed = true;&lt;br /&gt;                log("File: " + super.getFilePath() + " is succesfully parsed");&lt;br /&gt;            } else {&lt;br /&gt;                log("File: " + super.getFilePath() + " empty or not loaded!");&lt;br /&gt;            }&lt;br /&gt;        } catch (ParserConfigurationException e) {&lt;br /&gt;            setErrorCode(EC_ERROR);&lt;br /&gt;            setError("Error creating parser: " + e.toString());&lt;br /&gt;            error(e);&lt;br /&gt;        } catch (SAXException e) {&lt;br /&gt;            setErrorCode(EC_ERROR);&lt;br /&gt;            setError("Error parsing XML: " + e.toString());&lt;br /&gt;            error(e);&lt;br /&gt;        } catch (IOException e) {&lt;br /&gt;            setErrorCode(EC_ERROR);&lt;br /&gt;            setError("Error reading XML: " + e.toString());&lt;br /&gt;            error(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;with the following imports:&lt;br /&gt;&lt;pre class="brush: java"&gt;import javax.xml.namespace.QName;&lt;br /&gt;import javax.xml.parsers.DocumentBuilder;&lt;br /&gt;import javax.xml.parsers.DocumentBuilderFactory;&lt;br /&gt;import javax.xml.parsers.ParserConfigurationException;&lt;br /&gt;import javax.xml.xpath.XPath;&lt;br /&gt;import javax.xml.xpath.XPathConstants;&lt;br /&gt;import javax.xml.xpath.XPathExpression;&lt;br /&gt;import javax.xml.xpath.XPathExpressionException;&lt;br /&gt;import javax.xml.xpath.XPathFactory;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Mark that this code is part of a XMLFile class that extends a TextFile class that gives me the methods to load the file into a String attribute (text).&lt;br /&gt;Here I extracted the conversion from the text attribute to an InputSource object in a separate method. Also the creation of the parser (the DocumentBuilder) I put in a seperate method. This because I also need it to be able to create an empty Document.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;XPath Expressions&lt;/h4&gt;The "Oracle way" is pretty straight forward:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;     * Select Nodes using Xpath&lt;br /&gt;     * @param xpath&lt;br /&gt;     * @return NodeList &lt;br /&gt;     */&lt;br /&gt;    public NodeList selectNodes(String xpath) throws XSLException {&lt;br /&gt;        XMLDocument xmlDoc = getXmlDoc();&lt;br /&gt;        NodeList nl = xmlDoc.selectNodes(xpath);&lt;br /&gt;        return nl;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;To have it "Namespace Aware" you'll need a Namespace Resolver, which is a simple class based on a HashMap, implementing an Interface:&lt;br /&gt;&lt;pre class="brush: java"&gt;package com.darwinit.xmlfiles.xml;&lt;br /&gt;/**&lt;br /&gt; * Namespace Resolver: Helper class to do namespace aware XPath queries. &lt;br /&gt; *&lt;br /&gt; * @author Martien van den Akker&lt;br /&gt; * @author Darwin IT Professionals&lt;br /&gt; *&lt;br /&gt; * @remark: changed to JSE 1.4 code because of BPEL PM 10.1.2&lt;br /&gt; */&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;&lt;br /&gt;import oracle.xml.parser.v2.NSResolver;&lt;br /&gt;&lt;br /&gt;public class XMLNSResolver implements NSResolver{&lt;br /&gt;  private HashMap&amp;lt;String, String&amp;gt; nsMap = new HashMap&amp;lt;String, String&amp;gt;();&lt;br /&gt;    &lt;br /&gt;    public XMLNSResolver() {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;   public void addNS(String abbrev, String namespace){&lt;br /&gt;       nsMap.put(abbrev, namespace);&lt;br /&gt;   }&lt;br /&gt;    public String resolveNamespacePrefix(String string) {&lt;br /&gt;        return nsMap.get(string);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Then using the namespace resolver the code would be something like:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;     * Select nodes using Xpath with Namespace included&lt;br /&gt;     * @param xpath&lt;br /&gt;     * @return Nodelist &lt;br /&gt;     */&lt;br /&gt;    public NodeList selectNodesNS(String xpath) throws XSLException {&lt;br /&gt;    XMLDocument xmlDoc = getXmlDoc();&lt;br /&gt;    XMLNSResolver nsRes = getNsRes();&lt;br /&gt;        NodeList nl = this.xmlDoc.selectNodes(xpath, nsRes);&lt;br /&gt;        return nl;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The vendor indepent way is a little more complex. But it gives you some more flexibility.&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;     * Evaluate xpath expression &lt;br /&gt;     * &lt;br /&gt;     * @param xpathExpr the xpath expression&lt;br /&gt;     * @param returnType the return type that is expected.&lt;br /&gt;     * http://www.ibm.com/developerworks/library/x-javaxpathapi.html:&lt;br /&gt;     * XPathConstants.NODESET =&gt; node-set maps to an org.w3c.dom.NodeList&lt;br /&gt;     * XPathConstants.BOOLEAN =&gt; boolean maps to a java.lang.Boolean&lt;br /&gt;     * XPathConstants.NUMBER =&gt; number maps to a java.lang.Double&lt;br /&gt;     * XPathConstants.STRING =&gt; string maps to a java.lang.String&lt;br /&gt;     * XPathConstants.NODE&lt;br /&gt;     * &lt;br /&gt;     * @throws XPathExpressionException&lt;br /&gt;     */&lt;br /&gt;    public   Object evaluate(String xpathExpr, &lt;br /&gt;                    QName returnType) throws XPathExpressionException {&lt;br /&gt;        XPathFactory factory = XPathFactory.newInstance();&lt;br /&gt;        XPath xpath = factory.newXPath();&lt;br /&gt;        XMLNSResolver nsRes = getNsRes();&lt;br /&gt;        if (nsRes != null) {&lt;br /&gt;            xpath.setNamespaceContext(nsRes);&lt;br /&gt;        }&lt;br /&gt;        XPathExpression expr = xpath.compile(xpathExpr);&lt;br /&gt;        Document doc = getDoc();&lt;br /&gt;        Object resultObj = expr.evaluate(doc, returnType);&lt;br /&gt;        return resultObj;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Evaluate xpath expression to a double (when a number is expected from the xpath expression)&lt;br /&gt;     * &lt;br /&gt;     * @throws XPathExpressionException&lt;br /&gt;     */&lt;br /&gt;    public Double evaluateDouble(String xpathExpr) throws XPathExpressionException {&lt;br /&gt;        Double result = null;&lt;br /&gt;        Object resultObj = evaluate(xpathExpr, XPathConstants.NUMBER);&lt;br /&gt;        if (resultObj instanceof Double) {&lt;br /&gt;            result = (Double)resultObj;&lt;br /&gt;        }&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Select Nodes using Xpath&lt;br /&gt;     * &lt;br /&gt;     * @param xpath&lt;br /&gt;     * @return NodeList&lt;br /&gt;     * @throws XPathExpressionException &lt;br /&gt;     */&lt;br /&gt;    public NodeList selectNodes(String xpath) throws XPathExpressionException {&lt;br /&gt;        NodeList nl = (NodeList)evaluate(xpath, XPathConstants.NODESET);&lt;br /&gt;        return nl;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;The Namespace resolver changed slightly. It actually implements another interface:&lt;br /&gt;But the idea is the same:&lt;br /&gt;&lt;pre class="brush: java"&gt;package com.darwinit.xmlfiles.xml;&lt;br /&gt;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;&lt;br /&gt;import java.util.Iterator;&lt;br /&gt;&lt;br /&gt;import javax.xml.namespace.NamespaceContext;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Namespace Resolver: Helper class to do namespace aware XPath queries. &lt;br /&gt; *&lt;br /&gt; * @author Martien van den Akker&lt;br /&gt; * @author Darwin IT Professionals&lt;br /&gt; *&lt;br /&gt; */&lt;br /&gt;public class XMLNSResolver implements NamespaceContext {&lt;br /&gt;    private HashMap&amp;lt;String, String&amp;gt; nsMap = new HashMap&amp;lt;String, String&amp;gt;();&lt;br /&gt;   /**&lt;br /&gt;     * Constructor&lt;br /&gt;     */&lt;br /&gt;    public XMLNSResolver() {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Add a Namespace&lt;br /&gt;     * @param prefix&lt;br /&gt;     * @param namespace&lt;br /&gt;     */&lt;br /&gt;    public void addNS(String prefix, String namespace) {&lt;br /&gt;        nsMap.put(prefix, namespace);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Resolve a namespace from a prefix&lt;br /&gt;     * @param prefix&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    public String resolveNamespacePrefix(String prefix) {&lt;br /&gt;        return nsMap.get(prefix);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Resolve a namespace from a prefix&lt;br /&gt;     * @param prefix&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    public String getNamespaceURI(String prefix) {&lt;br /&gt;        return resolveNamespacePrefix(prefix);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Get the prefix that is registered for a NamespaceURI &lt;br /&gt;     * However, not necessary for xpath processing&lt;br /&gt;     * @param namespaceURI&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    public String getPrefix(String namespaceURI) {&lt;br /&gt;        throw new UnsupportedOperationException();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Get an iterator with the prefix registered for a NamespaceURI&lt;br /&gt;     * @param namespaceURI&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    public Iterator getPrefixes(String namespaceURI) {&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The differences are in the fact that you first have to 'compile' an xpath expression. And that the evaluation of the XPath on a Document expects you to provide the expected result datatype. (see the comments of the evaluate method).&lt;br /&gt;Then it will result an Object that you have to cast to the particular Java Class that corresponds with the Result XML DataType.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;XSLT&lt;/h4&gt;The last thing is transforming XSLT. The "Oracle Way" I used was:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;package com.darwinit.xmlfiles.xml;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.PrintWriter;&lt;br /&gt;import java.io.StringWriter;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.Hashtable;&lt;br /&gt;&lt;br /&gt;import oracle.xml.parser.v2.XMLDocument;&lt;br /&gt;import oracle.xml.parser.v2.XSLException;&lt;br /&gt;import oracle.xml.parser.v2.XSLProcessor;&lt;br /&gt;import oracle.xml.parser.v2.XSLStylesheet;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class XmlTransformer {&lt;br /&gt;    private void pl(String text) {&lt;br /&gt;        System.out.println(text);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public XmlTransformer() {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String transform(XMLDocument xslDoc, XMLDocument xmlDoc) {     &lt;br /&gt;     return transform (xslDoc, xmlDoc, null);&lt;br /&gt;    }    &lt;br /&gt;    &lt;br /&gt;    /**&lt;br /&gt;     * Transform the xmlDoc using xslDoc into String&lt;br /&gt;     * @param xslDoc&lt;br /&gt;     * @param xmlDoc&lt;br /&gt;     * @param parameters contains parameter that are passed to the xslt&lt;br /&gt;     * @return String output&lt;br /&gt;     */&lt;br /&gt;    public String transform(XMLDocument xslDoc, XMLDocument xmlDoc&lt;br /&gt;                           , Hashtable&amp;lt;String, String&amp;gt; parameters) {&lt;br /&gt;        XSLProcessor xslProcessor = new XSLProcessor();&lt;br /&gt;        XSLStylesheet xslt;&lt;br /&gt;        String result = "";&lt;br /&gt;        try {&lt;br /&gt;            StringWriter sw = new StringWriter();&lt;br /&gt;            PrintWriter pw = new PrintWriter(sw);&lt;br /&gt;            xslt = xslProcessor.newXSLStylesheet(xslDoc);&lt;br /&gt;            &lt;br /&gt;            xslProcessor.setXSLTVersion(XSLProcessor.XSLT20);&lt;br /&gt;            xslProcessor.showWarnings(true);&lt;br /&gt;            xslProcessor.setErrorStream(System.err);&lt;br /&gt;            &lt;br /&gt;            if (parameters != null) {&lt;br /&gt;            &lt;br /&gt;             for (String key : parameters.keySet()) {&lt;br /&gt;              String value = parameters.get(key);&lt;br /&gt;              xslProcessor.setParam("", key, value);&lt;br /&gt;             }&lt;br /&gt;            }                      &lt;br /&gt;            &lt;br /&gt;            xslProcessor.processXSL(xslt, xmlDoc, pw);&lt;br /&gt;            pw.flush();&lt;br /&gt;            pw.close();&lt;br /&gt;            sw.close();&lt;br /&gt;            result = sw.toString();&lt;br /&gt;        } catch (XSLException e) {&lt;br /&gt;&lt;br /&gt;            pl(e.toString());&lt;br /&gt;        } catch (IOException e) {&lt;br /&gt;            pl(e.toString());&lt;br /&gt;        }&lt;br /&gt;        return result;&lt;br /&gt;    }   &lt;br /&gt;    /**&lt;br /&gt;     * Clean up text from XML Leftovers&lt;br /&gt;     * @param text&lt;br /&gt;     * @return&lt;br /&gt;     */&lt;br /&gt;    public String cleanText(final String text){&lt;br /&gt;        String result = text;&lt;br /&gt;        result = result.replaceAll("&amp;amp;lt;","&amp;lt;");&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;    /**&lt;br /&gt;     * Transfomr the xmlDoc using xslDoc into String&lt;br /&gt;     * Cleanup XML code leftovers&lt;br /&gt;     * @param xslDoc&lt;br /&gt;     * @param xmlDoc&lt;br /&gt;     * @return String output&lt;br /&gt;     */&lt;br /&gt;    public String transform2Ascii(XMLDocument xslDoc, XMLDocument xmlDoc) {&lt;br /&gt;      String result = transform(xslDoc, xmlDoc);&lt;br /&gt;      result = cleanText(result);&lt;br /&gt;      return result;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;And the vendor indepent version of the same class:&lt;br /&gt;&lt;pre class="brush: java"&gt;package com.darwinit.xmlfiles.xml;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.PrintWriter;&lt;br /&gt;import java.io.StringWriter;&lt;br /&gt;import java.util.Hashtable;&lt;br /&gt;&lt;br /&gt;import javax.xml.transform.Transformer;&lt;br /&gt;import javax.xml.transform.TransformerException;&lt;br /&gt;import javax.xml.transform.TransformerFactory;&lt;br /&gt;import javax.xml.transform.dom.DOMSource;&lt;br /&gt;import javax.xml.transform.stream.StreamResult;&lt;br /&gt;&lt;br /&gt;import org.w3c.dom.Document;&lt;br /&gt;&lt;br /&gt;import com.darwinit.xmlfiles.log.LocalStaticLogger;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * XmlTransformer: Class implementing functionality to Transform XML using XSLT.&lt;br /&gt; * &lt;br /&gt; * See also http://www.ling.helsinki.fi/kit/2004k/ctl257/JavaXSLT/Ch05.html&lt;br /&gt; * &lt;br /&gt; * @author Martien van den Akker&lt;br /&gt; * @author Darwin IT Professionals&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;public abstract class XmlTransformer {&lt;br /&gt; public static final String className = "XmlTransformer";&lt;br /&gt; private static LocalStaticLogger lgr;&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Transform the xmlDoc using xslDoc into String&lt;br /&gt;  * &lt;br /&gt;  * @param xslDoc&lt;br /&gt;  * @param xmlDoc&lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; public static String transform(Document xslDoc, Document xmlDoc) {&lt;br /&gt;  return transform(xslDoc, xmlDoc, null);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Transform the xmlDoc using xslDoc into String, with parameters&lt;br /&gt;  * &lt;br /&gt;  * @param xslDoc&lt;br /&gt;  * @param xmlDoc&lt;br /&gt;  * @param parameters&lt;br /&gt;  *            contains parameter that are passed to the xslt&lt;br /&gt;  * @return String output&lt;br /&gt;  */&lt;br /&gt; @SuppressWarnings("static-access")&lt;br /&gt; public static String transform(Document xslDoc, Document xmlDoc,&lt;br /&gt;   Hashtable&amp;lt;String, String&amp;gt; parameters) {&lt;br /&gt;  final String methodName = "transform";&lt;br /&gt;  lgr.logStart(className, methodName);&lt;br /&gt;  String result = "";&lt;br /&gt;  try {&lt;br /&gt;   DOMSource xsltSource = new DOMSource(xslDoc);&lt;br /&gt;   DOMSource xmlSource = new DOMSource(xmlDoc);&lt;br /&gt;   StringWriter sw = new StringWriter();&lt;br /&gt;   PrintWriter pw = new PrintWriter(sw);&lt;br /&gt;   StreamResult streamResult = new StreamResult(pw);&lt;br /&gt;   // Get the transformer factory&lt;br /&gt;   TransformerFactory transFact = TransformerFactory.newInstance();&lt;br /&gt;   // Get a transformer for this particular stylesheet&lt;br /&gt;   Transformer trans = transFact.newTransformer(xsltSource);&lt;br /&gt;   // Add parameters&lt;br /&gt;   if (parameters != null) {&lt;br /&gt;    for (String key : parameters.keySet()) {&lt;br /&gt;     String value = parameters.get(key);&lt;br /&gt;     trans.setParameter(key, value);&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;   // Do the transformation&lt;br /&gt;   trans.transform(xmlSource, streamResult);&lt;br /&gt;   pw.flush();&lt;br /&gt;   pw.close();&lt;br /&gt;   sw.close();&lt;br /&gt;   // Get the result string&lt;br /&gt;   result = sw.toString();&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   lgr.error(className, methodName, e);&lt;br /&gt;  } catch (TransformerException e) {&lt;br /&gt;   lgr.error(className, methodName, e);&lt;br /&gt;  }&lt;br /&gt;  lgr.logEnd(className, methodName);&lt;br /&gt;  return result;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Clean up text from XML Leftovers&lt;br /&gt;  * &lt;br /&gt;  * @param text&lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; public static String cleanText(final String text) {&lt;br /&gt;  String result = text;&lt;br /&gt;  result = result.replaceAll("&amp;amp;lt;", "&amp;lt;");&lt;br /&gt;  return result;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Transform the xmlDoc using xslDoc into String Cleanup XML code leftovers&lt;br /&gt;  * &lt;br /&gt;  * @param xslDoc&lt;br /&gt;  * @param xmlDoc&lt;br /&gt;  * @return String output&lt;br /&gt;  */&lt;br /&gt; public static String transform2Ascii(Document xslDoc, Document xmlDoc) {&lt;br /&gt;  String result = transform(xslDoc, xmlDoc);&lt;br /&gt;  result = cleanText(result);&lt;br /&gt;  return result;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The code is not much different. Most important is that you have to wrap the input, xslt and result objects into particular interface objects. The examples I found worked with File(s) as Source and Result objects. But I wanted Document objects for the XLST and Input objects. And I want to have the result into a String, to be able to process it in anyway I want.&lt;br /&gt;&lt;br /&gt;I added also the possiblity to pass XSLT parameters. But I got it from a project I worked on and see that I haven't put that in the class in my XmlFiles project.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;I hope this helps in understanding how to work with XML parsers. Ofcourse all is rudimentary (I have several large books on the subject in the cupboard). But I have pretty much enough with the above. The code in my XmlFiles project is basically around this code. On top of these methods I have several other helper methods to do traverse nodes or to get it in a particular way. &lt;br /&gt;&lt;br /&gt;I thought it might be helpfull to put the Oracle Native methods side by side with the vendor-independent (JAXP) code. Doing so I would not state that one way is better than the other. The vendor-independent code have clearly the advantage that you can simply replace the parser, just by changing the class path. The code will work with the Oracle XML Parser just as good as with the Apache Xerces-J parser. &lt;br /&gt;The reason I did it the Oracle way before was just because I ran into these examples first, the time I started this. Probably there still are good reasons to use the native API's.&lt;br /&gt;&lt;br /&gt;Oracle also has a Pl/Sql Wrapper around the XML Parser. So the Oracle XML Parsing code has a Pl/Sql counter part. Might be nice to do this in a Pl/Sql way sometime. &lt;br /&gt;But as the code above isn't rocket science, it isn't new also. XML Parsing in Pl/Sql can be done from Oracle 8i onwards. Also roughly ten years already.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-157374502362478905?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/157374502362478905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=157374502362478905' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/157374502362478905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/157374502362478905'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/03/vendor-independent-xml-processing.html' title='Vendor independent XML processing'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-auqIhv0mKm4/TYhvqXHbTAI/AAAAAAAACT4/Xi1O8ZuNhig/s72-c/xmleditor.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-8225300736727941443</id><published>2011-03-17T02:49:00.000-07:00</published><updated>2011-03-17T03:23:31.363-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Query ClearQuest with Java.</title><content type='html'>At deployment of a new release of a project it might be required to deliver a list of solved issues in a release notes document. At least that was a requirement that my colleagues on my current project had.&lt;br /&gt;They copied and pasted the issues from the Rational ClearQuest tool, which they felt was error-prone and a tedious job. If I could create a tool for it?&lt;br /&gt;&lt;br /&gt;The first thing I did was to look into ClearQuest on how the import and export possibilities were. But although there is an export tool, it is not batch. It'll start a wizard that you have to go through. Within ClearQuest there are query possibilities. But then again: you're in the tool and we wanted to have it batch-wise, integrated with Ant.&lt;br /&gt;So it would be nice to be able to query ClearQuest in Java. And fortunately I found a cqjni.jar in the ClearQuest home. This jar is a Java Native Interface set of API's on CQ.&lt;br /&gt;&lt;br /&gt;There are, however, very few java examples. I did find an example on &lt;a href="http://www.ibm.com/developerworks/rational/library/4702.html"&gt;perl &lt;/a&gt;here. I could use this with some other examples to come up with my own code. So I'll lay out my steps here.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;0. Some helper methods&lt;/h4&gt;First I'll give you some helper methods that I use in the following examples. They're in fact shortcuts to "System.out.println".&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;  * Shortcut for output&lt;br /&gt;  * &lt;br /&gt;  * @param text&lt;br /&gt;  */&lt;br /&gt; public static void pl(String text) {&lt;br /&gt;  System.out.println(text);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static void pl(String text, Exception e) {&lt;br /&gt;  System.out.println(text);&lt;br /&gt;  e.printStackTrace();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Output a String array.&lt;br /&gt;  * &lt;br /&gt;  * @param label&lt;br /&gt;  * @param array&lt;br /&gt;  */&lt;br /&gt; public static void printStringArray(String label, String[] array) {&lt;br /&gt;  for (int idx = 0; idx &amp;lt; array.length; idx++) {&lt;br /&gt;   pl(label + " " + idx + ": " + array[idx]);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;1. Create session&lt;/h4&gt;The first&amp;nbsp; step to do is to create a CQSession: &lt;br /&gt;&lt;pre class="brush: java"&gt;pl("Begin");&lt;br /&gt;CQSession cqSession = new CQSession();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;2. List Installed Database Sets and Master Databases&lt;/h4&gt;To be able to query on CQ you'll have to find out what databases you can connect to. In CQ apparently databases are grouped in a DatabaseSet. And a DatabaseSet is correlated to a MasterDatabase. You can query them as follows.  &lt;br /&gt;&lt;pre class="brush: java"&gt;CQSession session = getCqSession();&lt;br /&gt;  String[] dbSets = session.GetInstalledDbSets();&lt;br /&gt;  String[] masters = session.GetInstalledMasterDbs();&lt;br /&gt;&lt;/pre&gt;As I understand it, a DabaseSet is put in a database. In my setup I've two masterdatabases and a DatabaseSet in each. I assumed that the entries in the String Arrays correspond to each other: dbSets[0] correlates to masters[0], etc.&lt;br /&gt;&lt;br /&gt;I combined the lot in a some combined methods. These are based on a helper Bean &lt;a href="http://www.darwin-it.nl/fileadmin/darwin/CodeVoorbeelden/Java/ClearQuest/DatabaseSet.java"&gt;&lt;i&gt;DatabaseSet&lt;/i&gt;&lt;/a&gt;.&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;  * Get Installed ClearQuest Database Sets&lt;br /&gt;  * &lt;br /&gt;  * @return&lt;br /&gt;  * @throws CQException&lt;br /&gt;  */&lt;br /&gt; public String[] getInstalledDbSetNames() throws CQException {&lt;br /&gt;  CQSession session = getCqSession();&lt;br /&gt;  String[] dbSets;&lt;br /&gt;  dbSets = session.GetInstalledDbSets();&lt;br /&gt;  return dbSets;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Get Installed ClearQuest Master Databases&lt;br /&gt;  * &lt;br /&gt;  * @return&lt;br /&gt;  * @throws CQException&lt;br /&gt;  */&lt;br /&gt; public String[] getInstalledMasterDbNames() throws CQException {&lt;br /&gt;  CQSession session = getCqSession();&lt;br /&gt;  String[] masters = session.GetInstalledMasterDbs();&lt;br /&gt;  return masters;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Get Installed ClearQuest Database Sets&lt;br /&gt;  * &lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; public Vector&amp;lt;DatabaseSet&amp;gt; getInstalledDatabaseSets() {&lt;br /&gt;  final String methodName = "getInstalledDatabaseSets";&lt;br /&gt;  Vector&amp;lt;DatabaseSet&amp;gt; dbSets = new Vector&amp;lt;DatabaseSet&amp;gt;();&lt;br /&gt;  try {&lt;br /&gt;   String[] dbSetNames = this.getInstalledDbSetNames();&lt;br /&gt;   String[] masters = this.getInstalledMasterDbNames();&lt;br /&gt;   for (int i = 0; i &amp;lt; dbSetNames.length; i++) {&lt;br /&gt;    DatabaseSet dbSet = new DatabaseSet(masters[i], dbSetNames[i]);&lt;br /&gt;    dbSets.add(dbSet);&lt;br /&gt;   }&lt;br /&gt;  } catch (CQException e) {&lt;br /&gt;   pl("Exception at " + methodName, e);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return dbSets;&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * List Installed ClearQuest Database Sets&lt;br /&gt;  * &lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; public void listInstalledDbSets() {&lt;br /&gt;  final String methodName = "listInstalledDbSets";&lt;br /&gt;  pl(methodName);&lt;br /&gt;  Vector&amp;lt;DatabaseSet&amp;gt; dbSets;&lt;br /&gt;  dbSets = getInstalledDatabaseSets();&lt;br /&gt;  ListIterator&amp;lt;DatabaseSet&amp;gt; it = dbSets.listIterator();&lt;br /&gt;  while (it.hasNext()) {&lt;br /&gt;   DatabaseSet dbSet = it.next();&lt;br /&gt;   pl(dbSet.toString());&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;3. Accessible Databases&lt;/h4&gt;To list the Accessible Databases I used the code that I found &lt;a href="http://www.ibm.com/developerworks/forums/thread.jspa?messageID=13901784"&gt;here&lt;/a&gt;. In my own code I moved some of the code to the methods above.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;  * List Accessible ClearQuest Databases&lt;br /&gt;  * &lt;br /&gt;  * @return&lt;br /&gt;  */&lt;br /&gt; public void listAccessibleDatases() {&lt;br /&gt;  final String methodName = "listInstalledDatabaseSets";&lt;br /&gt;  pl(methodName);&lt;br /&gt;  Vector&amp;lt;DatabaseSet&amp;gt; dbSets;&lt;br /&gt;  dbSets = getInstalledDatabaseSets();&lt;br /&gt;  ListIterator&amp;lt;DatabaseSet&amp;gt; it = dbSets.listIterator();&lt;br /&gt;  while (it.hasNext()) {&lt;br /&gt;   try {&lt;br /&gt;    DatabaseSet dbSet = it.next();&lt;br /&gt;    pl("Handling dbSet: " + dbSet.getName());&lt;br /&gt;    CQSession session = getCqSession();&lt;br /&gt;    CQDatabaseDescs dbDescriptors = session.GetAccessibleDatabases(&lt;br /&gt;      dbSet.getMasterDb(), "", dbSet.getName());&lt;br /&gt;    int n = (int) dbDescriptors.Count();&lt;br /&gt;    System.out.println(" Accessible database count: " + n);&lt;br /&gt;    for (int j = 0; j &amp;lt; n; j++) {&lt;br /&gt;     CQDatabaseDesc desc = dbDescriptors.Item(j);&lt;br /&gt;&lt;br /&gt;     pl(" Database " + j + ": " + desc.GetDatabaseName());&lt;br /&gt;    }&lt;br /&gt;   } catch (CQException e) {&lt;br /&gt;    pl("Exception at " + methodName, e);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;4. Connect to a database&lt;/h4&gt;If you know what database you want to connect to, you can logon:   &lt;br /&gt;&lt;pre class="brush: java"&gt;pl("Logon to ClearQuest");&lt;br /&gt;   cqSession.UserLogon("User", "Password", "CQ-database", "CQ-DatabaseSet");&lt;br /&gt;   setCqSession(cqSession)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;5. List Record Types&lt;/h4&gt;Record types are sort of the logical-entities in ClearQuest. You have to know the entity in which your issues are stored. To list the possible Record Types you'll have to connect to the database (see above). Then you can list the record types as follows:   &lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;  * List the possible RecordTypes&lt;br /&gt;  * &lt;br /&gt;  * @return&lt;br /&gt;  * @throws CQException&lt;br /&gt;  */&lt;br /&gt; public void listRecordTypes() {&lt;br /&gt;  final String methodName = "listRecordTypes";&lt;br /&gt;  pl(methodName);&lt;br /&gt;  try {&lt;br /&gt;   CQSession session = getCqSession();&lt;br /&gt;   String[] cqRecordTypes = session.GetEntityDefNames();&lt;br /&gt;   printStringArray("Record Type", cqRecordTypes);&lt;br /&gt;  } catch (CQException e) {&lt;br /&gt;   pl("Exception at " + methodName, e);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;The same way you can find so-called Family Types. I did not use them further.&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;  * List the possible Family Types&lt;br /&gt;  */&lt;br /&gt; public void listFamilyTypes() {&lt;br /&gt;  final String methodName = "listFamilyTypes";&lt;br /&gt;  pl(methodName);&lt;br /&gt;  try {&lt;br /&gt;   CQSession session = getCqSession();&lt;br /&gt;   String[] cqFamilyTypes = session.GetEntityDefFamilyNames();&lt;br /&gt;   printStringArray("Family Type", cqFamilyTypes);&lt;br /&gt;  } catch (CQException e) {&lt;br /&gt;   pl("Exception at " + methodName, e);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;6. Build a query&lt;/h4&gt;Now it's time to build the query. If you've build a query before in the CQ tool you'll probably be familiar with the concepts.  It starts with creating a query and add columns to it:   &lt;br /&gt;&lt;pre class="brush: java"&gt;CQQueryDef cqQueryDef = cqSession.BuildQuery("BPM");&lt;br /&gt;   cqQueryDef.BuildField("id");&lt;br /&gt;   cqQueryDef.BuildField("State");&lt;br /&gt;   cqQueryDef.BuildField("headline");&lt;br /&gt;   cqQueryDef.BuildField("Owner");&lt;br /&gt;   cqQueryDef.BuildField("Fix_By");&lt;br /&gt;&lt;/pre&gt;The parameter in the BuildQuery method is the RecordType that you can query with the code in previous paragraph. In this example the record type is "BPM". The field-names are those defined in the tool on the record type. So it might be handy to build your query first in the CQ-Tool, to know which attributes/columns are to your disposal.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;7. Create a filter&lt;/h4&gt;Of course you don't want the whole lot of issues. In a longer running project there can be thousands of them. So we'll need to add a filter. In the ClearQuest Tool you can have a hierarchy of so called filter nodes. A filter node has several expressions that are concatenated using And or Or operators. Such an expression in itself can be a other filter node or what I call a FilterField: a filter on a field.&lt;br /&gt;&lt;pre class="brush: java"&gt;pl("Query Issues");&lt;br /&gt;   CQQueryFilterNode cqQueryFilterNode = cqQueryDef&lt;br /&gt;     .BuildFilterOperator(BOOL_OP_AND);&lt;br /&gt;   String[] stateValues = { "Closed", "Resolved" };&lt;br /&gt;   cqQueryFilterNode.BuildFilter("State", COMP_OP_EQ, stateValues);&lt;br /&gt;   String[] branchValues = { "R1.%" };&lt;br /&gt;   cqQueryFilterNode.BuildFilter("Fix_by", COMP_OP_LIKE, branchValues);&lt;br /&gt;&lt;/pre&gt;Here you see that I use some constants. For the FilterOperators the possible values are:&lt;br /&gt;&lt;pre class="brush: java"&gt;// And operator&lt;br /&gt; public static final long BOOL_OP_AND = 1;&lt;br /&gt; // Or operator&lt;br /&gt; public static final long BOOL_OP_OR = 2;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For the Filter "Comparators" the following values are possible:&lt;br /&gt;&lt;pre class="brush: java"&gt;// Equality operator (=)&lt;br /&gt; public static final long COMP_OP_EQ = 1;&lt;br /&gt; // Inequality operator (&amp;lt;&amp;gt;)&lt;br /&gt; public static final long COMP_OP_NEQ = 2;&lt;br /&gt; // Less-than operator (&amp;lt;)&lt;br /&gt; public static final long COMP_OP_LT = 3;&lt;br /&gt; // Less-than or Equal operator (&amp;lt;=)&lt;br /&gt; public static final long COMP_OP_LTE = 4;&lt;br /&gt; // Greater-than operator (&amp;gt;)&lt;br /&gt; public static final long COMP_OP_GT = 5;&lt;br /&gt; // Greater-than or Equal operator (&amp;gt;=)&lt;br /&gt; public static final long COMP_OP_GTE = 6;&lt;br /&gt; // Like operator (value is a substring of the string in the given field)&lt;br /&gt; public static final long COMP_OP_LIKE = 7;&lt;br /&gt; // Not-like operator (value is not a substring of the string in the given&lt;br /&gt; // field)&lt;br /&gt; public static final long COMP_OP_NOT_LIKE = 8;&lt;br /&gt; // Between operator (value is between the specified delimiter values)&lt;br /&gt; public static final long COMP_OP_BETWEEN = 9;&lt;br /&gt; // Not-between operator (value is not between specified delimiter values)&lt;br /&gt; public static final long COMP_OP_NOT_BETWEEN = 10;&lt;br /&gt; // Is-NULL operator (field does not contain a value)&lt;br /&gt; public static final long COMP_OP_IS_NULL = 11;&lt;br /&gt; // Is-not-NULL operator (field contains a value)&lt;br /&gt; public static final long COMP_OP_IS_NOT_NULL = 12;&lt;br /&gt; // In operator (value is in the specified set)&lt;br /&gt; public static final long COMP_OP_IN = 13;&lt;br /&gt; // Not-in operator (value is not in the specified set)&lt;br /&gt; public static final long COMP_OP_NOT_IN = 14;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;8. Execute the query and process the rows&lt;/h4&gt;Having built the query, it can be executed. First you'll have to create a CQResultSet from the session based on the Query Definition. &lt;br /&gt;The query can then be executed and the result set can be processed using the MoveNext() method. The MoveNext() gives a status. As long as the status equals 1 there is a next record. With GetNumberOfColumns you can count the number of columns in the resultset. And with  GetColumnLabel and GetColumnValue you can get the Column name and value at a particular index. Of course you know what columns you asked for and in what order. But traversing over the available columns is handy, because adding a column to the query does not affect this part of the code. Also it enables you to search for the value of a particular column.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;CQResultSet cqResultSet = cqSession.BuildResultSet(cqQueryDef);&lt;br /&gt;   long count = cqResultSet.ExecuteAndCountRecords();&lt;br /&gt;   pl("count: " + count);&lt;br /&gt;   long status = cqResultSet.MoveNext();&lt;br /&gt;   while (status == 1) {&lt;br /&gt;    pl("Status: " + status);&lt;br /&gt;    for (int i = 1; i &amp;lt;= cqResultSet.GetNumberOfColumns(); i++) {&lt;br /&gt;     pl(cqResultSet.GetColumnLabel(i) + ": "&lt;br /&gt;       + cqResultSet.GetColumnValue(i));&lt;br /&gt;    }&lt;br /&gt;    status = cqResultSet.MoveNext();&lt;br /&gt;   }&lt;br /&gt;   pl("Status: " + status);&lt;br /&gt;   pl("Done");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;That's it. The example-snippets above come from a test class I put together and that can be&amp;nbsp; downloaded form &lt;a href="http://www.darwin-it.nl/fileadmin/darwin/CodeVoorbeelden/Java/ClearQuest/QueryClearQuest.java"&gt;here&lt;/a&gt;. It's a test class that I created from other examples and refactored somewhat. For this blog I anonymised it and rearranged some of the methods. In my application I refactored the class into seperate classes for the dbconnection, a query class and an export class. Of course that's what you do in a project, to make it neat. But in the basics it runs down to this particular example. So I kept it in my project to first pilot a new feature.&lt;br /&gt;&lt;br /&gt;Then I created some ant tasks and targets to do the export and run Word with a document and a macro to import the file. But that's another story...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-8225300736727941443?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/8225300736727941443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=8225300736727941443' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8225300736727941443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8225300736727941443'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/03/query-clearquest-with-java.html' title='Query ClearQuest with Java.'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-122296863383197981</id><published>2011-03-10T07:04:00.000-08:00</published><updated>2011-04-06T00:33:48.296-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Total Commander for Linux=&gt;Krusader</title><content type='html'>Oh, how I love Total Commander. I never found a file-manager that is so powerful. And how I missed that under Linux. I work a few years with Linux now, but on my Linux I still have TotalCommander. It can browse through archives, it can FTP and it has tabs to quickly switch locations. And I find copying/moving using to panes much more convenient than the Windows Explorer way. I kind of hate Windows Explorer. KDE-Dolfin is better, but to me still too much Windows Explorer.&lt;br /&gt;&lt;br /&gt;Today I looked at the Total Commander website, to see that there is a new version of it. I must admit that I have a new laptop with Windows 7/64bit. And one of the minor things that I miss in TC is that it's still 32 bit. It's not big of a problem, but in the context menu all the 64 bit tools (like svn) are under a sub-menu. That's a little inconvenient.&lt;br /&gt;&lt;br /&gt;In the FAQ I saw that a Linux version of TC is postponed indefinitely. But that there is one recommended tool: &lt;a href="http://www.krusader.org/"&gt;Krusader&lt;/a&gt;. That I missed that until now! I installed it right away and at first glance indeed it is the first tool that I find comparable to TC. Tools like midnight commander and under Windows FreeCommander or other lookalikes aren't for me.&lt;br /&gt;&lt;br /&gt;TC works under Wine, but not too optimal. Krusader however is native Linux. So I'm going to check that out. Just another reason to tempt me install OpenSuse over my Windows 7 system...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-122296863383197981?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/122296863383197981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=122296863383197981' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/122296863383197981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/122296863383197981'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/03/total-commander-for-linuxkrusader.html' title='Total Commander for Linux=&gt;Krusader'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-8556751898162012164</id><published>2011-03-03T08:06:00.000-08:00</published><updated>2011-03-16T07:39:37.272-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Weblogic'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='JDeveloper'/><title type='text'>Connection errors between JDeveloper 11g and OTN SoaBPM Appliance</title><content type='html'>I' m working with the "&lt;a href="http://www.oracle.com/technetwork/middleware/soasuite/learnmore/vmsoa-172279.html"&gt;Pre-built Virtual Machine for SOA Suite and BPM Suite 11g&lt;/a&gt;"  for a while now. &lt;br /&gt;I use it to prepare for SoaSuite and BPM Bootcamps and one thing I try to do is to use JDeveloper&amp;nbsp; 11g on my Host&amp;nbsp; (OpenSuse 11.2) and connect to the application server in my VirtualBox guest. In fact, that would (probably) be the architecture to use in a real developer environment.&lt;br /&gt;&lt;br /&gt;So I changed the network adapter of the VirtualBox VM (in Device Settings) from NAT to "host-only". Then I re-activated the network-adapter in the guest (Oracle Enterprise Linux), to have it query for new ip-settings.As root I queried for the ip-address using ' ifconfig':&lt;br /&gt;&lt;pre class="brush: plain"&gt;[root@soabpm-vm ~]# ifconfig&lt;br /&gt;eth0      Link encap:Ethernet  HWaddr 08:00:27:1C:4C:37&lt;br /&gt;          inet addr:&lt;span style="color: red;"&gt;192.168.56.101&lt;/span&gt;  Bcast:192.168.56.255  Mask:255.255.255.0&lt;br /&gt;          inet6 addr: fe80::a00:27ff:fe1c:4c37/64 Scope:Link&lt;br /&gt;          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1&lt;br /&gt;          RX packets:219 errors:0 dropped:0 overruns:0 frame:0&lt;br /&gt;          TX packets:192 errors:0 dropped:0 overruns:0 carrier:0&lt;br /&gt;          collisions:0 txqueuelen:1000&lt;br /&gt;          RX bytes:21908 (21.3 KiB)  TX bytes:26686 (26.0 KiB)&lt;br /&gt;          Interrupt:10 Base address:0xd020&lt;br /&gt;&lt;br /&gt;lo        Link encap:Local Loopback&lt;br /&gt;          inet addr:127.0.0.1  Mask:255.0.0.0&lt;br /&gt;          inet6 addr: ::1/128 Scope:Host&lt;br /&gt;          UP LOOPBACK RUNNING  MTU:16436  Metric:1&lt;br /&gt;          RX packets:2222 errors:0 dropped:0 overruns:0 frame:0&lt;br /&gt;          TX packets:2222 errors:0 dropped:0 overruns:0 carrier:0&lt;br /&gt;          collisions:0 txqueuelen:0&lt;br /&gt;          RX bytes:2942937 (2.8 MiB)  TX bytes:2942937 (2.8 MiB)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So the ip-address of my vm is '&lt;span style="color: red;"&gt;192.168.56.101&lt;/span&gt;'. &lt;br /&gt;&lt;br /&gt;Then I changed the /etc/hosts file of the VM as:&lt;br /&gt;&lt;pre class="brush: plain"&gt;127.0.0.1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; localhost&lt;br /&gt;192.168.56.101&amp;nbsp; soabpm-vm soapbm-vm.local bpm-vm.local bpm-vm&lt;br /&gt;::1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; localhost6.localdomain6 localhost6&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And I added the same address in the host file of my OpenSuse host:&lt;br /&gt;&lt;pre class="brush: plain"&gt;&amp;nbsp;192.168.56.101&amp;nbsp; soabpm-vm soabpm-vm.darwin-it.local&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In Jdeveloper 11g I created an application server connection, named "soabpm-vm', added the credentials (weblogic/welcome1), hostname: soabpm-vm, ports 7001/7002, domain name: domain1. And then we test:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-rKOU2Y6rMYk/TW-4q33i2sI/AAAAAAAACTw/PgSaEoU0H3M/s1600/AppServerConnectionTest.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="289" src="https://lh5.googleusercontent.com/-rKOU2Y6rMYk/TW-4q33i2sI/AAAAAAAACTw/PgSaEoU0H3M/s320/AppServerConnectionTest.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Fine. So in my BPM Bootcamp preperations I came to the point I have to map the abstract roles (swimlanes) to LDAP roles/users. Doing so you have to query the users over the application server connection. Choosing the connection it would populate the realm-poplist. In my case it would not.Testing in the JDeveloper within the VM would give me:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-RG86AemTqoo/TW-5v0JCYbI/AAAAAAAACT0/pl2z_9BzZLM/s1600/JdevIdentityLookup.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="309" src="https://lh5.googleusercontent.com/-RG86AemTqoo/TW-5v0JCYbI/AAAAAAAACT0/pl2z_9BzZLM/s320/JdevIdentityLookup.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Mark the Realm "jazn.com" automatically populated.&lt;br /&gt;&lt;br /&gt;So I tried to deploy a SoaProject, that builds fine, but deploying resulted in:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: red; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[03:10:41 PM] Error sending deployment request to server AdminServer [localhost:7001]&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: red; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;java.net.ConnectException: Connection refused &lt;/span&gt;&lt;br /&gt;&lt;span style="color: red; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[03:10:41 PM] Error sending deployment request to server AdminServer [localhost:7001]&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: red; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;java.net.ConnectException: Connection refused&amp;nbsp;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;After a while I noticed '&lt;span style="color: red; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;AdminServer [localhost:7001]&lt;/span&gt;'! That's not where I want to connect to! And it is certainly not the host I applied in the Jdev Applicatioin Server dialog.&lt;br /&gt;&lt;br /&gt;Apparently the AdminURL of Weblogic is not correctly set during startup. This is set in&amp;nbsp; the config.xml.&lt;br /&gt;This can easily be found as follows:&lt;br /&gt;&lt;pre class="brush: plain"&gt;[oracle@soabpm-vm config]$ cd&lt;br /&gt;[oracle@soabpm-vm ~]$ cd bin&lt;br /&gt;[oracle@soabpm-vm bin]$ . ./wls_env.sh&lt;br /&gt;[oracle@soabpm-vm bin]$ cd $DOMAIN_HOME/config&lt;br /&gt;[oracle@soabpm-vm config]$ ls config.xml&lt;br /&gt;config.xml&lt;br /&gt;&lt;/pre&gt;Edit the config.xml and look for:&lt;br /&gt;&lt;pre class="brush: plain"&gt;&amp;lt;external-dns-name&amp;gt;localhost&amp;lt;/external-dns-name&amp;gt;&lt;br /&gt;&lt;/pre&gt;Then change it in:&lt;br /&gt;&lt;pre class="brush: plain"&gt;&amp;lt;!--&amp;lt;external-dns-name&amp;gt;localhost&amp;lt;/external-dns-name&amp;gt;--&amp;gt;&lt;br /&gt;&amp;lt;external-dns-name&amp;gt;soabpm-vm&amp;lt;/external-dns-name&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As always it is good practice to backup the config.xml. And after the change of course you'll need to restart the weblogic server. &lt;br /&gt;But then the connection to the AdminServer will work, the realm can be queried and deploying will work.&lt;br /&gt;Important lesson: the hostname in the setting above should not be localhost, but a meaningful host name.that can be resolved on both the SoaSuite server as well as the Client running JDeveloper.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-8556751898162012164?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/8556751898162012164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=8556751898162012164' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8556751898162012164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8556751898162012164'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/03/jdeveloper-11g-and-otn-soabpm-appliance.html' title='Connection errors between JDeveloper 11g and OTN SoaBPM Appliance'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-rKOU2Y6rMYk/TW-4q33i2sI/AAAAAAAACTw/PgSaEoU0H3M/s72-c/AppServerConnectionTest.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-6618067234987143326</id><published>2011-03-03T01:03:00.000-08:00</published><updated>2011-04-06T00:34:21.360-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Lightning on Thunderbird 3.x X86_64</title><content type='html'>I used to use the Mozilla Calander plugin for Thunderbird: Lightning. Haven't used it for long, but today I found that it would be nice to have it back again. I found that it was on my thunderbird plugins but it was not compatible anymore with my version of Thunderbird.&lt;br /&gt;&lt;br /&gt;Since Lightning is architecture specific you need the 64 bit version of it. That is: if you use the 64-bit Linux Thunderbird. It is available but for some unknown reason Mozilla did not publish it. Via the &lt;a href="https://help.ubuntu.com/community/ThunderbirdLightning#Thunderbird31"&gt;Ubuntu site&lt;/a&gt; (thanks to the Ubuntu Community) I found the location of the 1.0b2 beta version (for Thunderbird 3.1.x) &lt;a href="http://releases.mozilla.org/pub/mozilla.org/calendar/lightning/releases/1.0b2/contrib/linux-x86_64"&gt;here&lt;/a&gt;. The 1.0b1 version (for Thunderbird 3.0.x) &lt;a href="http://releases.mozilla.org/pub/mozilla.org/calendar/lightning/releases/1.0b1/contrib/linux-x86_64/"&gt;here&lt;/a&gt;. Since it is version specific, with new versions you can try it with changing the version id in the url.&lt;br /&gt;&lt;br /&gt;Download it, together with the accompanying Google Calendar provider, and install it in Thunderbird.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-6618067234987143326?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/6618067234987143326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=6618067234987143326' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6618067234987143326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6618067234987143326'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/03/lightning-on-thunderbird-3x.html' title='Lightning on Thunderbird 3.x X86_64'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-2269352488712798753</id><published>2011-03-01T05:09:00.000-08:00</published><updated>2011-03-01T05:09:37.799-08:00</updated><title type='text'>VirtualBox on Windows XP-2</title><content type='html'>I thought it was quite simple to &lt;a href="http://darwin-it.blogspot.com/2011/03/virtualbox-on-windows-xp.html"&gt;increase the VM-memory beyond the 1500MB limit &lt;/a&gt;of the GUI.&lt;br /&gt;However, starting the SOABPM server in the OTN SOABPM appliance would certainly crash the VM. Very nice is the state VirtualBox will bring the VM in: the "Guru Mediation"-Mode.&lt;br /&gt;Well, I would not call myself a VirtualBox-guru, so I wouldn't mediate in why the VM didn't feel as comfortable as it should.&amp;nbsp; So turn-off the machine.&lt;br /&gt;&lt;br /&gt;It turns out that the the 1500MB limit is not as arbitrary as thought. In the Issue Ticket &lt;a href="http://www.virtualbox.org/ticket/6982"&gt;here&lt;/a&gt; I read that the VMM process places the complete VM's memory&amp;nbsp; in the process-memory space. In 32-bit Windows the maximum of the process-address space is 2GB.And 2GB for the kernel. Since there is addresspace needed for the VMM process, the video memory etc., the limit for the VM is set to 1500MB.&lt;br /&gt;I would think that the limit is some further on the "save side", possibly something like 1750MB would do either.&lt;br /&gt;&lt;br /&gt;Since I'm a pretty stubborn guy, I'll try 2000MB.&amp;nbsp; Also to see the "Guru Mediation" mode state again... Then I'll try some saver values.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-2269352488712798753?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/2269352488712798753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=2269352488712798753' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2269352488712798753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2269352488712798753'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/03/virtualbox-on-windows-xp-2.html' title='VirtualBox on Windows XP-2'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-4802324893809031608</id><published>2011-03-01T02:16:00.000-08:00</published><updated>2011-03-02T04:51:28.392-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Box'/><title type='text'>VirtualBox on Windows XP</title><content type='html'>Today I installed VirtualBox 3.2.12 on a Windows XP. No not 4.0, since that was the version I happened to have with me on my external HD.&lt;br /&gt;&lt;br /&gt;I imported the &lt;a href="http://www.oracle.com/technetwork/community/devjavascript:void%280%29eloper-vm/index.html"&gt;Technet SOABPM Appaliance&lt;/a&gt;, but I found that Virtual Box places the disks and machines in a hidden ".VirtualBox" folder within my "Documents and Settings" area. Since on this machine I have a roaming profile I don't want to have folders there with gig's on virtual disks. Logging on Windows with a roaming profile is already slow without this.&lt;br /&gt;&lt;br /&gt;So I moved the ".VirtualBox" folder to a "C:\Data\VirtualBox" folder. Then VirtualBox won't find your machine anymore. To solve that a few things are to be done.&lt;br /&gt;&lt;br /&gt;First change the defaults paths. In VB Go to &amp;lt;menu&amp;gt;/File/Preferences:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh4.googleusercontent.com/-aZfk4LoFq4I/TWzCcPe3rLI/AAAAAAAACTo/F-WVIP8QV_w/s1600/VirtualBoxPreferencesGeneral.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="307" src="https://lh4.googleusercontent.com/-aZfk4LoFq4I/TWzCcPe3rLI/AAAAAAAACTo/F-WVIP8QV_w/s320/VirtualBoxPreferencesGeneral.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;There you can change the paths to "C:\Data\VirtualMachines\VirtualBox\HardDisks" and "C:\Data\VirtualMachines\VirtualBox\Machines".&amp;nbsp; I differentiate my machines with a VirtualBox subfolder, since I also use VMWare Player.&lt;br /&gt;&lt;br /&gt;Then you can make a new VMware image based on the disks. To get the new machine have the same name as the old one I backed up the existing machine directory ("c:\Data\VirtualMachines\VirtualBox\Machines\vbox-oel5u4-soabpm-11gr1ps2-bp1-otn\").&lt;br /&gt;&lt;br /&gt;Then I create the machine with the "do not think for yourself, let's do that later"-default settings.&lt;br /&gt;After creating the machine with the two disks, I did a file compare with the old and new "vbox-oel5u4-soabpm-11gr1ps2-bp1-otn.xml" file in the machine folder.&lt;br /&gt;&lt;br /&gt;I copy and paste the diffent settings using the file compare tool of TotalCommander in Edit-mode:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Copy the &amp;lt;description&amp;gt; node&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;lt;memory pagefusion="false" ramsize="2500"/&amp;gt; &lt;br /&gt;Under windows XP (with 4GB, effective 3,5 GB memory) VirtualBox does not allow the setting higher then 1500MB. But editing it on file-level allows you to raise it beyond that limit. The appliance was made with 2048. This is pretty little for SoaSuite11g. But not to eat too much from Windows I gave it 2500. &lt;/li&gt;&lt;li&gt;Copy the &amp;lt;guestproperties&amp;gt; node&lt;/li&gt;&lt;li&gt;&lt;b&gt;Important&lt;/b&gt;: change the SATA-controller to:&amp;nbsp; &amp;lt;storagecontroller name="SCSI Controller" portcount="16" type="LsiLogic" usehostiocache="true"/&amp;gt;&lt;/li&gt;&lt;li&gt;I changed some other hardware settings from false to true based on the file compare. Eg. HardwareVirtEx.&lt;/li&gt;&lt;/ul&gt;Then it turns out that the changes did not reflect in VirtualBox. A refresh did not help. To force&amp;nbsp; VirtualBox to reread the settings, Killed the VirtualBox service with ProcessExplorer:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-8zFHDaHMZvM/TWzGzOAg61I/AAAAAAAACTs/4ALVPatQlMg/s1600/VirtualBoxService.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="44" src="https://lh5.googleusercontent.com/-8zFHDaHMZvM/TWzGzOAg61I/AAAAAAAACTs/4ALVPatQlMg/s640/VirtualBoxService.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;That did the trick. Also I have it now running with 2500MB!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-4802324893809031608?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/4802324893809031608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=4802324893809031608' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4802324893809031608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4802324893809031608'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/03/virtualbox-on-windows-xp.html' title='VirtualBox on Windows XP'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/-aZfk4LoFq4I/TWzCcPe3rLI/AAAAAAAACTo/F-WVIP8QV_w/s72-c/VirtualBoxPreferencesGeneral.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-6761649352644236805</id><published>2011-02-14T03:15:00.000-08:00</published><updated>2011-02-14T03:16:12.619-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle BPM Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><title type='text'>JDeveloper 11g SOA &amp; BPM Extensions</title><content type='html'>If you want to use JDeveloper 11g for Soa and/or BPM Development you need to download the SOA JDev Extension for the SOA Composite Designer and the BPM JDev extension for BPM Studio.&lt;br /&gt;&lt;br /&gt;In all the documentation you'll find, you see an explanation on how to download them using the Help/Update utilities of JDeveloper. This might be neat and user-friendly for updating one JDeveloper instance where you have a fast internet access. But it is not so handy if you have to provide these extensions to multiple JDeveloper instances for a course for example. Then it is handy when you're able to download them and provide them on a stick.&lt;br /&gt;&lt;br /&gt;I found these files on this &lt;a href="http://www.oracle.com/ocom/groups/public/@otn/documents/webcontent/156082.xml"&gt;JDeveloper extension page &lt;/a&gt;(just using Google). &lt;br /&gt;So I downloaded the latest versions on my harddisk at home, where I have a good internet access. I hope this page is on-line indefinately.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-6761649352644236805?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/6761649352644236805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=6761649352644236805' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6761649352644236805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6761649352644236805'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/02/jdeveloper-11g-soa-bpm-extensions.html' title='JDeveloper 11g SOA &amp; BPM Extensions'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-6207412860422514225</id><published>2011-02-01T01:31:00.000-08:00</published><updated>2011-04-05T23:51:26.529-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Sqldeveloper'/><title type='text'>Sql Developer Datamodeller 3.0 available</title><content type='html'>Just read on &lt;a href="http://sueharper.blogspot.com/2011/01/sql-developer-data-modeler-30-is.html"&gt;Sue Harpers blog&lt;/a&gt; that SQL Developer Datamodeller 3.0 went production. It's downloadable from its &lt;a href="http://www.oracle.com/technetwork/developer-tools/datamodeler/overview/index.html"&gt;OTN-page&lt;/a&gt;. I'm happy to know it's a free download. End 2008 I used the beta version to model a datamodel for a project I did then. I found it a very nice tool, a good replacement for the ERD/Datamodelling capabilities of Designer. There were a few "misses, and the main ones I had were:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Generation of pl/sql packages and functions was not possible&lt;/li&gt;&lt;li&gt;Subversion support was poor: when you save a project it recreates directories to save the xml-artifacts in. Recreating directory means removal of the .svn folders, which breaks your svn working copy.&lt;/li&gt;&lt;/ul&gt;In the &lt;a href="http://www.oracle.com/technetwork/developer-tools/datamodeler/newfeatures30-224506.html"&gt;new features list&lt;/a&gt; I saw promissing statements that these should be solved now. You should be able to generate packages and functions and there is even Subversion Integration (not only support): you can see pending changes, compare models and it shoud "recognize versioned designs". Well, isn't that great?&lt;br /&gt;&lt;br /&gt;Since it's free and since it's a really good modelling tool, I think it is a must-use on every project that uses a datamodel. Haven't used it yet? Re-engineer your ERD by importing your datamodel from the database. It gives a quick insight in the datamodel for newcomers in your project.&lt;br /&gt;&lt;br /&gt;See also for an early adopter of Sql Developer 3.0 &lt;a href="http://www.oracle.com/technetwork/developer-tools/sql-developer/overview/index.html"&gt;the SqlDeveloper OTN-page&lt;/a&gt;. It includes the Datamodeller.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-6207412860422514225?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/6207412860422514225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=6207412860422514225' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6207412860422514225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6207412860422514225'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/02/sql-developer-datamodeller-30-available.html' title='Sql Developer Datamodeller 3.0 available'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-6494857002325410015</id><published>2011-01-24T03:40:00.000-08:00</published><updated>2011-03-16T07:41:31.825-07:00</updated><title type='text'>Change http port  in Oracle XE</title><content type='html'>For my current project I had to install tomcat as a j2ee server in Eclipse. It would not start since the Oracle XE database has port 8080 in use.&lt;br /&gt;&lt;br /&gt;I found the method to change the ports in XE &lt;a href="http://www.sachinmore.com/2006/11/change-default-port-8080-in-oracle-xe.html"&gt;here&lt;/a&gt;. From that example I created my own little script:&lt;br /&gt;&lt;pre class="brush: plain"&gt;set serveroutput on&lt;br /&gt;&lt;br /&gt;select dbms_xdb.gethttpport as "HTTP-Port"&lt;br /&gt;,      dbms_xdb.getftpport as "FTP-Port" &lt;br /&gt;from dual;&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;  new_port varchar2(4):='8085';&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt; dbms_output.put_line('Change HTTP Port to '||new_port);&lt;br /&gt; dbms_xdb.sethttpport(new_port);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;select dbms_xdb.gethttpport as "HTTP-Port"&lt;br /&gt;,      dbms_xdb.getftpport as "FTP-Port" &lt;br /&gt;from dual;&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In good old Dutch: "Mucho Plezieros" with it...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-6494857002325410015?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/6494857002325410015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=6494857002325410015' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6494857002325410015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6494857002325410015'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2011/01/change-http-port-in-oracle-xe.html' title='Change http port  in Oracle XE'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-4610129415876958904</id><published>2010-12-09T05:09:00.000-08:00</published><updated>2011-04-06T00:45:22.695-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle E-Business Suite'/><title type='text'>What to do to expose EBS services as a Webservice</title><content type='html'>I got a comment (in Dutch) on my &lt;a href="http://darwin-it.blogspot.com/2009/02/one-on-e-business-suite-adapter.html"&gt;article about the EBS Adapter&lt;/a&gt;. &lt;br /&gt;Since giving short answers on simple questions is not my strengths, I'll answer with a blogpost.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the article you can make up that I'm not too enthusiastic about the EBS Adapter. The reality is often more nuanced than stated, you should consider the EBS adapter specific for your own situation.&lt;br /&gt;&lt;br /&gt;Two of the main reasons to use the EBS Adapter are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It sets the application context for you at connecting to the EBS instance&lt;/li&gt;&lt;li&gt;The Adapter Wizard enables you to introspect the available interfaces.&lt;/li&gt;&lt;/ul&gt;If these reasons are not applicable for you since for instance you set the Application Context yourself for whatever reason and/or you use customer pl/sql procedures, then might be too little to ratify the use.&lt;br /&gt;&lt;br /&gt;But what would I do if I need to expose a pl/sql as a webservice from EBS?&lt;br /&gt;&lt;br /&gt;EBS 11.5.10 indeed just works with JServe. From 12 onwards OC4J is used,  at least initially in the 10.1.2 version (don't know if later relases  are on 10.1.3).&lt;br /&gt;So to start with, I'd use at least a managed OC4J 10.1.3.x Application server.  Either single node or clustered. So not a standalone oc4j. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;Then it depends mainly if you can use SoaSuite. If you can use SoaSuite I would create a BPEL Process, an Oracle ESB or (in case of SoaSuite11g) OSB service, based on the SoaSuite database adapter. Then arrange for setting the application context in the implementation block of the package where you have put the pl/sql procedure in.&lt;br /&gt;&lt;br /&gt;If you can't use SoaSuite you could generate a webservice from JDeveloper based on the pl/sql procedure. And deploy that as a WAR or EAR file to the application server. The main disadvantage of having JDeveloper generate the webservice is that you can't influence the way the generated code calls the pl/sql procedure. So I think I would create a standalone java application that uses JNDI for getting the jdbc-connection. Then code the call of the pl/sql procedure in the java-application. Test it stand-alone. If that works then create webservice on that application. Doing so you have separated the technical code that does the job (calling the pl/sql procedure) and the actual webservice. For an example on how to use JNDI in standalone applications that also have to run on an AS see &lt;a href="http://darwin-it.blogspot.com/2009/10/jndi-in-your-applications.html"&gt;this article&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For creating the webservice it self you also have two choices:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Let JDeveloper generated the code for you. But then JDeveloper generates the wsdl and you have very little (near to nothing) influence on how it looks like. Unless you generate the webservice based on the wsdl.&lt;/li&gt;&lt;li&gt;Use a soap stack that supports annotations (like Sun Glassfish Metro). Using annotations you have very large influence on how the generated wsdl looks like. See for instance &lt;a href="http://darwin-it.blogspot.com/2009/06/hello-metro.html"&gt;this article&lt;/a&gt;. Only in that case the wsdl will be generated at startup of the webservice application in the application server.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So my preferred way to go is either use SoaSuite/OSB or create a annotation based webservice on a standalone java-app that calls my procedure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-4610129415876958904?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/4610129415876958904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=4610129415876958904' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4610129415876958904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4610129415876958904'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/12/what-to-do-to-expose-ebs-services-as.html' title='What to do to expose EBS services as a Webservice'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-3047822363980914819</id><published>2010-12-07T07:06:00.000-08:00</published><updated>2011-04-06T00:14:28.976-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='BPEL PM'/><title type='text'>Reinvoke BPEL Process</title><content type='html'>Back in 2008 I wrote an &lt;a href="http://darwin-it.blogspot.com/2008/01/how-to-create-bpel-job-scheduler.html"&gt;article &lt;/a&gt;on creating a BPEL Scheduler. The principle of that article I used later in a real implementation of a scheduler. In several blog-posts, amongst others of &lt;a href="http://clemensblog.blogspot.com/2006/04/bpel-scheduling-reoccuring-processes.html"&gt;Clemens Utschig &lt;/a&gt;and &lt;a href="http://technology.amis.nl/blog/1372/starting-a-bpel-process-instance-according-to-a-timed-schedule-in-oracle-bpel-pm"&gt;Lucas Jellema&lt;/a&gt;, I read all kinds of arguments why you should or shouldn't use BPEL for scheduling.&lt;br /&gt;&lt;br /&gt;I think however that BPEL is perfectly suitable to be used as to schedule jobs. Especially if you create a datamodel with an Apex front-end for instance (used JHeadstart myself for it) to register the schedule meta data to determine the next schedule dates.&lt;br /&gt;&lt;br /&gt;There are a few considerations though. One of them is reinvoking the scheduler for a new scheduled-date, after performing a task. In my earlier article I used a plain invoke on the client-partnerlink. A big disadvantage of that is dat every task instance is created under the same root instance. After&amp;nbsp; a few iterations the process tree under the tree finder is exorbitant big. &lt;br /&gt;&lt;br /&gt;This is solved quite easily by replacing the invoke by a piece of embedded java:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;bpelx:exec name="ReInvokeRH" language="Java" version="1.4"&amp;gt;&amp;lt;![CDATA[//Get logger&lt;br /&gt;                org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("my.log");&lt;br /&gt;                // Get singletonId&lt;br /&gt;                log.info("ReInvoke-Get SingletonId.");&lt;br /&gt;                String singletonId = (String)getVariableData("singletonId");;&lt;br /&gt;                //Construct xml message&lt;br /&gt;                log.info("ReInvoke - Construct XML message.");&lt;br /&gt;                String xml = "&amp;lt;BPELProcessProcessRequest xmlns=\"http://xmlns.oracle.com/BPELProcessProcessRequest \"&amp;gt;\n&amp;lt;singletonId&amp;gt;"&lt;br /&gt;                           + singletonId &lt;br /&gt;                           + "&amp;lt;/singletonId&amp;gt;\n&amp;lt;/BPELProcessProcessRequest &amp;gt;";&lt;br /&gt;                log.info("ReInvoke message: " + xml);&lt;br /&gt;                //Get a locator and delivery service.&lt;br /&gt;                log.info("ReInvoke - Get Locator.");&lt;br /&gt;                try {&lt;br /&gt;                  Locator locator = getLocator();&lt;br /&gt;                  log.info("ReInvoke - Initiate IDeliveryService.");&lt;br /&gt;                  IDeliveryService deliveryService = (IDeliveryService)locator.lookupService(IDeliveryService.SERVICE_NAME);&lt;br /&gt;                  // Construct a normalized message and send to Oracle BPEL Process Manager&lt;br /&gt;                  log.info("ReInvoke - Construct a normalized message and send to Oracle BPEL Process Manager.");&lt;br /&gt;                  NormalizedMessage nm = new NormalizedMessage();&lt;br /&gt;                  nm.addPart("payload", xml);&lt;br /&gt;                  // Initiate the BPEL process&lt;br /&gt;                  log.info("ReInvoke - Initiate the BPEL process.");&lt;br /&gt;                  deliveryService.post("BPELProcess", "initiate", nm);&lt;br /&gt;                } catch (RemoteException e) {&lt;br /&gt;                  log.error(e);&lt;br /&gt;                  setVariableData("invokeError", "true");&lt;br /&gt;                  setVariableData("invokeErrorMessage", "ReInvokeRH-RemoteException: "+e.toString());  &lt;br /&gt;                } catch (ServerException e) {&lt;br /&gt;                  log.error(e);&lt;br /&gt;                  setVariableData("invokeError", "true");&lt;br /&gt;                  setVariableData("invokeErrorMessage", "ReInvokeRH-ServerException: "+e.toString());&lt;br /&gt;                }&lt;br /&gt;                log.info("ReInvoke - Return.");]]&amp;gt;&lt;br /&gt;              &amp;lt;/bpelx:exec&amp;gt;&lt;br /&gt;&lt;/pre&gt;This will build a String message, create NormalizedMesage  of it, and post it to the "Initiate" operation of the "BPELProcess" using the post method of the DeliveryService that is fetched using the locator of the bpel instance.&lt;br /&gt;&lt;br /&gt;Doing so the parent-child relation is broken, the new instance runs in a new process-instance-tree.&lt;br /&gt;&lt;br /&gt;Another consideration is that you might want to "listen" to external messages to do an abort or a reschedule. This can be done in several ways. For example by doing a correlated receive (using a correlation set on a field in the request message like the "singletonId" in the reinvoke example) in a parallel flow. &lt;br /&gt;&lt;br /&gt;Problem is that at a normal reinvoke this receive has to be released. If not, the parellel flow will not end and/or the correlation set will not be freed. In the new instance you might get a runtime message that there is already a receive on the same correlation-id. In another project I solved a similar problem by calling the process instance with an abort message from within the process instance, before doing a re-invoke. This is quite costly in terms of performance since it involves a message to the bpel-service with all the overhead (even if it's in fact a WSIF call). So recently I found myself a little smarter solution.&lt;br /&gt;&lt;br /&gt;What I basically did was to wrap the parallel flow with the receive and task-execution logic with a scope.&lt;br /&gt;Instead of normally ending the branches, I throw a "finish" or "abort" exception:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;throw name="Throw_Finish" faultName="client:Finish" faultVariable="ReceiveInput_initiate_InputVariable"/&amp;gt;&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;Then this can be catched in the surrounding scope:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;catch faultName="client:Finish" faultVariable="ReceiveInput_initiate_InputVariable"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This might look strange at first sight, to end your normal (or abort) flow using a business-exception. Ending your flow is not an exception, is it?&lt;br /&gt;But it will release your receive-activities and the correlation id they hold for a reinvoke on the same correlation-id.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-3047822363980914819?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/3047822363980914819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=3047822363980914819' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3047822363980914819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3047822363980914819'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/12/reinvoke-bpel-process.html' title='Reinvoke BPEL Process'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-633690926551960807</id><published>2010-11-02T01:27:00.000-07:00</published><updated>2011-04-06T00:30:13.114-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='B2B'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><title type='text'>B2B Queue to JMS</title><content type='html'>Lately I was asked to help with routing messages from a object-type based AQ-queue to JMS.&lt;br /&gt;The thing is that JMS works with text. So you have to transform the objecttype to text.&lt;br /&gt;When the Object type is one of your own, you could extend it with a method "toXML" to give a XML message based on the attributes of the object.&lt;br /&gt;&lt;br /&gt;In this case it was about a Oracle Integratin B2B AQ Queue, which is based on the B2B object "IP_MESSAGE_TYPE".&lt;br /&gt;&lt;br /&gt;It turns out not too hard to translate the object type to JMS. I created a package for it which I provided for download &lt;a href="http://www.darwin-it.nl/fileadmin/darwin/CodeVoorbeelden/PLSQL/def_b2b.pck"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can test it with the following code:&lt;br /&gt;&lt;pre class="brush: plain"&gt;declare&lt;br /&gt;  -- Non-scalar parameters require additional processing&lt;br /&gt;  result     sys.aq$_jms_text_message;&lt;br /&gt;  ip_message ip_message_type;&lt;br /&gt;  payload    clob;&lt;br /&gt;begin&lt;br /&gt;  payload         := def_b2b.varchar_to_clob('Jet, Teun, Vuur, Schapen');&lt;br /&gt;  ip_message := ip_message_type(MSG_ID           =&gt; 'Aap'&lt;br /&gt;                                    ,INREPLYTO_MSG_ID =&gt; 'noot'&lt;br /&gt;                                    ,FROM_PARTY       =&gt; 'Mies'&lt;br /&gt;                                    ,TO_PARTY         =&gt; 'Zus'&lt;br /&gt;                                    ,ACTION_NAME      =&gt; 'Lezen'&lt;br /&gt;                                    ,DOCTYPE_NAME     =&gt; 'Leesplankje'&lt;br /&gt;                                    ,DOCTYPE_REVISION =&gt; '1.0'&lt;br /&gt;                                    ,MSG_TYPE         =&gt; 1&lt;br /&gt;                                    ,PAYLOAD          =&gt; payload&lt;br /&gt;                                    ,ATTACHMENT       =&gt; null);&lt;br /&gt;  -- Call the function&lt;br /&gt;  result := def_b2b.ip_message2jms_msg(ip_message =&gt; ip_message);&lt;br /&gt;   result.get_text( :msg);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see a jms-accesible AQ-queue has a special system-Object-type: 'sys.aq$_jms_text_message'. There are several others, for different kinds of jms queues or topics. Also markt that the object types differ between Oracle 10g or 11g Enterprise  Edition or equivalent and Oracle XE. In XE you wouldn't find a 'construct' method. You could try the &lt;a href="http://technology.amis.nl/blog/2384/enqueuing-aq-jms-text-message-from-plsql-on-oracle-xe"&gt;solution of Peter Ebell for this&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Another thing is that the guys that asked me for help, had to do the enqueue of the message on the JMS-queue based on the enqueue on the source B2B-queue.&lt;br /&gt;From Oracle they got permission to use a trigger on the Queue-table. To begin with they used a Before Row Insert trigger. Besides triggers on queue-tables are not support and certainly not the way to go, they encountered a problem with it. And that lays in the fact that the payload attribute is a CLOB. I allways found the way Oracle handled CLOBs at least  "a little remarkable". On insert you create a row with an empty CLOB and then query it for update. In the queried row you upload the content to the CLOB-column. Since an AQ queue is based on a table it works essentially the same way. So on Before Row Insert the payload attribute is still empty. They solved it to use an After Delete trigger (when the message is consumed by the subscribing-process).&lt;br /&gt;&lt;br /&gt;The way to go is actually to register a notification service on the queue using code like: &lt;br /&gt;&lt;pre class="brush: plain"&gt;declare&lt;br /&gt;  lc_reg_info      SYS.AQ$_REG_INFO;&lt;br /&gt;  lc_reg_info_list SYS.AQ$_REG_INFO_LIST;&lt;br /&gt;begin&lt;br /&gt;  lc_reg_info := SYS.AQ$_REG_INFO('B2B.IP_IN_QUEUE:&lt;consumer&gt;'&lt;br /&gt;                                 ,DBMS_AQ.NAMESPACE_AQ&lt;br /&gt;                                 ,'plsql://b2b.def_b2b.handle_inbound_notification?PR=1'&lt;br /&gt;                                 ,HEXTORAW('FF'));&lt;br /&gt;&lt;br /&gt;  lc_reg_info_list := SYS.AQ$_REG_INFO_LIST(lc_reg_info);&lt;br /&gt;  dbms_aq.register(lc_reg_info_list, 1);&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Such a plsql notification function is a function that is required to have a particular "authograph":&lt;br /&gt;&lt;pre class="brush: plain"&gt;PROCEDURE handle_inbound_notification(context  RAW&lt;br /&gt;                                       ,reginfo  sys.aq$_reg_info&lt;br /&gt;                                       ,descr    sys.aq$_descriptor&lt;br /&gt;                                       ,payload  RAW&lt;br /&gt;                                       ,payloadl NUMBER)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;These parameters provide you with the data to fetch/dequeue the message this procedure is called for. You won't get the message itself, you have to dequeue-it explicitly. See the package for an example to implement this procedure.&lt;br /&gt;&lt;br /&gt;You should perform the register for every queue-consumer that you want to reroute the messages for. But it is not too hard to put this in a parameterized-procedure and call it based on a query that fetches the consumer from either the dictionary or (better) the B2B repository. In fact this code is extracted from such a construct. But it was a little too much (I already put a reasonable amount of time in the package) to anonymize it and make it more generic.&lt;br /&gt;If you need more help with it, I could of course provide some consultancy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-633690926551960807?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/633690926551960807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=633690926551960807' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/633690926551960807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/633690926551960807'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/11/b2b-queue-to-jms.html' title='B2B Queue to JMS'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-9160605682901652120</id><published>2010-10-11T06:01:00.000-07:00</published><updated>2011-04-05T23:51:48.923-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Sqldeveloper'/><title type='text'>SQL Datamodeler EA 3.0</title><content type='html'>Hello&lt;br /&gt;The EA version of sql data modeler is available.&lt;br /&gt;See http://forums.oracle.com/forums/ann.jspa?annID=1446&lt;br /&gt;&lt;br /&gt;Features:&lt;br /&gt;http://www.oracle.com/technetwork/developer-tools/datamodeler/ea1-newfeatures-176686.html&lt;br /&gt;&lt;br /&gt;Finally it should be possible to generate packages.....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-9160605682901652120?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/9160605682901652120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=9160605682901652120' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/9160605682901652120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/9160605682901652120'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/10/sql-datamodeler-ea-30.html' title='SQL Datamodeler EA 3.0'/><author><name>Erik Trip - Darwin IT Professionals</name><uri>http://www.blogger.com/profile/17829205033288938089</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-8116090279973173342</id><published>2010-09-27T02:41:00.000-07:00</published><updated>2011-04-06T00:39:34.313-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='BPEL PM'/><title type='text'>Templates in BPEL Transforms</title><content type='html'>Multiple times I encountered that the Transformation tool of de BPEL designer has difficulties to cope with xpath and xslt functions in the stylesheet that it does not 'know'.&lt;br /&gt;We have for example some custom xslt functions and I use some xpath 2.0 functions. And if I use them and deploy the process, they'll work. But for the mapper -tool the transform is invalid and it will not show the transformation map.&lt;br /&gt;&lt;br /&gt;This is especially true for BPEL 10.1.2 that is still used at my current customer (there is a upgrade to 11g project on going).&lt;br /&gt;&lt;br /&gt;Very anoying, because we have some large xsl's that use a large number of custom xslt-functions to do a cached dvm lookup.&lt;br /&gt;&lt;br /&gt;But today I found a very nice workaround. If you hide those functions in a custom user template then the transformation map does not have difficulties with it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I now have the following user-defined template (put at the bottom of the xsl stylesheet):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;xsl:template name=&amp;quot;TransformLandCode&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name=&amp;quot;landCode&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;xsl:comment&amp;gt;Transform Landcode gebruikmakend van cache:lookup&lt;br /&gt;&amp;lt;/xsl:comment&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name=&amp;quot;result&amp;quot; select=&amp;quot;cache:lookup($landCode,&amp;amp;quot;LandCodeDomain_&amp;lt;FromSystem&amp;gt;To&amp;lt;ToSystem&amp;gt;&amp;amp;quot;)&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select=&amp;quot;$result&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:template&amp;gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So where I had something like:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;xsl:value-of select=&amp;quot;cache:lookup(/ns1:rootElement/ns1:subElement/ns1:LandCode,&amp;amp;quot;LandCodeDomain_&amp;amp;lt;FromSystem&amp;amp;gt;To&amp;amp;lt;ToSystem&amp;amp;gt;&amp;amp;quot;)&amp;quot;/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I now call the template:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;xsl:call-template name=&amp;quot;TransformLandCode&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name=&amp;quot;landCode&amp;quot; select=&amp;quot;/ns1:rootElement/ns1:subElement/ns1:LandCode&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Nice is by the way that the mapper also allows for adding the call statement in to the map using drag and drop. Also the parameters can be filled using dragging the lines:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_myrkQ5dyTYg/TKBsLf0Q_dI/AAAAAAAACRo/LDR2nmwi5Uo/s1600/bpel1012-TransformationMapper.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 118px;" src="http://4.bp.blogspot.com/_myrkQ5dyTYg/TKBsLf0Q_dI/AAAAAAAACRo/LDR2nmwi5Uo/s320/bpel1012-TransformationMapper.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5521532087931305426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And of course you can add code-snippets for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-8116090279973173342?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/8116090279973173342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=8116090279973173342' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8116090279973173342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8116090279973173342'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/09/templates-in-bpel-transforms.html' title='Templates in BPEL Transforms'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_myrkQ5dyTYg/TKBsLf0Q_dI/AAAAAAAACRo/LDR2nmwi5Uo/s72-c/bpel1012-TransformationMapper.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-1746036542567856634</id><published>2010-09-22T03:00:00.000-07:00</published><updated>2011-04-05T23:52:08.646-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Headache from postfix</title><content type='html'>Earlier I wrote a &lt;a href="http://darwin-it.blogspot.com/2010/03/postfix-for-handling-mail-in-your.html"&gt;post&lt;/a&gt; on how postfix could be used in a mail integration solution. This was a result on a project that I'm doing using postfix to catch mail and transfer it via a bash-shell script, through mq to BPEL PM using the mq-adapter.&lt;br /&gt;&lt;br /&gt;I added a logging construction in the script that give me a nice mechanism to do some logging:&lt;br /&gt;&lt;pre class="brush: bash"&gt;...&lt;br /&gt;TRUE=1&lt;br /&gt;FALSE=0&lt;br /&gt;...&lt;br /&gt;#Logging variables&lt;br /&gt;LOG_ENABLED=$TRUE&lt;br /&gt;#LOG_ENABLED=$FALSE&lt;br /&gt;LOG_DIR=/tmp/log&lt;br /&gt;LOG_FILENAME=$LOG_DIR/routescript.log&lt;br /&gt;#Check log dir and create it if it does not exist.&lt;br /&gt;check_logdir(){&lt;br /&gt;if [ "$LOG_ENABLED" -eq $TRUE ]; then&lt;br /&gt;  if [ -d $LOG_DIR ]; then&lt;br /&gt;    #log a seperation line&lt;br /&gt;    log&lt;br /&gt;  else&lt;br /&gt;    mkdir $LOG_DIR&lt;br /&gt;  fi&lt;br /&gt;fi&lt;br /&gt;}&lt;br /&gt;#Function to display usage&lt;br /&gt;usage(){&lt;br /&gt;  SCRIPT_PARAMETERS=" -q queuename -s sender -r receiver";&lt;br /&gt;  USAGE="Usage: `basename $0` $SCRIPT_PARAMETERS";&lt;br /&gt;  echo $USAGE;&lt;br /&gt;}&lt;br /&gt;#Log&lt;br /&gt;log(){&lt;br /&gt;  if [ "$LOG_ENABLED" -eq $TRUE ]; then&lt;br /&gt;    TEXT="$1 ""$2"&lt;br /&gt;    echo $TEXT &gt;&gt;$LOG_FILENAME;&lt;br /&gt;  fi&lt;br /&gt;}&lt;br /&gt;# First check logdir&lt;br /&gt;check_logdir&lt;br /&gt;&lt;br /&gt;#&lt;span style="font-style: italic;"&gt;Do the rest of the script logic&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It works nicely, but the solution described in the earlier post works only for mails with one receipient. This was caused by the flag 'D' in the transport-line of the master.cf:&lt;br /&gt;The 'D' flag prepends a message with a property line with the receipient.&lt;br /&gt;&lt;pre class="brush: plain"&gt;# 2010-02-10, M. van den Akker: Setup transport routescript for passing message to a bash-script&lt;br /&gt;routescript   unix  -       n       n       -       -       pipe&lt;br /&gt;flags=F&lt;span style="font-weight: bold;"&gt;D&lt;/span&gt;q. user=smtpuser argv=/bin/bash -c /home/smtpuser/routescript.sh -s $sender -r $recipient -q $nexthop&lt;br /&gt;&lt;/pre&gt;Besides removing this flag, also the argument parsing of the script should be adapted, to support for multiple receipients:&lt;br /&gt;&lt;pre class="brush: bash"&gt;ARG_NR=0;&lt;br /&gt;until [ -z "$1" ]&lt;br /&gt;do&lt;br /&gt;  ARG_NR=$(($ARG_NR+1));&lt;br /&gt;  log "Argument $ARG_NR: " $1&lt;br /&gt;  case $1 in&lt;br /&gt;    "-s") PARAM=$1;;&lt;br /&gt;    "-r") PARAM=$1;;&lt;br /&gt;    "-q") PARAM=$1;;&lt;br /&gt;    * )  case $PARAM in&lt;br /&gt;            "-s") SENDER=$1;&lt;br /&gt;                  log "Sender: " $SENDER;;&lt;br /&gt;            "-r") RECEIVER=$1;&lt;br /&gt;                  log "Receiver: " $RECEIVER;&lt;br /&gt;                  if  [ -z "$RECEIVER_LIST" ]&lt;br /&gt;                  then&lt;br /&gt;                    RECEIVER_LIST=$RECEIVER;&lt;br /&gt;                  else&lt;br /&gt;                    RECEIVER_LIST="$RECEIVER_LIST,$RECEIVER";&lt;br /&gt;                  fi&lt;br /&gt;                  log "Receiverlist: " $RECEIVER_LIST;;&lt;br /&gt;            "-q") FQN_QUEUE_NAME=$1;&lt;br /&gt;                  log "Queue: " $FQN_QUEUE_NAME;;&lt;br /&gt;            * ) usage;&lt;br /&gt;            exit $E_WRONG_ARGS;;&lt;br /&gt;         esac;;&lt;br /&gt;  esac;&lt;br /&gt;shift 1;&lt;br /&gt;done;&lt;br /&gt;#Log Parameters.&lt;br /&gt;log "SENDER: " $SENDER&lt;br /&gt;log "RECEIVER_LIST: " $RECEIVER_LIST&lt;br /&gt;log "FQN_QUEUE_NAME: " $FQN_QUEUE_NAME&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But implementing this I got the strange behaviour that posfix did call my script but the script did not get any arguments! Logging like the following gave me 0 arguments:&lt;br /&gt;&lt;pre class="brush: plain"&gt;# Check Arguments&lt;br /&gt;log "Number of arguments:  $#"&lt;br /&gt;log "Arguments:  $*"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Yesterday and this morning I tried and figured and thought until my brains got nearly overheated. But since all my configs seemed alright and even the version I knew they worked, it finally stroke me that it had to with the commandline to call the script.&lt;br /&gt;&lt;br /&gt;And I finally had it. It was due to the nasty '-c' option after '/bin/bash'!&lt;br /&gt;&lt;br /&gt;It probably got there through an example I used. And it was removed in the test environments, but apparently not in my examples and documentation. So it also came into my earlier post. The option toggles the spawn of a new bash-session for the script. The arguments got into the 'parent' session but not into the 'child'-session that runs the script. Removing the '-c'option would do the trick.&lt;br /&gt;&lt;br /&gt;Furthermore I moved the $receiver argument to the end since it can expand to more arguments. Although the script would not have problems with it, I found it saver.&lt;br /&gt;&lt;br /&gt;So the resulting (correct) line in the master.cf should be:&lt;br /&gt;&lt;pre class="brush: plain"&gt;routemq   unix  -       n       n       -       -       pipe&lt;br /&gt;flags=Fq. user=smtpbridge argv=/bin/bash  /home/smtpbridge/routemq.sh -q $nexthop -s $sender -r $recipient&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-1746036542567856634?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/1746036542567856634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=1746036542567856634' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1746036542567856634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1746036542567856634'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/09/headache-from-postfix.html' title='Headache from postfix'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-1011079252225138997</id><published>2010-08-31T03:15:00.000-07:00</published><updated>2011-04-06T00:41:49.154-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>Index-of, replace and key-value parsing in XSLT</title><content type='html'>Lately I had to change a few BPEL Processes in a way that I had to pass multiple parameters in one field. Instead of a complete base64 encoded data-object I had to pass a key to that object in a way that I could determine that the object was in fact a key-value pair. The field contains in that case in fact two key-value pairs. I thought that if I would code the key-value pair with something like $KEY="AABBCCDDEEFF" I could search for $KEY=" and then the value after the double-quote and before the next would then be the value.&lt;br /&gt;&lt;br /&gt;The problem with XSLT is that you have functions like &lt;span style="font-style: italic;"&gt;substring-before()&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;substring-after()&lt;/span&gt; and positional substring, where the from-position and length can be passed as numeric values. But for the latter function you need to determine the start and end position of the sub-string to extract from the input string. But apparently XSLT does not provide something like the Pl/Sql &lt;span style="font-style: italic;"&gt;instr&lt;/span&gt; or Java &lt;span style="font-style: italic;"&gt;index-of().&lt;/span&gt; Also XSLT lacks a replace function in which you can replace a string within a string with a replacement string. The xslt-replace() function does a character-by-character replace.&lt;br /&gt;&lt;br /&gt;Fortunately you can build these functions quite easilily yourself as xslt-templates using the &lt;span style="font-style: italic;"&gt;substring-before(), substring-after()&lt;/span&gt;, and &lt;span style="font-style: italic;"&gt;string-length()&lt;/span&gt; functions. I found the examples somewhere and adapted them a little for my purpose. Mainly to get them case-insensitive.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Index-of-ci&lt;/span&gt;&lt;br /&gt;Here is my Case insensitive version of the Index-of template:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;!-- index-of: find position of search within string&lt;br /&gt;2010-08-31, by Martien van den Akker --&amp;gt;&lt;br /&gt;&amp;lt;xsl:template name="index-of-ci"&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="string"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="search"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="startPos"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="searchLwr" select="xp20:lower-case($search)"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="work"&amp;gt;&lt;br /&gt;&amp;lt;xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;xsl:when test="string-length($startPos)&amp;amp;gt;0"&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="substring($string,$startPos)"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:when&amp;gt;&lt;br /&gt;&amp;lt;xsl:otherwise&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="$string"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;&amp;lt;/xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="stringLwr" select="xp20:lower-case($work)"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="result"&amp;gt;&lt;br /&gt;&amp;lt;xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;xsl:when test="contains($stringLwr,$searchLwr)"&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="stringBefore"&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="substring-before($stringLwr,$searchLwr)"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;&amp;lt;xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;xsl:when test="string-length($startPos)&amp;amp;gt;0"&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="$startPos +string-length($stringBefore)"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:when&amp;gt;&lt;br /&gt;&amp;lt;xsl:otherwise&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="1 + string-length($stringBefore)"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;&amp;lt;/xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;/xsl:when&amp;gt;&lt;br /&gt;&amp;lt;xsl:otherwise&amp;gt;-1&amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;&amp;lt;/xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;&amp;lt;xsl:copy-of select="$result"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:template&amp;gt;&lt;/pre&gt;&lt;br /&gt;The template expects 3 parameters:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;string&lt;/span&gt;: the string in which is searched&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;search&lt;/span&gt;: the substring that has to be searched&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;startPos&lt;/span&gt;: position in &lt;span style="font-style: italic;"&gt;string&lt;/span&gt; where the search is started&lt;/li&gt;&lt;/ul&gt;The first thing the template does is declaring a &lt;span style="font-style: italic;"&gt;work&lt;/span&gt;-variable. If &lt;span style="font-style: italic;"&gt;startPos &lt;/span&gt;is not given, the variable &lt;span style="font-style: italic;"&gt;work&lt;/span&gt; will contain the complete input &lt;span style="font-style: italic;"&gt;string&lt;/span&gt;. But if &lt;span style="font-style: italic;"&gt;startPos&lt;/span&gt; is given &lt;span style="font-style: italic;"&gt;work&lt;/span&gt; will contain the substring of &lt;span style="font-style: italic;"&gt;string&lt;/span&gt; from &lt;span style="font-style: italic;"&gt;startPos&lt;/span&gt; to the end.&lt;br /&gt;&lt;br /&gt;Then the input and the search strings are converted to lower case into new variables:  and&lt;span style="font-style: italic;"&gt;inputLwr&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;searchLwr&lt;/span&gt;. These variables are to test case-insensitively if the search string is in the input. If that is the case then the part of the input &lt;span style="font-style: italic;"&gt;string&lt;/span&gt; before the &lt;span style="font-style: italic;"&gt;search&lt;/span&gt; string is determined with the &lt;span style="font-style: italic;"&gt;substring-before()&lt;/span&gt; function. The &lt;span style="font-style: italic;"&gt;string-length()&lt;/span&gt; of the result denotes in fact the numeric position of the &lt;span style="font-style: italic;"&gt;search&lt;/span&gt; string within the input &lt;span style="font-style: italic;"&gt;string&lt;/span&gt;. This is incremented by 1 or by &lt;span style="font-style: italic;"&gt;startPos&lt;/span&gt; depending on &lt;span style="font-style: italic;"&gt;startPos&lt;/span&gt; being filled.&lt;br /&gt;&lt;br /&gt;The template can be called without the &lt;span style="font-style: italic;"&gt;startPos parameter:&lt;/span&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;xsl:call-template name="index-of-ci"&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="string" select="$input"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="search" select="$keyStr"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or with the parameter:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;xsl:call-template name="index-of-ci"&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="string" select="$input"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="search" select="string('&amp;amp;quot;')"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="startPos" select="$startIdx"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Replace&lt;/span&gt;&lt;br /&gt;The next template replaces the &lt;span style="font-style: italic;"&gt;fromStr&lt;/span&gt; in &lt;span style="font-style: italic;"&gt;input&lt;/span&gt; to &lt;span style="font-style: italic;"&gt;toStr&lt;/span&gt;.&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;!-- replace-ci: case insensitive replace based on strings &lt;br /&gt;2010-08-31, by Martien van den Akker --&amp;gt;&lt;br /&gt;&amp;lt;xsl:template name="replace-ci"&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="input"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="fromStr"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="toStr"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="startStr"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:if test="string-length( $input ) &amp;amp;gt; 0"&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="posStartStr"&amp;gt;&lt;br /&gt;&amp;lt;xsl:call-template name="index-of-ci"&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="string"&lt;br /&gt;select="$input"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="search"&lt;br /&gt;select="$startStr" /&amp;gt;&lt;br /&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="startPos"&amp;gt;&lt;br /&gt;&amp;lt;xsl:call-template name="index-of-ci"&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="string"&lt;br /&gt;select="$input"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="search"&lt;br /&gt;select="$fromStr" /&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="startPos"&lt;br /&gt;select="$posStartStr" /&amp;gt;&lt;br /&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="inputLwr" select="xp20:lower-case($input)"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="startStrLwr" select="xp20:lower-case($startStr)"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;xsl:when test="contains( $input, $startStrLwr ) and contains( $inputLwr, $fromStr )"&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="stringBefore" select="substring($input,1,$startPos - 1)"/&amp;gt;   &lt;br /&gt;&amp;lt;xsl:variable name="stringAfter" select="substring($input,$startPos + string-length($fromStr))"/&amp;gt;   &lt;br /&gt;&amp;lt;xsl:value-of select="concat($stringBefore,$toStr)"/&amp;gt;         &lt;br /&gt;&amp;lt;xsl:call-template name="replace-ci"&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="input"&lt;br /&gt;select="$stringAfter"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="fromStr"&lt;br /&gt;select="$fromStr" /&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="toStr"&lt;br /&gt;select="$toStr" /&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="startStr"&lt;br /&gt;select="$startStr" /&amp;gt;&lt;br /&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;&amp;lt;/xsl:when&amp;gt;&lt;br /&gt;&amp;lt;xsl:otherwise&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="$input"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;&amp;lt;/xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;/xsl:if&amp;gt;&lt;br /&gt;&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here the pos of the from string is determined using the &lt;span style="font-style: italic;"&gt;index-of-ci&lt;/span&gt; template described earlier.&lt;br /&gt;But this is done from the position of the &lt;span style="font-style: italic;"&gt;startStr&lt;/span&gt; that marks the start of the replacement search. For example, if you want to replace domain names in email-adresses, you want to start the search of the domain after the at-sign ( '@' ).&lt;br /&gt;Having the start position of the 'from'-string the part of the input before and after the 'from'-string is taken using the &lt;span style="font-style: italic;"&gt;string-before&lt;/span&gt;() and &lt;span style="font-style: italic;"&gt;strina-after()&lt;/span&gt; functions.&lt;br /&gt;The 'to'-string is concatenated to the result of the &lt;span style="font-style: italic;"&gt;string-before()&lt;/span&gt;. The result of the &lt;span style="font-style: italic;"&gt;string-after&lt;/span&gt;()  is used to call the template recursively to search the remainder of the input-string.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Parsing keys&lt;/span&gt;&lt;br /&gt;The following template parses a key value like $KEY="AABBCCDDEEFF"&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;!-- Parse a KeyValue&lt;br /&gt;2010-08-31, By Martien van den Akker --&amp;gt;&lt;br /&gt;&amp;lt;xsl:template name="getKeyValue"&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="input"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="key"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:param name="default"/&amp;gt;&lt;br /&gt;&amp;lt;!-- Init variables --&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="keyStr" select="concat('$',$key,'=&amp;amp;quot;')"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:if test="string-length( $input ) &amp;amp;gt; 0"&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="startIdxKey"&amp;gt;&lt;br /&gt;&amp;lt;xsl:call-template name="index-of-ci"&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="string" select="$input"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="search" select="$keyStr"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="keyLength" select="string-length($keyStr)"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="startIdx" select="$startIdxKey+$keyLength"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:variable name="endIdx"&amp;gt;&lt;br /&gt;&amp;lt;xsl:call-template name="index-of-ci"&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="string" select="$input"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="search" select="string('&amp;amp;quot;')"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name="startPos" select="$startIdx"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;&amp;lt;!-- Determine value --&amp;gt;&lt;br /&gt;&amp;lt;xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;xsl:when test="$startIdxKey&amp;amp;gt;=0 and $endIdx&amp;amp;gt;=0"&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="substring($input,$startIdx, $endIdx - $startIdx)"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:when&amp;gt;&lt;br /&gt;&amp;lt;xsl:when test="$startIdxKey&amp;gt;0 and $endIdx&amp;amp;lt;0"&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="substring($input,$startIdx)"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:when&amp;gt;&lt;br /&gt;&amp;lt;xsl:otherwise&amp;gt;&lt;br /&gt;&amp;lt;xsl:if test="$default='Y'"&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="$input"/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:if&amp;gt;&lt;br /&gt;&amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;&amp;lt;/xsl:choose&amp;gt;&lt;br /&gt;&amp;lt;/xsl:if&amp;gt;&lt;br /&gt;&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&lt;/pre&gt;The working is quite similar to the templates above. If you understand the replace-template, you wouldn't have trouble with this one. Basically the value is search using the &lt;span style="font-style: italic;"&gt;index-of-ci&lt;/span&gt; template with a concatenation of '$', the &lt;span style="font-style:italic;"&gt;key&lt;/span&gt; and '="'. The string after that is the value, with a double quote as the end delimiter. &lt;br /&gt;Having this template you can search for the key any where in the string, even if there are multiple key-value pairs. &lt;br /&gt;The template can be called like:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;ns1:Id&amp;gt;&lt;br /&gt;&amp;lt;xsl:call-template name=&amp;quot;getKeyValue&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name=&amp;quot;input&amp;quot; select=&amp;quot;/ns2:aap/ns2:noot&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name=&amp;quot;key&amp;quot; select=&amp;quot;&amp;apos;KEY&amp;apos;&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;xsl:with-param name=&amp;quot;default&amp;quot; select=&amp;quot;&amp;apos;Y&amp;apos;&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;&amp;lt;/ns1:Id&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The parameter 'default' is optional: if it is set to 'Y' and the KEY is not found in the input string, then the value of the input is returned as result. Otherwise nothing is returned.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;I found these templates very helpful. Using them you can do almost any string replacements in XSLT. ALso to me they function as example to cope with more advanced XSLT-challenges.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-1011079252225138997?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/1011079252225138997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=1011079252225138997' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1011079252225138997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1011079252225138997'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/08/index-of-replace-and-key-value-parsing.html' title='Index-of, replace and key-value parsing in XSLT'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-187280992728553391</id><published>2010-07-01T00:18:00.000-07:00</published><updated>2011-04-06T00:18:12.698-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle VM'/><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Box'/><title type='text'>VMWare Player vs. Server, vs. Virtual Box</title><content type='html'>Virtualization is great. It is very handy to have your complex installations of server software in a Virtual Machine. I do it for years and have only some client tools that do need a complex installation on my host. JDeveloper, SQLDeveloper or Pl/Sql Developer for instance. It enables you to reinstall your laptop and be up and running after having installed your virtualization product. Provided that you backup your VM's of course. Also I have a Windows based VM with some tools for administration purposes.&lt;br /&gt;&lt;br /&gt;I started years ago with VMware Workstation 3 to 5.x. But then VMware Server came out. And back then workstation did not provide much extra above Server. And although I had a demo license for Workstation (which ended), Server was for free. Actually the only missing feature in Server I encountered was 'Shared Folders'. But that I solved using (S)Ftp. Under windows it is very convenient to have a FileZilla Server. You could solve it by defining a share in Windows. But I found that that gives some problems when you have multiple copies of a VM running on the same network. Then you have to change your host name, etc. And it is problematic if you have multiple shared open in multiple VM's while your windows account have a regularly changed password. So shared folders as an alternative to FTP is not necessary but very convenient.&lt;br /&gt;&lt;br /&gt;Shortly after VMware Server VMware Player came out. But until today it was not possible to create new VM's in Player. And that is a 'must have' to me.&lt;br /&gt;&lt;br /&gt;VMware 2.0 was a large step for me since I found it astonishing that the footprint from 1.0 grew by a factor 5! But since VMware dit not keep 1.0 up with the Linux Kernel changes, I did the upgrade. Now I was a pretty satisfied VMware Server user.&lt;br /&gt;&lt;br /&gt;But there are two problems now with VMware Server 2.x.:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;VMware Server 2.x does not keep up with the Linux kernel changes either. I upgraded to OpenSuse 11.2, which worked very well. But stepped back to 11.1 since VMware Server did not install with that kernel.&lt;/li&gt;&lt;li&gt;Since FireFox 3.6 the VMware Console does not work anymore. This is solvable by installing a seperate FF 3.5.9 for VMware usage. But this is very inconvenient.&lt;/li&gt;&lt;/ul&gt;Lately I tried Virtual Box again because of the Firefox problems and I reported to be very enthousiastic about it. And indeed it is a very good product. But unfortunately most of my VM's are VMware based. It is possible to run a VM in virtual box based on VMware files. But you have to create a new Virtual Box VM for that purpose that refer to the VMware files. And than you have to de-install the VMware Tools (which probably have installed in that VM) and install VirtualBox GuestAdditions. It's all doable and no rocket-science. But it's not a simple import-and-run.&lt;br /&gt;&lt;br /&gt;But since 25th of may &lt;a href="http://www.vmware.com/products/player/"&gt;VMware Player 3.1 &lt;/a&gt;was released. And apparently Vmware released it as an answer to the Windows XP mode on Windows 7. To run older Windows XP compatible apps in Windows 7. But it occurs to me that they've looked closely to VirtualBox. The VMware Unity mode is quite comparable or actually the same as the Seamless Windows mode of VirtualBox. This is a very attractive feature that makes VMware Player as well as VirtualBox suitable to beat the Windows XP mode of Windows 7. I have not be able to try the XP mode of Windows 7. So I don't know about load times of the XP mode. But for VirtualBox and VMware Player you need to start the guest Windows to be able to use it. And you have to have an activated version of Windows in your VM.&lt;br /&gt;&lt;br /&gt;And since VMware Player 3.1 I'm able to create VM's in Player. Actually, with being able to create VM's in Player and with the 'Shared Folder' feature I think you might say that Player is on the 'must-have'-feature-level of VMware Workstation 5.5. And since Player has a smaller foot print (100MB, about the same as Server 1.0.x)  and does not need to have an Apache Tomcat running, no need for browser access of the console: VM's running in a seperate application window, Player is a very much better suitable for running VM's on a laptop/desktop. And a feature like VMware Unity/VirtualBox Seamless Windows mode  is really nice. It is funny to have windows applications running in a window side by side with your Linux apps. Even copy and paste works.  And having shared folders makes it possible to have your Guest-OS apps work with the same files as your host OS apps.&lt;br /&gt;&lt;br /&gt;And what made me most lyric? I had my OpenSuse 11.1 connected to a beamer. In the NVidia conrols I had the CRT (as NVidia/X called it) placed right of my LCD desktop. Then I placed my PowerPoint in Unity on the Beamer area of the desktop (so I was able to see other apps on my lcd screen). And then it played the slideshow fullscreen on the beamer...&lt;br /&gt;I was very happy about it, because I had PowerPoint 2007 working under Wine. But editing a file under PowerPoint2007/wine was not doable. Whey drag and drop or move an object on the canvas the canvas becomes black until you release the object. Only then it draws again. But in the VMware Unity mode, PowerPoint 2007 is usable under Linux!&lt;br /&gt;&lt;br /&gt;To conclude, when to use what? A question I try to answer a lot lately.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If you want to run VMware VM's on your own laptop along with other apps, use VMware Player&lt;/li&gt;&lt;li&gt;If you want to run MS-Office 2007 or other Windows apps side by side with other applications on your Linux machine, use either VMware Player with Unity or Virtual Box with Seamless Windows mode (you may choose).  But you should try if the app works properly enough under Wine, since that will give you much faster startup times and lower system-load, since you do not have to load Windows as a guest os.&lt;/li&gt;&lt;li&gt;If you want to run VM's on a host that has to be reachable from different location, then use VMware Server. For example, if you have a spare desktop on the attick that you want to leverage for different purposes, then use Server. With server you can start, stop and use the VM-desktop using a browser. Unfortunatly it has to be a FireFox 3.5 at most, for the current Server version (2.x).&lt;/li&gt;&lt;li&gt;If you look for an enterprise solution, look at Oracle VM or VMware ESX and their management products. These solutions are beyond my use. Since they run on 'bare-metal', and that is out of the question for me.&lt;/li&gt;&lt;/ul&gt;I don't have particular arguments for the choice between VirtualBox and VMware Player. There are other virtualization tools like KVM or Xen based. There are people that favor a particular solution over VMware because of performance. Especially the VMware would not be that fast in IO-operations. But I haven't seen any benchmarks that support this. I haven't done any measurements in particular but I did not experience any particular performance differences between VirtualBox and VMware. The only reason actually that I favor VMware is just that most of my VM's are based on VMware.&lt;br /&gt;&lt;br /&gt;But I sincerely hope that Oracle works on improving both Oracle VM and VirtualBox in a way that get both products in line with eachother and eventually let both products work with the same VM-architecture. Then it would be able to use Oracle VM's on both Oracle VM and VirtualBox. Maybe that would be an extra stimulus to build VirtualBox/Oracle VM appliances.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-187280992728553391?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/187280992728553391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=187280992728553391' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/187280992728553391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/187280992728553391'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/07/vmware-player-vs-server-vs-virtual-box.html' title='VMWare Player vs. Server, vs. Virtual Box'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-1655438892878647610</id><published>2010-06-16T06:19:00.000-07:00</published><updated>2011-03-16T08:05:27.422-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><title type='text'>Oracle Inserts based on DB2 selects</title><content type='html'>It's been a while that I wrote an article. This week I struggled with creating insert scripts based on data from DB2 to be used in my local test database (Oracle XE) at my customer.&lt;br /&gt;&lt;br /&gt;We use Siebel and have to integrate here and there by querying data from the Siebel DB2 database. It turns out that my local database adapter has trouble with connecting to the DB2 database. Could not find out what's wrong, so I decided that I would query the data from the Siebel tables and insert it into my local XE database. It's faster anyway  (in my case) and it also allows me to manipulate the data for test-case purposes.&lt;br /&gt;But querying db2 to generate insert statements isn't as obvious as I would do it in Oracle.&lt;br /&gt;&lt;br /&gt;Here is an example script.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: sql"&gt;select&lt;br /&gt;'Insert into CONTACT (PARTYROWID,KLANTID,KLANTTYPE,AANGEMAAKTOP,BANKCODE,BANKLOCATIE,KLANTSTATUS,CORRESPONSDENTIETAAL,PRIMAIRTELEFOONNUMMER,'&lt;br /&gt;|| 'PRIMAIRTELEFOONTYPE,PRIMAIREMAIL,PRIMAIREMAILFORMAAT,TELEFOONPRIVE,TELEFOONOVERIG,TELEFOONMOBIEL,TELEFOONWERK,FAX,EMAIL,EMAILFORMAAT,EMAILDATUM,'&lt;br /&gt;|| 'EMAILBRON,INGEZETENEVAN,NATIONALITEIT,ACHTERNAAM,VOLLEDIGEACHTERNAAM,ROEPNAAM,GESLACHTSNAAM,VOORLETTERS,VOLLEDIGEVOORNAMEN,ACADEMISCHETITEL'&lt;br /&gt;||',TUSSENTITEL,ACHTERVOEGSEL,ACHTERTITEL,VOORVOEGSEL,VOORVOEGSELGESLACHTSNAAM,GEBOORTDATUM,GESLACHT,GEBOORTELAND,GEBOORTEPLAATS,EIGENHUIS,FAILLIET,SAMENLEVINGSVORM'&lt;br /&gt;||',BURGERLIJKSTAAT,HUW_VOORWAARDEN,PERSONEEL,TYPEKLANT,MAATSCHAPPELIJKESTATUS,LOKALEKLANTINDELING,CENTRALEKLANTINDELING,KLANTINDELING,LOKAALINGEDEELD,BEHOEFTEPROFIEL,'&lt;br /&gt;||'TAXIDENTIFICATIONNR,WOONPLAATSVERKLARING,SOFINUMMER,REDENGEENSOFINUMER,DATUMOVERLIJDEN,OVERLEDEN,AARDIDENTIFICATIEDOC,DATUMLEGITIMATIE,NRIDENTIFICATIEDOC,'&lt;br /&gt;|| 'DATUMUITGIFTE,LANDUITGIFTE,PLAASTUITGIFTE,PERTELEFOONBENADEREN,PEREMAILBENADEREN,PERPOSTBENADEREN,PERSMSBENADEREN,PERFAXBENADEREN,INSOLVENCYSTATUS,IKBNUMBER)'&lt;br /&gt;||' values ('&lt;br /&gt;|| ''''|| coalesce(ctt.PARTYROWID,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.KLANTID,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.KLANTTYPE,'') ||''','&lt;br /&gt;|| case when ctt.AANGEMAAKTOP is not null then 'to_date('''||varchar_format( ctt.AANGEMAAKTOP,'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' else 'null' end ||','&lt;br /&gt;|| ''''|| coalesce(ctt.BANKCODE,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.BANKLOCATIE,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.KLANTSTATUS,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.CORRESPONSDENTIETAAL,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.PRIMAIRTELEFOONNUMMER,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.PRIMAIRTELEFOONTYPE,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.PRIMAIREMAIL,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.PRIMAIREMAILFORMAAT,'') ||''','&lt;br /&gt;|| ''''|| coalesce(varchar(ctt.TELEFOONPRIVE),'') ||''','&lt;br /&gt;|| ''''|| coalesce(varchar(ctt.TELEFOONOVERIG),'') ||''','&lt;br /&gt;|| ''''|| coalesce(varchar(ctt.TELEFOONMOBIEL),'') ||''','&lt;br /&gt;|| ''''|| coalesce(varchar(ctt.TELEFOONWERK),'') ||''','&lt;br /&gt;|| ''''|| coalesce(varchar(ctt.FAX),'') ||''','&lt;br /&gt;|| ''''|| coalesce(varchar(ctt.EMAIL),'') ||''','&lt;br /&gt;|| ''''|| coalesce(varchar(ctt.EMAILFORMAAT),'') ||''','&lt;br /&gt;|| case when ctt.EMAILDATUM is not null then 'to_date('''||varchar_format( ctt.EMAILDATUM,'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' else 'null' end ||','&lt;br /&gt;|| ''''|| coalesce(EMAILBRON,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.INGEZETENEVAN,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.NATIONALITEIT,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.ACHTERNAAM,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.VOLLEDIGEACHTERNAAM,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.ROEPNAAM,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.GESLACHTSNAAM,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.VOORLETTERS,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.VOLLEDIGEVOORNAMEN,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.ACADEMISCHETITEL,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.TUSSENTITEL,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.ACHTERVOEGSEL,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.ACHTERTITEL,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.VOORVOEGSEL,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.VOORVOEGSELGESLACHTSNAAM,'') ||''','&lt;br /&gt;|| case when ctt.GEBOORTDATUM is not null then 'to_date('''||varchar_format( ctt.GEBOORTDATUM,'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' else 'null' end ||','&lt;br /&gt;|| ''''|| coalesce(ctt.GESLACHT,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.GEBOORTELAND,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.GEBOORTEPLAATS,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.EIGENHUIS,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.FAILLIET,'') ||''','&lt;br /&gt;|| ''''|| coalesce(ctt.SAMENLEVINGSVORM,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.BURGERLIJKSTAAT,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.HUW_VOORWAARDEN,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.PERSONEEL,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.TYPEKLANT,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.MAATSCHAPPELIJKESTATUS,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.LOKALEKLANTINDELING,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.CENTRALEKLANTINDELING,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.KLANTINDELING,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.LOKAALINGEDEELD,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.BEHOEFTEPROFIEL,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.TAXIDENTIFICATIONNR,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.WOONPLAATSVERKLARING,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.SOFINUMMER,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.REDENGEENSOFINUMER,'') ||''','&lt;br /&gt;|| case when ctt.DATUMOVERLIJDEN is not null then 'to_date('''||varchar_format( ctt.DATUMOVERLIJDEN,'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' else 'null' end ||','&lt;br /&gt;|| ''''|| coalesce( ctt.OVERLEDEN,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.AARDIDENTIFICATIEDOC,'') ||''','&lt;br /&gt;|| case when ctt.DATUMLEGITIMATIE is not null then 'to_date('''||varchar_format( ctt.DATUMLEGITIMATIE,'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' else 'null' end ||','&lt;br /&gt;|| ''''|| coalesce( ctt.NRIDENTIFICATIEDOC,'') ||''','&lt;br /&gt;|| case when ctt.DATUMUITGIFTE is not null then 'to_date('''||varchar_format( ctt.DATUMUITGIFTE,'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' else 'null' end ||','&lt;br /&gt;|| ''''|| coalesce( ctt.LANDUITGIFTE,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.PLAASTUITGIFTE,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.PERTELEFOONBENADEREN,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.PEREMAILBENADEREN,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.PERPOSTBENADEREN,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.PERSMSBENADEREN,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.PERFAXBENADEREN,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.INSOLVENCYSTATUS,'') ||''','&lt;br /&gt;|| ''''|| coalesce( ctt.IKBNUMBER,'') ||''');'&lt;br /&gt;from siebel.contact ctt&lt;br /&gt;where klantid='12345';&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The first  'not so obvious' is the NVL-function. This is a typical Oracle function. For most purposes this can be translated to the coalesce function above. In most cases when the column is empty I want to have an "empty value". In some cases just&lt;br /&gt;giving "coalesce( column-reference,'')" does not suffice. I had to cast the column explicitly to char with the varchar() function:&lt;br /&gt;&lt;pre class="brush: sql"&gt;coalesce(varchar(ctt.TELEFOONPRIVE),'')&lt;/pre&gt;&lt;br /&gt;Here &lt;span style="font-style: italic;"&gt;TELEFOONPRIVE&lt;/span&gt; is apparently a number column. The function coalesce() assumes the number datatype and can't accept an empty string as default string.&lt;br /&gt;&lt;br /&gt;For dates it is a little more complicated. If there is a date I want to transform it to an Oracle to_date function. But then I have to be sure that the format comming from DB2 is of a standard format. I choose "YYYY-MM-DD HH24:MI:SS". If the date is empty I just want to return an empty string again. I couldn't come up with a simple construct using coalesce(). So I used the &lt;span style="font-style: italic;"&gt;CASE WHEN&lt;/span&gt;-construct:&lt;br /&gt;&lt;pre class="brush: sql"&gt;case when ctt.DATUMOVERLIJDEN is not null then 'to_date('''||varchar_format( ctt.DATUMOVERLIJDEN,'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' else 'null' end&lt;/pre&gt;&lt;br /&gt;It took me a while to find out that where in Oracle you can provide a date-format to the to_char(&amp;lt;date-value&amp;gt;, &amp;lt;date-format&amp;gt;) function, in DB2 you need the varchar_format(&amp;lt;date-value&amp;gt;, &amp;lt;date-format&amp;gt;) function for that. Luckily the accepted date-formats are the same in my case. So here I transform the date-value from DB2 to the required date-format and concatenate it with the Oracle to_date() function with the same format.&lt;br /&gt;&lt;br /&gt;The generated insert statement(s) will look like (enter at values clause added manually for readability):&lt;br /&gt;&lt;pre class="brush: sql"&gt;Insert into CONTACT (PARTYROWID,KLANTID,KLANTTYPE,AANGEMAAKTOP,BANKCODE,BANKLOCATIE,KLANTSTATUS,CORRESPONSDENTIETAAL,PRIMAIRTELEFOONNUMMER,PRIMAIRTELEFOONTYPE,PRIMAIREMAIL,PRIMAIREMAILFORMAAT,TELEFOONPRIVE,TELEFOONOVERIG,TELEFOONMOBIEL,TELEFOONWERK,FAX,EMAIL,EMAILFORMAAT,EMAILDATUM,EMAILBRON,INGEZETENEVAN,NATIONALITEIT,ACHTERNAAM,VOLLEDIGEACHTERNAAM,ROEPNAAM,GESLACHTSNAAM,VOORLETTERS,VOLLEDIGEVOORNAMEN,ACADEMISCHETITEL,TUSSENTITEL,ACHTERVOEGSEL,ACHTERTITEL,VOORVOEGSEL,VOORVOEGSELGESLACHTSNAAM,GEBOORTDATUM,GESLACHT,GEBOORTELAND,GEBOORTEPLAATS,EIGENHUIS,FAILLIET,SAMENLEVINGSVORM,BURGERLIJKSTAAT,HUW_VOORWAARDEN,PERSONEEL,TYPEKLANT,MAATSCHAPPELIJKESTATUS,LOKALEKLANTINDELING,CENTRALEKLANTINDELING,KLANTINDELING,LOKAALINGEDEELD,BEHOEFTEPROFIEL,TAXIDENTIFICATIONNR,WOONPLAATSVERKLARING,SOFINUMMER,REDENGEENSOFINUMER,DATUMOVERLIJDEN,OVERLEDEN,AARDIDENTIFICATIEDOC,DATUMLEGITIMATIE,NRIDENTIFICATIEDOC,DATUMUITGIFTE,LANDUITGIFTE,PLAASTUITGIFTE,PERTELEFOONBENADEREN,PEREMAILBENADEREN,PERPOSTBENADEREN,PERSMSBENADEREN,PERFAXBENADEREN,INSOLVENCYSTATUS,IKBNUMBER) &lt;br /&gt;values ('1-100BM-100','000000105727750','Person',to_date('2006-05-09 19:59:21','YYYY-MM-DD HH24:MI:SS'),'3365','336515','C','NL','','','','','','','','','','','',to_date('2008-09-15 00:00:00','YYYY-MM-DD HH24:MI:SS'),'FULFILMENT','01','',to_date('2009-07-08 00:00:00','YYYY-MM-DD HH24:MI:SS'),'NL','NL','Name','Name','','Name','I.R.S.','Iris Ronald Simon','','','','','','',to_date('1966-11-11 00:00:00','YYYY-MM-DD HH24:MI:SS'),'M','NL','Tool Town','Y','N','3','1','9','03','01','08','','1','1','Y','','','X','123456789','',null,'N','03',to_date('2005-07-29 00:00:00','YYYY-MM-DD HH24:MI:SS'),'IC4631943',to_date('2004-07-29 00:00:00','YYYY-MM-DD HH24:MI:SS'),'NL','Tool Village','N','N','Y','Y','N','','1-22A-3344');&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-1655438892878647610?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/1655438892878647610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=1655438892878647610' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1655438892878647610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1655438892878647610'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/06/oracle-inserts-based-on-db2-selects.html' title='Oracle Inserts based on DB2 selects'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-3240505688151931987</id><published>2010-04-21T04:47:00.000-07:00</published><updated>2010-04-21T05:25:51.855-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Box'/><title type='text'>Shared folders in VirtualBox</title><content type='html'>If you have installed the VirtualBox guest-additions then you can use the SharedFolders functionality as well. This might be a usefull differentiating feature over VMware Server. VMware Workstation has this feature as well, but it will cost you about 190 dollar.&lt;br /&gt;&lt;br /&gt;Shared Folders are folders on your host OS that you denoted to the virtualization product (VirtualBox or VMware Workstation) as being available to the guest OS. This handy because you then do not have to setup Windows or Samba shares on your host to connect to from your guest. Also it prevents you from having to setup particular network settings for it.&lt;br /&gt;&lt;br /&gt;An alternative to shared folders, besides Windows or Samba shares is to (S)Ftp the particular files to your guest. If it is about installation files (for example the Oracle 11gR2 database) then you need to have space available in the guest-virtual disks. The virtual disks will grow accordingly. If you go for that approach then it is wise to add a temporary virtual disk to hold the installations. Afterwards you can remove the disk without the need to defrag and shrink the remaining disks.&lt;br /&gt;&lt;br /&gt;To use the shared folders in VirtualBox you need to define a folder to share in the SharedFolders screen. This is available through the Devices main menu option:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_myrkQ5dyTYg/S87rRTR-3MI/AAAAAAAACPQ/evVxSi_z2Gs/s1600/VirtualBoxSharedFolders.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 237px;" src="http://4.bp.blogspot.com/_myrkQ5dyTYg/S87rRTR-3MI/AAAAAAAACPQ/evVxSi_z2Gs/s400/VirtualBoxSharedFolders.png" alt="" id="BLOGGER_PHOTO_ID_5462562080512990402" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In a Windows guest you might find the shared folders in the Windows Explorer under the network places.&lt;br /&gt;In Linux guest you need to mount the share explicitly.&lt;br /&gt;You first need to make a directory under the /mnt folder :&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[root@oel5soa11g mnt]# mkdir Zarchief&lt;br /&gt;[root@oel5soa11g mnt]# chmod a+w Zarchief/&lt;br /&gt;[root@oel5soa11g mnt]# chmod a+x Zarchief/&lt;br /&gt;[root@oel5soa11g mnt]# ls -l&lt;br /&gt;total 8&lt;br /&gt;drwxrwxrwx 2 root root 4096 Apr 21 14:11 Zarchief&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then you can mount the shared folder with the following command:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# mount -t vboxsf [SharedFolderName] /mnt/[FolderName]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[root@oel5soa11g mnt]# mount -t vboxsf Zarchief /mnt/Zarchief&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-3240505688151931987?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/3240505688151931987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=3240505688151931987' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3240505688151931987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3240505688151931987'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/04/shared-folders-in-virtualbox.html' title='Shared folders in VirtualBox'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_myrkQ5dyTYg/S87rRTR-3MI/AAAAAAAACPQ/evVxSi_z2Gs/s72-c/VirtualBoxSharedFolders.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-1542277964197773229</id><published>2010-04-21T02:29:00.000-07:00</published><updated>2010-04-21T02:48:34.727-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Machines'/><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Box'/><title type='text'>FireFox 3.6 conflict with VMware Console: VirtualBox</title><content type='html'>Today I wanted to work with a VMware image to play around with weblogic/soasuite 11g etc. But I ran into the nasty FireFox 3.6 conflict with the VMware Console. Since FireFox 3.6.x the console won't start, because of some &lt;a href="http://communities.vmware.com/thread/252218"&gt;time-out error&lt;/a&gt;. The solution would be to downgrade to FireFox 3.5. But since I have a repository installed version, I found a downgrade too tedious. Too bad that the console plugin won't install in Google Chrome. I tried Mozilla Seamonkey, but that wouldn't do the trick also.&lt;br /&gt;&lt;br /&gt;So I desided to get VirtualBox from the stable again. I neatly installed it using the VirtualBox repository for my OpenSUSE (see the bottom of the page &lt;a href="http://www.virtualbox.org/wiki/Linux_Downloads"&gt;here&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;I created a VirtualBox VM based on the VMware files of the VM I wanted to start. See &lt;a href="http://darwin-it.blogspot.com/2009/10/virtualbox-virtual-competitor-of-vmware.html"&gt;this earlier blogpost&lt;/a&gt; for a how-to.&lt;br /&gt;&lt;br /&gt;Naively I removed the IDE-controller. But it turns out to be needed to be able to mount the Guest-Additions-ISO file. So don't remove that.&lt;br /&gt;&lt;br /&gt;Now I hope that there is blessing on this traject, since I have put in too much time in it already, in my opinion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-1542277964197773229?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/1542277964197773229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=1542277964197773229' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1542277964197773229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1542277964197773229'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/04/firefox-36-conflict-with-vmware-console.html' title='FireFox 3.6 conflict with VMware Console: VirtualBox'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-1394636103245157627</id><published>2010-04-01T02:44:00.000-07:00</published><updated>2011-03-16T08:06:16.911-07:00</updated><title type='text'>Logging in bash script</title><content type='html'>To debug a bash script and to know what the environment is where a script is behaving it is convenient to log. This is what I added to my e-mail prosessing script yesterday. It is simple and of course every one else could think of it. Probably it is invented hundreds of times. Here's my solution.&lt;br /&gt;&lt;pre class="brush: bash"&gt;#!/bin/bash&lt;br /&gt;###################################################################################################&lt;br /&gt;# Log&lt;br /&gt;# Script to demonstrate logging&lt;br /&gt;#&lt;br /&gt;# author: Martien van den Akker&lt;br /&gt;# (C) march 2010&lt;br /&gt;# Darwin-IT Professionals&lt;br /&gt;###################################################################################################&lt;br /&gt;#Declarations&lt;br /&gt;TRUE=1&lt;br /&gt;FALSE=0&lt;br /&gt;#Logging variables&lt;br /&gt;LOG_ENABLED=$TRUE&lt;br /&gt;#LOG_ENABLED=$FALSE&lt;br /&gt;LOG_DIR=/tmp/log&lt;br /&gt;LOG_FILENAME=$LOG_DIR/routemq.log&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#Check log dir and create it if it does not exist.&lt;br /&gt;check_logdir(){&lt;br /&gt;if [ "$LOG_ENABLED" -eq $TRUE ]; then&lt;br /&gt;if [ -d $LOG_DIR ]; then&lt;br /&gt;#log a seperation line&lt;br /&gt;log&lt;br /&gt;else&lt;br /&gt;mkdir $LOG_DIR&lt;br /&gt;fi&lt;br /&gt;fi&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#Log&lt;br /&gt;log(){&lt;br /&gt;if [ "$LOG_ENABLED" -eq $TRUE ]; then&lt;br /&gt;TEXT="$1 ""$2"&lt;br /&gt;echo $TEXT &gt;&gt;$LOG_FILENAME;&lt;br /&gt;fi&lt;br /&gt;}&lt;br /&gt;# First check logdir&lt;br /&gt;check_logdir&lt;br /&gt;# Log Arguments&lt;br /&gt;&lt;br /&gt;log "Number of arguments: " $#&lt;br /&gt;log "First argument: " $1&lt;br /&gt;log "Second argument: " $1&lt;br /&gt;log "End of script"&lt;/pre&gt;&lt;br /&gt;The script starts with a call to check_logdir(). This function checks if the LOG_DIR exists. If it exists it adds a seperation line. This is because the if has to have a command in the then section. But it is also convenient because you have a seperation line between script calls.&lt;br /&gt;Then there is the log function. The log function accepts two parameters. One is the prompt, the other is a string to be concatenated to the prompt. Handy for listing parameter-values.&lt;br /&gt;But you could also do a logging of only one line. For example the last line.&lt;br /&gt;&lt;br /&gt;The logging can be enabled or disabled by commenting/uncommenting the proper line of:&lt;br /&gt;&lt;pre class="brush: bash"&gt;LOG_ENABLED=$TRUE&lt;br /&gt;#LOG_ENABLED=$FALSE&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-1394636103245157627?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/1394636103245157627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=1394636103245157627' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1394636103245157627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/1394636103245157627'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/04/logging-in-bash-script.html' title='Logging in bash script'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-784702209274336664</id><published>2010-04-01T01:43:00.001-07:00</published><updated>2010-04-01T01:59:24.851-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Generic'/><title type='text'>Outsourcing of server management</title><content type='html'>It's like in the old Cobol days. When you were working at the Automation department of the Dutch Tax office (I got this from past co-workers that were some older than I), you worked in Apeldoorn in the east of the country, but the datacenter was in The Hague in the west. A distance of about 300 km.&lt;br /&gt;&lt;br /&gt;You coded your Cobol on punch cards. And if you were smart then you indexed your lines. You had to do a visual code check. The punch cards were put in a box and sent by courier to the datacenter in The Hague. There the cards were 'loaded' to the mainframe and if you did your visual code checking well it compiled and executed. And then you got your output back by courier.&lt;br /&gt;If the box fell of the cart, you were happy you indexed your code lines. Because then the cards could be fed to a punch-card-sorter.&lt;br /&gt;&lt;br /&gt;That's about how I feel right now. I created a script and developed a postfix configuration. But it has to be put on the Linux development machine by a system manager. Although it's a development-server there are some good reasons to not give me root-priviliges to the development server.&lt;br /&gt;And since postfix runs as root, you have to be root to change the config-files. But because I do not even have a normal user-account I cannot read the logs. The script is put in a non-root-non-postfix-useraccount. But I can't update the script myself.&lt;br /&gt;&lt;br /&gt;So, I have to do a change and now we wait until the feedback. This already goes on for days, a few weeks/months if I include the requests for accounts and initial server setup. And that for something that could be solved in a few hours (if I exclude the requests for accounts and initial server setup), if I could get my own fingers at the keys.&lt;br /&gt;&lt;br /&gt;But so be it. The server management here is not really 'outsourced', but it is at another geographical location. In another city. And done by other people that are also busy with other tasks. They're helpful. They really are. But the overall duration is the price the organization, the customer is paying for these policies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-784702209274336664?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/784702209274336664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=784702209274336664' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/784702209274336664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/784702209274336664'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/04/outsourcing-of-server-management.html' title='Outsourcing of server management'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-4396346958177047313</id><published>2010-03-24T00:21:00.000-07:00</published><updated>2011-03-16T08:08:21.828-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Postfix for handling mail in your integration solution</title><content type='html'>Sometimes there is a need for integrating with mail. You could say: that's easy, since we could use the notification service in BPEL as described &lt;a href="http://darwin-it.blogspot.com/2009/09/process-e-mail-with-oracle-bpel-pm-1012.html"&gt;here&lt;/a&gt;.&lt;br /&gt;However, this solution requires that there is a mail-box to connect to. But what if you want to serve multiple (10s, 100s or even 1000s of) e-mail-addresses within a certain domain? Maybe multiple sub-domains within a certain main-domain? Then you would not want to create seperate mail-boxes for each address. That would give to much of an administration. Not only you have to create new mail-boxes, but also have activation agents for each of this mail-box. That would have an enormous performance pressure. So, what then?&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://darwin-it.blogspot.com/2009/09/process-e-mail-with-oracle-bpel-pm-1012.html"&gt;my previous post on handling email with SoaSuite (BPEL)&lt;/a&gt;, I already mentioned Apache James as an email server. Nearly every Linux distribution also comes with Postfix. Postfix is a Mail Transfer Agent. It's not an e-mail server like James. It handles SMTP-messages. It will listen for SMTP-trafic and filter each message to determine if it has to be passed on to another MTA or to be handled locally. If a message has to be handled locally, it can be stored  to local mailboxes or a local POP or IMAP server, for example. But it is also quite easy to let Postfix call a local script or executable. And that for mail-addresses that meet certain filter rules, like belonging to a domain. This script can then be used to have the message put/enqueued on a queue. The script can also be used to enhance the email messages with properties from the SMTP-envelope. I added that in the example too.&lt;br /&gt;&lt;br /&gt;Now I'm not an e-mail server expert. But I had to figure out how to configure Postfix for this use-case. And although Postfix seem complicated at first sight, this turns out remarkebally easy.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Postfix installation&lt;/span&gt;&lt;br /&gt;I choose Oracle Enterprise Linux 5 Update 4, as an alternative to Red Hat. But about any Linux-taste would do. Provided that it has a Postfix-pacYou might uninstall Sendmail (or unselect it in the package-options on install of the OS). This to prevent collision with the Postfix functionality.&lt;br /&gt;&lt;br /&gt;Although you would do al the configuration as root (postfix runs as root), it is strongly advised to introduce an extra user for the message-handling. To own the scripts, etc.&lt;br /&gt;In my setup the following folders are created:&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; background: rgb(224, 224, 224) none repeat scroll 0% 0%; width: 253.75pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" valign="top" width="134"&gt;   &lt;p class="TableHeading" style=""&gt;&lt;span lang="NL"&gt;Folder&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; background: rgb(224, 224, 224) none repeat scroll 0% 0%; width: 253.75pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" valign="top" width="338"&gt;   &lt;p class="TableHeading" style=""&gt;&lt;span lang="NL"&gt;Meaning&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style=""&gt;   &lt;td style="border-style: none none solid solid; padding: 0cm 5.4pt; width: 100.75pt;" valign="top" width="134"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span lang="NL"&gt;/etc/postfix&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;   &lt;td style="border-style: none solid solid; padding: 0cm 5.4pt; width: 253.75pt;" valign="top" width="338"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style=""&gt;Configuration files and lookup tables&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style=""&gt;   &lt;td style="border-style: none none solid solid; padding: 0cm 5.4pt; width: 100.75pt;" valign="top" width="134"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span lang="NL"&gt;/usr/libexec/postfix&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;   &lt;td style="border-style: none solid solid; padding: 0cm 5.4pt; width: 253.75pt;" valign="top" width="338"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span lang="NL"&gt;Postfix   daemons&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style=""&gt;   &lt;td style="border-style: none none solid solid; padding: 0cm 5.4pt; width: 100.75pt;" valign="top" width="134"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span lang="NL"&gt;/var/spool/postfix&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;   &lt;td style="border-style: none solid solid; padding: 0cm 5.4pt; width: 253.75pt;" valign="top" width="338"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span lang="NL"&gt;Queue files&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style=""&gt;   &lt;td style="border-style: none none solid solid; padding: 0cm 5.4pt; width: 100.75pt;" valign="top" width="134"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span lang="NL"&gt;/usr/sbin&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;   &lt;td style="border-style: none solid solid; padding: 0cm 5.4pt; width: 253.75pt;" valign="top" width="338"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span lang="NL"&gt;Postfix   commands&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;This is a quite common setup, but in other (Linux or Unix) distributions the folder locations might differ slightly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Postfix Usecase&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_myrkQ5dyTYg/S6nIjxi2LCI/AAAAAAAACPI/D2NFQbY-X-I/s1600/PostfixSetup.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 538px; height: 301px;" src="http://1.bp.blogspot.com/_myrkQ5dyTYg/S6nIjxi2LCI/AAAAAAAACPI/D2NFQbY-X-I/s400/PostfixSetup.gif" alt="" id="BLOGGER_PHOTO_ID_5452109340829166626" border="0" /&gt;&lt;/a&gt;This schema provides an overview on how Postfix will work. Left Incoming (smtp) messages will be picked up by the Smtp-deamon. Then via "Cleanup" it will be handed over to the QueueManager, via the incoming queue. The Queuemanager will put the message on the Active queue. From there it will be picked up by either the smtp-service to forward the mail to the smtp-server on the infrastructure of your Internet Service Provider or your company. Using MA-records of the DNS-server it will determine to which  smtp-server it has to be send actually.&lt;br /&gt;In our use-case the pipe deamon is the interesting one. This is the one we're going to instruct to call a script.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Basic Settings&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Hostname&lt;/span&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;hostname&lt;/span&gt; command can be used to determine the fully qualified name. This is the one used by Postfix to determine the host. If this does not include the domain-name then the following command can be used to instruct Postfix what the FQN should be:&lt;br /&gt;&lt;pre class="brush: plain"&gt;postconf -e myhostname=vmsmtp.darwin-it.local&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Mydestination&lt;/i&gt;&lt;br /&gt;This parameter can be left default. But if mail have to be accepted for certain domains and to be delivered using the local transport, set the following parameter in main.cf:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: plain"&gt;# 2010-02-03, M. vd. Akker: To have mail accepted for .darwin-it.local&lt;br /&gt;mydestination = $myhostname, localhost.$mydomain, localhost, .darwin-it.local&lt;/pre&gt;&lt;br /&gt;For now leave it default:&lt;br /&gt;&lt;pre class="brush: plain"&gt;mydestination = $myhostname, localhost.$mydomain, localhost&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Network interfaces&lt;/i&gt;&lt;br /&gt;To have mail from external networks, non-localhost, the inet_interfaces must be set in main.cf. In my case I run Postfix within a Virtual Machine. And I want to use my Thunderbird to send mail to Postfix. So first Postfix has to be told from which network-devices it should accept mail from. Since my VM is "hidden", for simplicity we accept mail from all network devices. But this can be narrowed down.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: plain"&gt;# RECEIVING MAIL&lt;br /&gt;&lt;br /&gt;# The inet_interfaces parameter specifies the network interface&lt;br /&gt;# addresses that this mail system receives mail on.  By default,&lt;br /&gt;# the software claims all active interfaces on the machine. The&lt;br /&gt;# parameter also controls delivery of mail to user@[ip.address].&lt;br /&gt;#&lt;br /&gt;# See also the proxy_interfaces parameter, for network addresses that&lt;br /&gt;# are forwarded to us via a proxy or network address translator.&lt;br /&gt;#&lt;br /&gt;# Note: you need to stop/start Postfix when this parameter changes.&lt;br /&gt;#&lt;br /&gt;# 2010-02-10, M. van den Akker: Setup all interfaces for excepting mail.&lt;br /&gt;inet_interfaces = all&lt;br /&gt;#inet_interfaces = $myhostname&lt;br /&gt;#inet_interfaces = $myhostname, localhost&lt;br /&gt;#inet_interfaces = localhost&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Specific domains to accept mail from are set with mynetworks parameters. To select sub-domains to accept mail from, change the mynetwork parameter to accept mail from your host for example.&lt;br /&gt;&lt;pre class="brush: plain"&gt;# TRUST AND RELAY CONTROL&lt;br /&gt;&lt;br /&gt;# The mynetworks parameter specifies the list of "trusted" SMTP&lt;br /&gt;# clients that have more privileges than "strangers".&lt;br /&gt;#&lt;br /&gt;# In particular, "trusted" SMTP clients are allowed to relay mail&lt;br /&gt;# through Postfix.  See the smtpd_recipient_restrictions parameter&lt;br /&gt;# in postconf(5).&lt;br /&gt;#&lt;br /&gt;# You can specify the list of "trusted" network addresses by hand&lt;br /&gt;# or you can let Postfix do it for you (which is the default).&lt;br /&gt;#&lt;br /&gt;# By default (mynetworks_style = subnet), Postfix "trusts" SMTP&lt;br /&gt;# clients in the same IP subnetworks as the local machine.&lt;br /&gt;# On Linux, this does works correctly only with interfaces specified&lt;br /&gt;# with the "ifconfig" command.&lt;br /&gt;#&lt;br /&gt;# Specify "mynetworks_style = class" when Postfix should "trust" SMTP&lt;br /&gt;# clients in the same IP class A/B/C networks as the local machine.&lt;br /&gt;# Don't do this with a dialup site - it would cause Postfix to "trust"&lt;br /&gt;# your entire provider's network.  Instead, specify an explicit&lt;br /&gt;# mynetworks list by hand, as described below.&lt;br /&gt;#&lt;br /&gt;# Specify "mynetworks_style = host" when Postfix should "trust"&lt;br /&gt;# only the local machine.&lt;br /&gt;#&lt;br /&gt;#mynetworks_style = class&lt;br /&gt;#mynetworks_style = subnet&lt;br /&gt;#mynetworks_style = host&lt;br /&gt;&lt;br /&gt;# Alternatively, you can specify the mynetworks list by hand, in&lt;br /&gt;# which case Postfix ignores the mynetworks_style setting.&lt;br /&gt;#&lt;br /&gt;# Specify an explicit list of network/netmask patterns, where the&lt;br /&gt;# mask specifies the number of bits in the network part of a host&lt;br /&gt;# address.&lt;br /&gt;#&lt;br /&gt;# You can also specify the absolute pathname of a pattern file instead&lt;br /&gt;# of listing the patterns here. Specify type:table for table-based lookups&lt;br /&gt;# (the value on the table right-hand side is not used).&lt;br /&gt;#&lt;br /&gt;# 2010-02-10, M. van den Akker: Setup for accepting mail from CMI and localhost.&lt;br /&gt;mynetworks = &lt;span style="font-weight: bold;"&gt;192.168.192.0/28&lt;/span&gt;, 127.0.0.0/8&lt;br /&gt;#mynetworks = 168.100.189.0/28, 127.0.0.0/8&lt;br /&gt;#mynetworks = $config_directory/mynetworks&lt;br /&gt;#mynetworks = hash:/etc/postfix/network_table&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Where  &lt;span style="font-weight: bold;"&gt;192.168.192.0/28&lt;/span&gt; should be replaced by the address-range of the host(s) from which you want to be able to receive email.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Start and stop postfix&lt;/b&gt;&lt;br /&gt;Postfix can be stopped by:&lt;br /&gt;&lt;pre class="brush: plain"&gt;[root@vmsmtpserver postfix]# postfix stop&lt;/pre&gt;Postfix can be started by:&lt;br /&gt;&lt;pre class="brush: plain"&gt;[root@vmsmtpserver postfix]# postfix start&lt;/pre&gt;If it’s not already running.&lt;br /&gt;&lt;br /&gt;After making changes to the configuration, Postfix has to be told to reload the configuration:&lt;br /&gt;&lt;pre class="brush: plain"&gt;[root@vmsmtpserver postfix]# postfix reload&lt;br /&gt;postfix/postfix-script: refreshing the Postfix mail system&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Incoming e-Mail&lt;/span&gt;&lt;br /&gt;Postfix will have to be configured that *.darwin-it.local will be seen as a domain for virtual mailbox addresses. The virtual transport has to be configured that these messages are handled by the pipe-deamon to call an external script.&lt;br /&gt;&lt;br /&gt;We'll instruct Postfix also to enrich the smtp-message with two Custom properties:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;x-envelope-to: Recipient list from the SMTP-Header&lt;/li&gt;&lt;li&gt;x-envelope-from: From-email-addres from the SMTP Header&lt;/li&gt;&lt;/ul&gt;Actually we implement the enrichment in the script. But Postfix will pass these properties as parameters.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Create a transport&lt;/span&gt;&lt;br /&gt;To have incoming mail for .darwin-it.local transported to the script, a new transport has to be configured.&lt;br /&gt;&lt;br /&gt;This is done in the master.cf file:&lt;br /&gt;&lt;pre class="brush: plain"&gt;# 2010-02-10, M. van den Akker: Setup transport routescript for passing message to a bash-script&lt;br /&gt;routescript   unix  -       n       n       -       -       pipe&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;flags&lt;/span&gt;=FDq. &lt;span style="font-weight: bold;"&gt;user&lt;/span&gt;=smtpuser &lt;span style="font-weight: bold;"&gt;argv&lt;/span&gt;=/bin/bash -c /home/smtpuser/routescript.sh -&lt;span style="font-weight: bold;"&gt;s&lt;/span&gt; $sender -&lt;span style="font-weight: bold;"&gt;r&lt;/span&gt; $recipient -&lt;span style="font-weight: bold;"&gt;q&lt;/span&gt; $nexthop -&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here a new transport is created, named “routescript”. It refers to the “pipe” deamon.&lt;br /&gt;&lt;br /&gt;The “flags=FDq” denote that the From and destination addresses  from the header are added to the header.&lt;br /&gt;Change the following if necessary:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The &lt;span style="font-weight: bold;"&gt;user &lt;/span&gt;denotes the unix-user that is used to run the script. In this case the unix-user “smtpuser” is used. Change it to the proper user (other than “root” or “postfix” ) .&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;argv&lt;/span&gt;: denotes in this case that a bash script is called. Bash is called to run the routescript.sh script, that is placed in the home folder of the smtpuser. Change the path according to the correct location of the given script.&lt;/li&gt;&lt;li&gt;The next parameters are parameters for the routemq.sh script:&lt;ul&gt;&lt;li&gt;-&lt;span style="font-weight: bold;"&gt;s&lt;/span&gt;: the sender of the message, $sender refers to the from-address on the smtp-envelope&lt;/li&gt;&lt;li&gt;-&lt;span style="font-weight: bold;"&gt;r&lt;/span&gt;: the recipient(s) of the message, $recipient refers to the to-list on the smtp-envelope&lt;/li&gt;&lt;li&gt;-&lt;span style="font-weight: bold;"&gt;q&lt;/span&gt;: the queue on which the message has to be put. Our script was designed to queue the message on IBM mq. The property $nexthop refers to the nexthop property in the transport map. Having used this parameter to denote the particular queue enables us to change only the transport map if a queue is changed. Or reuse this transport for different queues in different transport mappings. This is a nice way to pass info about the actual/technical transport channel to be used.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Create transport map&lt;/span&gt;&lt;br /&gt;To route the '.darwin-it.local' domain to the script a transport map has to be made in the transport file.&lt;br /&gt;&lt;br /&gt;Add the following line to the transport map file:&lt;br /&gt;&lt;pre class="brush: plain"&gt;# 2010-02-10, M. van den Akker: Setup transport routescript for handling darwin-it.local-messages.&lt;br /&gt;.darwin-it.local routescript:&lt;span style="font-weight: bold;"&gt;queuename&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Where &lt;span style="font-weight: bold;"&gt;queuename&lt;/span&gt; is the queue that is used for the smtp-messages. This is the 'nexthop'-parameter where the $nexthop property in the master.cf refers to.&lt;br /&gt;&lt;br /&gt;After having changed the transport map file, it has to be compiled into an indexed binary using the postmap tool. So execute the following command:&lt;br /&gt;&lt;pre class="brush: plain"&gt;[root@vmsmtpserver postfix]# postmap transport&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Define transport map&lt;/span&gt;&lt;br /&gt;To have the transport map used by Postfix, add the following lines to the main.cf :&lt;br /&gt;&lt;pre class="brush: plain"&gt;# 2010-02-10, M. van den Akker: use transport map&lt;br /&gt;transport_maps=hash:/etc/postfix/transport&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Routescript&lt;/span&gt;&lt;br /&gt;Make sure that the routescript.sh as given in the appendix is placed on the location as defined in the master.cf above. In the example above it is: /home/smtpuser/routescript.sh&lt;br /&gt;Make it owned by the user that is used by Postfix to execute the script (smtpuser).&lt;br /&gt;Then make the script executable:&lt;br /&gt;&lt;pre class="brush: plain"&gt;[smtpuser@vmsmtpserver postfix]$ chmod +x routescript.sh&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The actual script as an example is given at the end of this article.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Outgoing e-Mail&lt;/span&gt;&lt;br /&gt;All outgoing e-mail should be forwarded to your companies or ISP's smpt-infrastructure.&lt;br /&gt;&lt;br /&gt;To do so set the relay-host parameter to the particular smtp-server in main.cf:&lt;br /&gt;&lt;pre class="brush: plain"&gt;# INTERNET OR INTRANET&lt;br /&gt;&lt;br /&gt;# The relayhost parameter specifies the default host to send mail to&lt;br /&gt;# when no entry is matched in the optional transport(5) table. When&lt;br /&gt;# no relayhost is given, mail is routed directly to the destination.&lt;br /&gt;#&lt;br /&gt;# On an intranet, specify the organizational domain name. If your&lt;br /&gt;# internal DNS uses no MX records, specify the name of the intranet&lt;br /&gt;# gateway host instead.&lt;br /&gt;#&lt;br /&gt;# In the case of SMTP, specify a domain, host, host:port, [host]:port,&lt;br /&gt;# [address] or [address]:port; the form [host] turns off MX lookups.&lt;br /&gt;#&lt;br /&gt;# If you're connected via UUCP, see also the default_transport parameter.&lt;br /&gt;#&lt;br /&gt;#relayhost = $mydomain&lt;br /&gt;#relayhost = [gateway.my.domain]&lt;br /&gt;#relayhost = [mailserver.isp.tld]&lt;br /&gt;#relayhost = uucphost&lt;br /&gt;#relayhost = [an.ip.add.ress]&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Restart Postfix&lt;/span&gt;&lt;br /&gt;After having made the necessary changes above it is important to restart (stop and sart) Postfix. Just doing a reload of the config will probably not suffice.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;It took me some time to understand Postfix. I was quite overwhelmed by the options. And it took me some time to figure out how to configure it for this particular usecase. Where I had to consult a co-worker (the one that sort of made up this use-case; thanks to Hugo). But as with most other things: after all it turns out to be  simple. And it might be useful for many other cases.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Appendix: the routescript.sh&lt;/span&gt;&lt;br /&gt;Below the script is given to be called by Postfix to route the messages. This script is designed to either output the message to a file or to an IBM mq client. The mq-client has to be installed from a licensed installment of IBM. IBM also provides the &lt;a href="http://www-01.ibm.com/support/docview.wss?rs=171&amp;amp;uid=swg24000647"&gt;MA01-support pack&lt;/a&gt;, in which for several OS'es an compiled executable is provided. This executable (simply called 'q') provides a commandline interface to the IBM mq-client.  The mq-client can put the message to a queue, but also to standard out. This is handy for testing, where no mq-client is available.&lt;br /&gt;&lt;br /&gt;There are 2 lines to edit:&lt;br /&gt;• &lt;span style="font-weight: bold;"&gt;Q=~/bin/ma01/q&lt;/span&gt; : give here the proper path the q-executable from the MA01-support pack&lt;br /&gt;• &lt;span style="font-weight: bold;"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;fi|"$Q" -O "$QUEUE_NAME&lt;/span&gt;"&lt;/span&gt; : here the output of the if-block is outputted to the q-client using the queue-name. If the queue is not available in test-environment this will give an error. For test purposes it might be usefull to comment this line use (uncomment) either the line '&lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;#fi|"$Q" -s&lt;/span&gt;' to have the q-client output the message to STDOUT, or '&lt;span style="font-weight: bold; color: rgb(51, 102, 255);"&gt;#fi&gt;$FILENAME&lt;/span&gt;' to have the output directed to file.&lt;br /&gt;&lt;br /&gt;The script will exit with the result code of the last command, which is the q-client. If that one fails, the script with exit with the result-code telling Postfix to consider the call failed. Postfix will consider the message undelivered and retry it later.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;#!/bin/bash&lt;br /&gt;###################################################################################################&lt;br /&gt;# Route messages.&lt;br /&gt;# Script to route an email message, read from pipe and output it to a channel.&lt;br /&gt;#&lt;br /&gt;# author: Martien van den Akker&lt;br /&gt;# (C) januari 2010&lt;br /&gt;# Darwin-IT Professionals&lt;br /&gt;###################################################################################################&lt;br /&gt;#Declartions&lt;br /&gt;E_WRONG_ARGS=85;&lt;br /&gt;NUMBER_OF_EXPECTED_ARGS=6;&lt;br /&gt;FILENAME=/tmp/routemq-`date +%Y%m%d-%H%M%S.%N`&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Q=~/bin/ma01/q&lt;/span&gt;&lt;br /&gt;TRUE=1&lt;br /&gt;HDR_ENV_FROM="x-envelope-from"&lt;br /&gt;HDR_ENV_TO="x-envelope-to"&lt;br /&gt;&lt;br /&gt;#Function to display usage&lt;br /&gt;usage(){&lt;br /&gt;SCRIPT_PARAMETERS="-r receiver -s sender -q queuename";&lt;br /&gt;USAGE="Usage: `basename $0` $SCRIPT_PARAMETERS";&lt;br /&gt;echo $USAGE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# Check Arguments&lt;br /&gt;if [ $# -lt $NUMBER_OF_EXPECTED_ARGS ]&lt;br /&gt;then&lt;br /&gt;usage&lt;br /&gt;exit $E_WRONG_ARGS;&lt;br /&gt;fi&lt;br /&gt;until [ -z "$1" ]&lt;br /&gt;do&lt;br /&gt;case $1 in&lt;br /&gt;"-s") SENDER=$2;;&lt;br /&gt;"-r") RECEIVER=$2;;&lt;br /&gt;"-q") QUEUE_NAME=$2;;&lt;br /&gt;* ) usage;&lt;br /&gt;exit $E_WRONG_ARGS;;&lt;br /&gt;esac;&lt;br /&gt;shift 2;&lt;br /&gt;done;&lt;br /&gt;&lt;br /&gt;#echo header variables and cat stdin to output.&lt;br /&gt;#Edit next line to give the proper full path to the “q”-executable from the MA01-support-pack&lt;br /&gt;if [ "$TRUE" ]&lt;br /&gt;then&lt;br /&gt;echo "$HDR_ENV_FROM: $SENDER"&lt;br /&gt;echo "$HDR_ENV_TO: $RECEIVER"&lt;br /&gt;cat -&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;fi|"$Q"  -O "$QUEUE_NAME"&lt;/span&gt; #  uncomment to output to $QUEUENAME (Comment previous line)&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;#fi|"$Q" -s&lt;/span&gt; # only output to stdout&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;#fi&gt;$FILENAME&lt;/span&gt; #uncomment to output to filename&lt;br /&gt;&lt;br /&gt;exit $? #Exit with result-code of last command, which is the "q" command.&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-4396346958177047313?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/4396346958177047313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=4396346958177047313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4396346958177047313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4396346958177047313'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/03/postfix-for-handling-mail-in-your.html' title='Postfix for handling mail in your integration solution'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_myrkQ5dyTYg/S6nIjxi2LCI/AAAAAAAACPI/D2NFQbY-X-I/s72-c/PostfixSetup.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-29169744639118709</id><published>2010-03-10T00:23:00.001-08:00</published><updated>2010-03-10T00:45:04.634-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Apache James on IBM AIX</title><content type='html'>Apache James is a very nice e-mail server to be used in a development or test environment, where you need to integrate with an email system. I mentioned it in an earlier post. It supports smtp, pop, nntp (news) and imap.&lt;br /&gt;It's installation is as simple as can be: just unzip the tool, set your JAVA_HOME environment variable and run the appropriate run.sh or run.bat script (given your OS being either Unix/Linux or Windows).  The only thing you need besides the zip is a Java Runtime Environment that is at least of version 1.4.2.&lt;br /&gt;&lt;br /&gt;For most systems this is all you have to do to get it running.  But I found that on IBM AIX (5.x) it is a little less obvious. Getting it running is not an issue, but as soon as you want to add a user, you'll run into the error:&lt;br /&gt;&lt;pre&gt;Exception: Security error: java.security.NoSuchAlgorithmException: SHA MessageDigest not available&lt;/pre&gt;And after that the telnet connection is closed.&lt;br /&gt;It turns out that the security-provider packages are not registered properly. To get it right there are two things to do.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Make sure that the JAVA_HOME is pointing to the jre folder in the root folder of the java-installment on your system. So like: /usr/java5_64/jre instead of /usr/java5_64. Also make sure that there is a lib/ext folder (/usr/java5_64/jre/lib/ext) that contains a &amp;lt;make&amp;gt;jceprovider.jar, eg. sunjce_provider.jar or ibmjceprovider.jar.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Change &amp;lt;james-home&amp;gt;/bin/phoenix.sh to register the extensions:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;Find the line:&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;JVM_EXT_DIRS="$PHOENIX_HOME/lib:$PHOENIX_HOME/tools/lib"&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Change it to:&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;JVM_EXT_DIRS="$PHOENIX_HOME/lib:$JAVA_HOME/lib/ext:$PHOENIX_HOME/tools/lib"&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now james can be started using the run.sh/run.bat scripts and using the telnet console you should be able to succesfully add users.&lt;br /&gt;&lt;br /&gt;It might be that on your system, the system administrators block port 25(smtp) and 110 (pop). That would prevent james to startup the smtp and pop services.&lt;br /&gt;In the &amp;lt;james-home&amp;gt;/apps/james/SAR-INF/ there is a config.xml file. In that file you can find a line:&lt;br /&gt;&lt;pre&gt;&amp;lt;pop3server enabled="true"&amp;gt;&lt;/pre&gt;&lt;br /&gt;There you can choose to disable pop by changing the enabled attribute. But benaath that line there is a port element. You could change that instead to for example 8110. That would enable pop-support on the 8110 port. You should instruct your client to use that port off course.&lt;br /&gt;The same counts for smtp-support. That can be found at:&lt;br /&gt;&lt;pre&gt;&amp;lt;smtpserver enabled="true"&amp;gt;&lt;/pre&gt;&lt;br /&gt;For smtp you could choose to set the port to 8025.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-29169744639118709?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/29169744639118709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=29169744639118709' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/29169744639118709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/29169744639118709'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/03/apache-james-on-ibm-aix.html' title='Apache James on IBM AIX'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-7459689112672148264</id><published>2010-01-28T01:14:00.000-08:00</published><updated>2010-01-28T07:21:34.572-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Generic'/><title type='text'>Oracle Sun now definitely one team</title><content type='html'>Today I read the news that the European Commity approved the Sun acquisition without further demands. See &lt;a href="http://webwereld.nl/nieuws/64989/oracle-plant-een-webversie-van-openoffice.html#source=head"&gt;webwereld.nl&lt;/a&gt;. Actually it is already a week ago. But today I read also the plans of a Web Open Office, or Open Web Office. Or Open Cloud Office. An alternative of Google's Docs. I'm very curious how that would look like and how it will compare to Google Docs. Open Office is a fairly mature Office Suite. So I'm looking forward to see which OpenOffice features will find their way in to the Oracle Cloud.&lt;br /&gt;&lt;br /&gt;Further more the clouds are cleared upon MySql.&lt;br /&gt;&lt;br /&gt;Another interesting statement I found was that Java SE should support more languages. Probably as an answer to the .Net world where you can develop in multiple languages. So lots of promisses that makes it interesting to "keep an eye in the sail" with Oracle (famous Dutch saying).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-7459689112672148264?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/7459689112672148264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=7459689112672148264' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7459689112672148264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7459689112672148264'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/01/oracle-sun-now-definately-one-team.html' title='Oracle Sun now definitely one team'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-8381087833343743919</id><published>2010-01-18T06:38:00.000-08:00</published><updated>2011-03-16T08:10:12.461-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Application Server'/><title type='text'>Application Server Connection in JDeveloper 10.1.3.x</title><content type='html'>This is actually a tip from the dusty old box, although I imagine that there are still people around with SoaSuite/Jdeveloper 10g. I got a VMware image with SoaSuite10133. And I couldn't connect to it with JDeveloper from outside the VM. And I should have the solution somewhere but I couldn't reproduce it. The solution lies in the opmn.xml found in $ORACLE_HOME/opmn/conf.&lt;br /&gt;&lt;br /&gt;There you'll find a notification-server element. It propbably does not have the ipaddr node below it by default. But add it like below with 0.0.0.0 as ip-addresses. Doing so enables you to connect with a jdeveloper on a remote machine.&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;notification-server inter&amp;gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);font-family:ipv4;"&gt;&amp;lt;ipaddr remote="0.0.0.0" request="0.0.0.0"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;port local="6100" remote="6200" request="6003"/&amp;gt;&lt;br /&gt;&amp;lt;ssl enabled="true" wallet-file="$ORACLE_HOME/opmn/conf/ssl.wlt/default"/&amp;gt;&lt;br /&gt;&amp;lt;/notification-server&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I wrote about connecting to an Oracle Application Server/SoaSuite within a VM in greater detail &lt;a href="http://darwin-it.blogspot.com/2008/02/soasuite-in-vmware.html"&gt;here&lt;/a&gt;, but I did not include the actual opmn.xml snippet like above.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-8381087833343743919?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/8381087833343743919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=8381087833343743919' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8381087833343743919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8381087833343743919'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/01/application-server-connection-in.html' title='Application Server Connection in JDeveloper 10.1.3.x'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-6315431906150144511</id><published>2010-01-15T00:07:00.001-08:00</published><updated>2011-04-06T00:58:16.765-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><title type='text'>It's back: the Business Event System</title><content type='html'>My first steps on integration were on Oracle AQ (from Oracle 8i onwards) and Oracle Workflow Standalone 2.6.x. One of my big dissapointments were that from Oracle 10g AS and DB, Oracle Workflow is desupported. You may use it as long as the 10g licenses last (either for database or AS). But then it is End of Life time. In 11g Oracle Workflow is not delivered anymore. And that is quite a pity, since it was quite a good Workflow tool, especially for datasbase centric applications. The nice thing is that it recides and runs completely in the database. Also it has a pretty good Eventing system. You can define events on a web-based UI. Then you can subscribe Oracle Workflow processes, Java-classes or pl/sql rule-functions on an event.&lt;br /&gt;&lt;br /&gt;The good thing about business events is that you can make applications really independend from each other. If you have  an application and you need that something happens if a certain mutation in your application is done, for example on creation of an order, the order should be interfaced to another application or logged, then you would create a function call in a database trigger, or from your ADF-BC entity-object. The side-affect is that if your called-functionality is invalid, not available or gives errors, then your calling-application would not work.  Also if it is a long running process that is called, than it will all happen in the session of the end-user, who must wait until all processing is done.&lt;br /&gt;&lt;br /&gt;And that all is wrong. The calling application should only notify an infrastructure component (like a business event system) and should not care about what is done with this notification. Doing so the end-user get's his sesson back immediately. The application won't disfunction because of corrupted subscribing applications. The application has done what it's responsible for.&lt;br /&gt;&lt;br /&gt;The business event system then will handle all the subscriptions in the back-ground. And handle all errors, throw them to an error hospital for example.&lt;br /&gt;&lt;br /&gt;But unfortunately the Oracle Workflow Business Event System is no more. Although it is still available in Oracle's E-Business Suite. But that is quite large to install for only BES. EBS is leaning heavily on BES, since most mutations on EBS entities have Events defined on which as an EBS-developer you can subscribe your custom-code. Even if there is no Event available for what you need to do, you shouldn't code it directly on a trigger, but let a database trigger raise your newly defined custom event. And subscribe your code on that event.&lt;br /&gt;&lt;br /&gt;This week I delivered the OPN Bootcamp on SoaSuite11g. It was very nice and I'm looking forward to the &lt;a href="http://www.darwin-it.nl/diensten/trainen/oracle-partner-network-opn-delivery-partner/"&gt;next to come&lt;/a&gt; (9-11th february in Belgium). There's already written a lot on SoaSuite 11g, but little on the comeback of BES: the &lt;span style="font-weight: bold;"&gt;Event Delivery Network.&lt;/span&gt;&lt;br /&gt;Although I like the SCA/Composite. Although I like the integration of all components. But if I must choose, I would pronounce the EDN as the most interesting and promissing addition.&lt;br /&gt;&lt;br /&gt;In the OPN Bootcamp there is a small chapter with a little lab to smell just a little on EDN. See also the chapter in "&lt;a href="http://www.packtpub.com/article/event-delivery-network-oracle-soa-suite-11g-R1"&gt;Getting Started with SoaSuite11g&lt;/a&gt;". A larger explanation is found &lt;a href="http://download.oracle.com/docs/cd/E12839_01/integration.1111/e10224/obe_intro.htm"&gt;here&lt;/a&gt;. And &lt;a href="http://download.oracle.com/docs/cd/E15523_01/integration.1111/e10226/busevent_mang.htm#BABFEFJC"&gt;here&lt;/a&gt; you can read about the managing of EDN.&lt;br /&gt;&lt;br /&gt;Raising/publishing an event from a mediator is really easy. Just a few clicks. Also subscribing on a event is just a few clicks away. Also you can raise/publish events from ADF-BC or from Java. But what I miss is an explanation on how to raise an event from Pl/Sql. It is mentioned that it is possible. And in the managing-guide, you'll see how you can create database-agents. But I have to find out how to do it from Pl/Sql. I'll post it when I've found out the how-to.&lt;br /&gt;&lt;br /&gt;I've great expectations on EDN. I hope and expect that Oracle will expand the useability further more with enabling other technologies to be able to publish and subscribe to events, the propagation of events to remote systems over WANs, etc. I think they'll do because they need a good Event System when for example BPEL and/or BPM is to replace Oracle Workflow in E-Business Suite.&lt;br /&gt;&lt;br /&gt;But we as SOA/EDA consultants have to train Business Analists to think in events. EDN is targetted to the Business. So they have to embrace the concept of events.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-6315431906150144511?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/6315431906150144511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=6315431906150144511' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6315431906150144511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6315431906150144511'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/01/its-back-business-event-system.html' title='It&apos;s back: the Business Event System'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-7163934591009740641</id><published>2010-01-06T07:04:00.000-08:00</published><updated>2010-01-06T07:12:55.918-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BPEL PM'/><title type='text'>Failed to compile the generated BPEL classes</title><content type='html'>Today I ran in a weird problem, one moment I could compile my bpel process, a minor change later I couldn't.  I got the very descriptive error (not):&lt;br /&gt;&lt;pre&gt;Error: Failed to compile classes. Failed to compile the generated BPEL classes for %process-name%.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;After a little trial and error I ran a expression in a while loop:&lt;br /&gt;&lt;pre&gt;condition="bpws:getVariableData('EKDSuccess')=&lt;span style="font-weight: bold;"&gt;&amp;amp;quot;false&amp;amp;quot;&lt;/span&gt; and bpws:getVariableData('EKDTryCount')&amp;lt;=bpws:getVariableData('EKDMaxRetries')" &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It turned out to be the quotes around the word "false". I changed them to single-quotes, like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;condition="bpws:getVariableData('EKDSuccess')='false' and bpws:getVariableData('EKDTryCount')&amp;lt;=bpws:getVariableData('EKDMaxRetries')"&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And then it compiled. It was in 10.1.2 (old I know). So maybe in 10.1.3.x it is solved.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-7163934591009740641?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/7163934591009740641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=7163934591009740641' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7163934591009740641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/7163934591009740641'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/01/failed-to-compile-generated-bpel.html' title='Failed to compile the generated BPEL classes'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-8952047368731706414</id><published>2010-01-04T23:28:00.000-08:00</published><updated>2011-04-06T00:39:47.486-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='BPEL PM'/><title type='text'>Passing parameters to an XSLT in BPEL</title><content type='html'>Yesterday for me it became handy to be able to pass parameters to an XSLT in BPEL. I've seen the need earlier, but solved it a different way. By setting the target element with a default and then over writing that default in a later assign-copy step.&lt;br /&gt;&lt;br /&gt;But yesterday I had to transform a document a variable number of times, for a list of elements. In my case I had a document with a list of recipients and I had to transform that to another document for each recipient. Each recipient had a number of elements with personal and address information that had to be transformed to the target. So simply defaulting and overwriting would not work, or was a lot of work.&lt;br /&gt;&lt;br /&gt;To pass parameters as arguments to a XSLT is quite easy and neatly described in several blogs, amongst others in &lt;a href="http://blogs.oracle.com/sdhurjati/2009/04/passing_parameters_to_xslt_fil.html"&gt;Sudheer Dhurjati's Blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In my case I had to pass an index to be able to select the particular recipient that I need to transform. And another parameter that holds a number of documents that is determined from another source:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;&lt;br /&gt;&amp;lt;parameters xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;xsi:schemaLocation="http://schemas.oracle.com/service/bpel/common /S:/DEV/Sources/BPEL/Processes/CRMI_COM_VersturenBerichtContactMgt/1.0/src/xsltparameters.xsd"&lt;br /&gt;xmlns="http://schemas.oracle.com/service/bpel/common"&amp;gt;&lt;br /&gt;&amp;lt;item&amp;gt;&lt;br /&gt;&amp;lt;name&amp;gt;AantalBijlagen&amp;lt;/name&amp;gt;&lt;br /&gt;&amp;lt;value&amp;gt;2&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&amp;lt;item&amp;gt;&lt;br /&gt;&amp;lt;name&amp;gt;OntvangerIndex&amp;lt;/name&amp;gt;&lt;br /&gt;&amp;lt;value&amp;gt;1&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;lt;/item&amp;gt;&lt;br /&gt;&amp;lt;/parameters&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;In Sudheer's blog (and in other examples) the parameters are initialized by copying an XML fragment with the particular parameters.  If you have to change one of the parameters this could be done by doing an indexed xpath-expression in the &amp;lt;to&amp;gt; of the assign step:&lt;br /&gt;[/prm:parameters/prm:item[prm:name='OntvangerIndex']/prm:value]&lt;br /&gt;with [http://schemas.oracle.com/service/bpel/common] as [prm]&lt;br /&gt;&amp;lt;value xmlns="http://schemas.oracle.com/service/bpel/common"&amp;gt;1&amp;lt;/value&amp;gt;&lt;br /&gt;&lt;br /&gt;But for flexibilities sake, I would propose a slightly different approach. And for that I need an adapted version of the XSD:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="windows-1252" ?&amp;gt;&lt;br /&gt;&amp;lt;xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&lt;br /&gt;xmlns:bplcmn="http://schemas.oracle.com/service/bpel/common"&lt;br /&gt;xmlns="http://schemas.oracle.com/service/bpel/common"&lt;br /&gt;targetNamespace="http://schemas.oracle.com/service/bpel/common"&lt;br /&gt;elementFormDefault="qualified"&amp;gt;&lt;br /&gt;&amp;lt;xsd:element name="parameters"&amp;gt;&lt;br /&gt;&amp;lt;xsd:complexType&amp;gt;&lt;br /&gt;&amp;lt;xsd:sequence&amp;gt;&lt;br /&gt;&amp;lt;xsd:element ref="bplcmn:item" minOccurs="1" maxOccurs="unbounded"/&amp;gt;&lt;br /&gt;&amp;lt;/xsd:sequence&amp;gt;&lt;br /&gt;&amp;lt;/xsd:complexType&amp;gt;&lt;br /&gt;&amp;lt;/xsd:element&amp;gt;&lt;br /&gt;&amp;lt;xsd:element name="item" type="bplcmn:itemType"/&amp;gt;&lt;br /&gt;&amp;lt;xsd:complexType name="itemType"&amp;gt;&lt;br /&gt;&amp;lt;xsd:sequence&amp;gt;&lt;br /&gt;&amp;lt;xsd:element name="name" type="xsd:string"/&amp;gt;&lt;br /&gt;&amp;lt;xsd:element name="value" type="xsd:string"/&amp;gt;&lt;br /&gt;&amp;lt;/xsd:sequence&amp;gt;&lt;br /&gt;&amp;lt;/xsd:complexType&amp;gt;&lt;br /&gt;&amp;lt;/xsd:schema&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this XSD I created 'item' as a seperate element based on a seperated (named) complex-type. I'm actually not so fond of nested complex-types, because it prevents you from using elements lower in the hierarchy for seperate variables.&lt;br /&gt;Using this XSD, you can create a seperate item-variable, based on the item-element.&lt;br /&gt;This is item-variable can be filled with a name and value, just by copying to the particular elements.&lt;br /&gt;The item variable has then to be added to the parameters node using the addChildNode function:&lt;br /&gt;&lt;pre class="brush: xml"&gt;ora:addChildNode(bpws:getVariableData('XsltParams','/bplcmn:parameters'),bpws:getVariableData('item','/bplcmn:item'))&lt;/pre&gt;The first argument of the addChildNode function denotes the element under which you want to add a child. In the expression above this is the 'parameters' element in the XsltParams variable. The second argument is the node you want to add as a child, in this case the 'item'-variable. Of course this expression is the &amp;lt;from&amp;gt;-expression in the copy-rule of the assignment step. The &amp;lt;to&amp;gt; will be most of the times the parent element used in the addChildNode expression:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;to variable="XsltParams" query="/bplcmn:parameters"/&amp;gt;&lt;/pre&gt;I found the description of the addChildNode function in the expression builder not so clear. So this might also be helpfull for other situations where you have to build up a node structure dynamically.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-8952047368731706414?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/8952047368731706414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=8952047368731706414' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8952047368731706414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8952047368731706414'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2010/01/passing-parameters-to-xslt-in-bpel.html' title='Passing parameters to an XSLT in BPEL'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-5822545023421380141</id><published>2009-12-22T01:31:00.000-08:00</published><updated>2009-12-22T02:00:09.368-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='JDeveloper'/><title type='text'>JDeveloper 11g and SoaSuite 11g: a tight combination</title><content type='html'>I remember the first release of BPEL Process Manager in the Oracle Application Server architecture. It was 10.1.2. Before that there was a first global available version (I believe it was called version 2.0). The 10.1.2 release came with a developer install with a very specific version of JDeveloper with the BPEL designer. From 10.1.3 and onwards, the SoaSuite (BPEL,ESB) designers were add-ons. The idea was that with every JDeveloper you could perform SoaSuite-development. But the advice to keep up the JDeveloper version with the SoaSuite version was kept (use JDeveloper 10.1.3.5 with SoaSuite 10.1.3.5).&lt;br /&gt;&lt;br /&gt;This week I started preparing the OPN Bootcamp on SoaSuite 11g, that I'm to give in january (from 12th to 14th in De Meern, The Netherlands, see &lt;a href="http://www.darwin-it.nl/diensten/trainen/oracle-partner-network-opn-delivery-partner/"&gt;here&lt;/a&gt;). I got a prepared Virtual Machine with SoaSuite 11g installed. But it is a one-cpu 2GB VM (that I could give it more memory of course), and I would like to have my sources outside the VM. So for performance and development convenience I choose to install a seperate JDeveloper.&lt;br /&gt;&lt;br /&gt;Of course I went for the latest version (11.1.1.2, downloaded &lt;a href="http://www.oracle.com/technology/software/products/jdev/htdocs/soft11.html"&gt;here&lt;/a&gt;). But I got connection failures at configuring the Application Server connection. Struggled with it for a few hours (in between struggling with another problem, though), disabling firewalls, googling around. But no clues.&lt;br /&gt;&lt;br /&gt;This morning with fresh curage I thought:lets not be too stubborn and try the suggested version of JDeveloper (11.1.1.1). The Soa-Infra version was: v11.1.1.0.0 - 11.1.1.1.0, according to the soa-infra page. The great thing about Jdeveloper 11g is that the studio-download is about 1GB. And having installed it, you have to download the SOA Composite editor separately via the Help&gt;Update-functionality. It's about an addtional 230MB. And I found JDeveloper 10.1.3.x with about 700MB large already (Soa-designers included)!&lt;br /&gt;&lt;br /&gt;But turns out to solve the problem. So no backwards-compatibility. Tight version coupling.&lt;br /&gt;So if you run into connection problems between Jdeveloper 11g and SoaSuite, just check the version numbers.&lt;br /&gt;&lt;br /&gt;Oh, and if you like to join the OPN Bootcamp in january, check out the&lt;a href="http://www.darwin-it.nl/diensten/trainen/oracle-partner-network-opn-delivery-partner/"&gt; enablement pages&lt;/a&gt;.&lt;br /&gt;The course can be given in English if required.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-5822545023421380141?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/5822545023421380141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=5822545023421380141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5822545023421380141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5822545023421380141'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/12/jdeveloper-11g-and-soasuite-11g-tight.html' title='JDeveloper 11g and SoaSuite 11g: a tight combination'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-5914771705935958261</id><published>2009-12-11T00:05:00.000-08:00</published><updated>2011-03-16T08:12:40.167-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='BPEL PM'/><title type='text'>Multi Operations BPEL</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Invocation flavours&lt;/span&gt;&lt;br /&gt;Most BPEL processes have just one entry and one exit point. Actually, if you create a new BPEL process you have the following templates:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Synchronous&lt;/li&gt;&lt;li&gt;Asynchronous&lt;/li&gt;&lt;li&gt;Empty&lt;/li&gt;&lt;/ul&gt;Empty you use when you want to start your BPEL process using an Adapter (File, Database, AQ, MQ, etc.). But often developers choose asynchronous and then figure they need to start the process using an adapter but leave the originally generated WSDL. The side effect might be that another developer might try to invoke the process/service using the original WSDL that is in fact not implemented anymore.&lt;br /&gt;&lt;br /&gt;For the two other templates you can have the following service flavours:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Synchronous (Request/Reply)&lt;/li&gt;&lt;li&gt;Asynchronous Request/Reply&lt;/li&gt;&lt;li&gt;Fire&amp;amp;Forget&lt;/li&gt;&lt;/ul&gt;Fire&amp;amp;Forget is about the same as Asynchronous Request/Reply. Often the terms and their meanings are mixed up. One says Asynchronous but means Fire&amp;amp;Forget. The distinguise is in the fact that with an Asynchronous process you expect an answer and with Fire and Forget you don't. Most of the times (I did that in the past as well) one builds an asynchronous process but does not put a corresponding receive in the calling process. There is little wrong with that. However if the developer even deletes the invoke to call back to the caller, but another developer does put in a receive (it is in fact an asynchronous process, right?) then it waits for a callback that never comes. So I strongly advice in to distinguise between Asynchronous and Fire&amp;amp;Forget, by removing the call-back partnerlink-type and porttype from the WSDL. And so delete the corresponding call-back-invoke from the process.&lt;br /&gt;&lt;br /&gt;Normally there are two ways for invoking these process, corresponding to the type. The "process"-operation for Synchronous and the "initiate"-operation for the Asynchronous/Fire&amp;amp;Forget ones.&lt;br /&gt;&lt;br /&gt;So that's about it on the invocation flavours, right?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Multiple Operations&lt;/span&gt;&lt;br /&gt;Well, not really. There are certain cases that you need to invoke your process in different ways. In the past I build processes that are initiated by one Operation (the initiate for Asynchronous), but I needed to send signals to the running process. For example, I build a schedule process that is initiated to wait for a certain time to do a certain task, based on information in the database. And if that is changed by an end-user, because the scheduled date/time is moved, you want to reschedule the process to have it wait for the new time.&lt;br /&gt;Another reason may be that you have to impelement a certain WSDL that is agreed upon (top-down-method).&lt;br /&gt;&lt;br /&gt;You do that by adding a new operation to the port-type in the WSDL. This new operation can have other message-types for input and output then the initiate operation.&lt;br /&gt;&lt;br /&gt;For example, if you create a new process, like the Asynchronous MultiOperationProcess, the WSDL will look like:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;definitions name="MultiOperationProcess"&lt;br /&gt;targetNamespace="http://xmlns.oracle.com/MultiOperationProcess"&lt;br /&gt;xmlns="http://schemas.xmlsoap.org/wsdl/"&lt;br /&gt;xmlns:client="http://xmlns.oracle.com/MultiOperationProcess"&lt;br /&gt;xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;TYPE DEFINITION - List of services participating in this BPEL process&lt;br /&gt;The default output of the BPEL designer uses strings as input and&lt;br /&gt;output to the BPEL Process. But you can define or import any XML&lt;br /&gt;Schema type and use them as part of the message types.&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;types&amp;gt;&lt;br /&gt;&amp;lt;schema xmlns="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br /&gt;&amp;lt;import namespace="http://xmlns.oracle.com/MultiOperationProcess" schemaLocation="MultiOperationProcess.xsd" /&amp;gt;&lt;br /&gt;&amp;lt;/schema&amp;gt;&lt;br /&gt;&amp;lt;/types&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;MESSAGE TYPE DEFINITION - Definition of the message types used as&lt;br /&gt;part of the port type defintions&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;message name="MultiOperationProcessRequestMessage"&amp;gt;&lt;br /&gt;&amp;lt;part name="payload" element="client:MultiOperationProcessProcessRequest"/&amp;gt;&lt;br /&gt;&amp;lt;/message&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;message name="MultiOperationProcessResponseMessage"&amp;gt;&lt;br /&gt;&amp;lt;part name="payload" element="client:MultiOperationProcessProcessResponse"/&amp;gt;&lt;br /&gt;&amp;lt;/message&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;PORT TYPE DEFINITION - A port type groups a set of operations into&lt;br /&gt;a logical service unit.&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;!-- portType implemented by the MultiOperationProcess BPEL process --&amp;gt;&lt;br /&gt;&amp;lt;portType name="MultiOperationProcess"&amp;gt;&lt;br /&gt;&amp;lt;operation name="initiate"&amp;gt;&lt;br /&gt;&amp;lt;input message="client:MultiOperationProcessRequestMessage"/&amp;gt;&lt;br /&gt;&amp;lt;/operation&amp;gt;&lt;br /&gt;&amp;lt;/portType&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- portType implemented by the requester of MultiOperationProcess BPEL process&lt;br /&gt;for asynchronous callback purposes&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;portType name="MultiOperationProcessCallback"&amp;gt;&lt;br /&gt;&amp;lt;operation name="onResult"&amp;gt;&lt;br /&gt;&amp;lt;input message="client:MultiOperationProcessResponseMessage"/&amp;gt;&lt;br /&gt;&amp;lt;/operation&amp;gt;&lt;br /&gt;&amp;lt;/portType&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;PARTNER LINK TYPE DEFINITION&lt;br /&gt;the MultiOperationProcess partnerLinkType binds the provider and&lt;br /&gt;requester portType into an asynchronous conversation.&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;plnk:partnerLinkType name="MultiOperationProcess"&amp;gt;&lt;br /&gt;&amp;lt;plnk:role name="MultiOperationProcessProvider"&amp;gt;&lt;br /&gt;&amp;lt;plnk:portType name="client:MultiOperationProcess"/&amp;gt;&lt;br /&gt;&amp;lt;/plnk:role&amp;gt;&lt;br /&gt;&amp;lt;plnk:role name="MultiOperationProcessRequester"&amp;gt;&lt;br /&gt;&amp;lt;plnk:portType name="client:MultiOperationProcessCallback"/&amp;gt;&lt;br /&gt;&amp;lt;/plnk:role&amp;gt;&lt;br /&gt;&amp;lt;/plnk:partnerLinkType&amp;gt;&lt;br /&gt;&amp;lt;/definitions&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Adding an operation is simple:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;definitions name="MultiOperationProcess" targetNamespace="http://xmlns.oracle.com/MultiOperationProcess"&lt;br /&gt;xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:client="http://xmlns.oracle.com/MultiOperationProcess"&lt;br /&gt;xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"&amp;gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;TYPE DEFINITION - List of services participating in this BPEL process&lt;br /&gt;The default output of the BPEL designer uses strings as input and&lt;br /&gt;output to the BPEL Process. But you can define or import any XML&lt;br /&gt;Schema type and use them as part of the message types.&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;types&amp;gt;&lt;br /&gt;&amp;lt;schema xmlns="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br /&gt;&amp;lt;import namespace="http://xmlns.oracle.com/MultiOperationProcess" schemaLocation="MultiOperationProcess.xsd"/&amp;gt;&lt;br /&gt;&amp;lt;/schema&amp;gt;&lt;br /&gt;&amp;lt;/types&amp;gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;MESSAGE TYPE DEFINITION - Definition of the message types used as&lt;br /&gt;part of the port type defintions&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;message name="MultiOperationProcessRequestAapMessage"&amp;gt;&lt;br /&gt;&amp;lt;part name="payload" element="client:MultiOperationProcessProcessAapRequest"/&amp;gt;&lt;br /&gt;&amp;lt;/message&amp;gt;&lt;br /&gt;&amp;lt;message name="MultiOperationProcessRequestNootMessage"&amp;gt;&lt;br /&gt;&amp;lt;part name="payload" element="client:MultiOperationProcessProcessNootRequest"/&amp;gt;&lt;br /&gt;&amp;lt;/message&amp;gt;&lt;br /&gt;&amp;lt;message name="MultiOperationProcessResponseMessage"&amp;gt;&lt;br /&gt;&amp;lt;part name="payload" element="client:MultiOperationProcessProcessResponse"/&amp;gt;&lt;br /&gt;&amp;lt;/message&amp;gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;PORT TYPE DEFINITION - A port type groups a set of operations into&lt;br /&gt;a logical service unit.&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;!-- portType implemented by the MultiOperationProcess BPEL process --&amp;gt;&lt;br /&gt;&amp;lt;portType name="MultiOperationProcess"&amp;gt;&lt;br /&gt;&amp;lt;operation name="initiateAap"&amp;gt;&lt;br /&gt;&amp;lt;input message="client:MultiOperationProcessRequestAapMessage"/&amp;gt;&lt;br /&gt;&amp;lt;/operation&amp;gt;&lt;br /&gt;&amp;lt;operation name="initiateNoot"&amp;gt;&lt;br /&gt;&amp;lt;input message="client:MultiOperationProcessRequestNootMessage"/&amp;gt;&lt;br /&gt;&amp;lt;/operation&amp;gt;&lt;br /&gt;&amp;lt;/portType&amp;gt;&lt;br /&gt;&amp;lt;!-- portType implemented by the requester of MultiOperationProcess BPEL process&lt;br /&gt;for asynchronous callback purposes&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;portType name="MultiOperationProcessCallback"&amp;gt;&lt;br /&gt;&amp;lt;operation name="onResult"&amp;gt;&lt;br /&gt;&amp;lt;input message="client:MultiOperationProcessResponseMessage"/&amp;gt;&lt;br /&gt;&amp;lt;/operation&amp;gt;&lt;br /&gt;&amp;lt;/portType&amp;gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;PARTNER LINK TYPE DEFINITION&lt;br /&gt;the MultiOperationProcess partnerLinkType binds the provider and&lt;br /&gt;requester portType into an asynchronous conversation.&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;plnk:partnerLinkType name="MultiOperationProcess"&amp;gt;&lt;br /&gt;&amp;lt;plnk:role name="MultiOperationProcessProvider"&amp;gt;&lt;br /&gt;&amp;lt;plnk:portType name="client:MultiOperationProcess"/&amp;gt;&lt;br /&gt;&amp;lt;/plnk:role&amp;gt;&lt;br /&gt;&amp;lt;plnk:role name="MultiOperationProcessRequester"&amp;gt;&lt;br /&gt;&amp;lt;plnk:portType name="client:MultiOperationProcessCallback"/&amp;gt;&lt;br /&gt;&amp;lt;/plnk:role&amp;gt;&lt;br /&gt;&amp;lt;/plnk:partnerLinkType&amp;gt;&lt;br /&gt;&amp;lt;/definitions&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can even change an existing operation. But then you'll have to change the initial receive:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_myrkQ5dyTYg/SyIMVdofxRI/AAAAAAAACN4/GpjKA4Tddz0/s1600-h/ReceiveInitiateAap.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 379px;" src="http://1.bp.blogspot.com/_myrkQ5dyTYg/SyIMVdofxRI/AAAAAAAACN4/GpjKA4Tddz0/s400/ReceiveInitiateAap.png" alt="" id="BLOGGER_PHOTO_ID_5413903264924026130" border="0" /&gt;&lt;/a&gt;Now you can add another Receive to cater for the receive events of the other porttype. Of course you need a Correlation Set to make sure that the event is sent to the right instance of the process.&lt;br /&gt;&lt;br /&gt;We just added an operation to the Port Type. But you can also add another PortType. That means however also another Partnerlink type:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;definitions name="MultiOperationProcess" targetNamespace="http://xmlns.oracle.com/MultiOperationProcess"&lt;br /&gt;xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:client="http://xmlns.oracle.com/MultiOperationProcess"&lt;br /&gt;xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"&amp;gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;TYPE DEFINITION - List of services participating in this BPEL process&lt;br /&gt;The default output of the BPEL designer uses strings as input and&lt;br /&gt;output to the BPEL Process. But you can define or import any XML&lt;br /&gt;Schema type and use them as part of the message types.&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;types&amp;gt;&lt;br /&gt;&amp;lt;schema xmlns="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br /&gt;&amp;lt;import namespace="http://xmlns.oracle.com/MultiOperationProcess" schemaLocation="MultiOperationProcess.xsd"/&amp;gt;&lt;br /&gt;&amp;lt;/schema&amp;gt;&lt;br /&gt;&amp;lt;/types&amp;gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;MESSAGE TYPE DEFINITION - Definition of the message types used as&lt;br /&gt;part of the port type defintions&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;message name="MultiOperationProcessRequestAapMessage"&amp;gt;&lt;br /&gt;&amp;lt;part name="payload" element="client:MultiOperationProcessProcessAapRequest"/&amp;gt;&lt;br /&gt;&amp;lt;/message&amp;gt;&lt;br /&gt;&amp;lt;message name="MultiOperationProcessRequestNootMessage"&amp;gt;&lt;br /&gt;&amp;lt;part name="payload" element="client:MultiOperationProcessProcessNootRequest"/&amp;gt;&lt;br /&gt;&amp;lt;/message&amp;gt;&lt;br /&gt;&amp;lt;message name="MultiOperationProcessRequestMiesMessage"&amp;gt;&lt;br /&gt;&amp;lt;part name="payload" element="client:MultiOperationProcessProcessMiesRequest"/&amp;gt;&lt;br /&gt;&amp;lt;/message&amp;gt;&lt;br /&gt;&amp;lt;message name="MultiOperationProcessResponseMessage"&amp;gt;&lt;br /&gt;&amp;lt;part name="payload" element="client:MultiOperationProcessProcessResponse"/&amp;gt;&lt;br /&gt;&amp;lt;/message&amp;gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;PORT TYPE DEFINITION - A port type groups a set of operations into&lt;br /&gt;a logical service unit.&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;!-- portType implemented by the MultiOperationProcess BPEL process --&amp;gt;&lt;br /&gt;&amp;lt;portType name="MultiOperationProcess"&amp;gt;&lt;br /&gt;&amp;lt;operation name="initiateAap"&amp;gt;&lt;br /&gt;&amp;lt;input message="client:MultiOperationProcessRequestAapMessage"/&amp;gt;&lt;br /&gt;&amp;lt;/operation&amp;gt;&lt;br /&gt;&amp;lt;operation name="initiateNoot"&amp;gt;&lt;br /&gt;&amp;lt;input message="client:MultiOperationProcessRequestNootMessage"/&amp;gt;&lt;br /&gt;&amp;lt;/operation&amp;gt;&lt;br /&gt;&amp;lt;/portType&amp;gt;&lt;br /&gt;&amp;lt;portType name="MultiOperationProcessMies"&amp;gt;&lt;br /&gt;&amp;lt;operation name="initiateMies"&amp;gt;&lt;br /&gt;&amp;lt;input message="client:MultiOperationProcessRequestMiesMessage"/&amp;gt;&lt;br /&gt;&amp;lt;/operation&amp;gt;&lt;br /&gt;&amp;lt;/portType&amp;gt;&lt;br /&gt;&amp;lt;!-- portType implemented by the requester of MultiOperationProcess BPEL process&lt;br /&gt;for asynchronous callback purposes&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;portType name="MultiOperationProcessCallback"&amp;gt;&lt;br /&gt;&amp;lt;operation name="onResult"&amp;gt;&lt;br /&gt;&amp;lt;input message="client:MultiOperationProcessResponseMessage"/&amp;gt;&lt;br /&gt;&amp;lt;/operation&amp;gt;&lt;br /&gt;&amp;lt;/portType&amp;gt;&lt;br /&gt;&amp;lt;!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;PARTNER LINK TYPE DEFINITION&lt;br /&gt;the MultiOperationProcess partnerLinkType binds the provider and&lt;br /&gt;requester portType into an asynchronous conversation.&lt;br /&gt;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --&amp;gt;&lt;br /&gt;&amp;lt;plnk:partnerLinkType name="MultiOperationProcess"&amp;gt;&lt;br /&gt;&amp;lt;plnk:role name="MultiOperationProcessProvider"&amp;gt;&lt;br /&gt;&amp;lt;plnk:portType name="client:MultiOperationProcess"/&amp;gt;&lt;br /&gt;&amp;lt;/plnk:role&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;plnk:role name="MultiOperationProcessRequester"&amp;gt;&lt;br /&gt;&amp;lt;plnk:portType name="client:MultiOperationProcessCallback"/&amp;gt;&lt;br /&gt;&amp;lt;/plnk:role&amp;gt;&lt;br /&gt;&amp;lt;/plnk:partnerLinkType&amp;gt;&lt;br /&gt;&amp;lt;plnk:partnerLinkType name="MultiOperationProcessMies"&amp;gt;&lt;br /&gt;&amp;lt;plnk:role name="MultiOperationProcessProviderMies"&amp;gt;&lt;br /&gt;&amp;lt;plnk:portType name="client:MultiOperationProcessMies"/&amp;gt;&lt;br /&gt;&amp;lt;/plnk:role&amp;gt;&amp;lt;/plnk:partnerLinkType&amp;gt;&lt;br /&gt;&amp;lt;/definitions&amp;gt;&lt;br /&gt;&lt;/pre&gt;Having this you need another partnerlink in your process to get events from it:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_myrkQ5dyTYg/SyIP3yzXU5I/AAAAAAAACOA/akEIESMiWZA/s1600-h/PartnerLinkClientMies.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 368px;" src="http://3.bp.blogspot.com/_myrkQ5dyTYg/SyIP3yzXU5I/AAAAAAAACOA/akEIESMiWZA/s400/PartnerLinkClientMies.png" alt="" id="BLOGGER_PHOTO_ID_5413907153257190290" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The corresponding XSD is:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;schema attributeFormDefault="unqualified" elementFormDefault="qualified"&lt;br /&gt;targetNamespace="http://xmlns.oracle.com/MultiOperationProcess" xmlns="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br /&gt;&amp;lt;element name="MultiOperationProcessProcessAapRequest"&amp;gt;&lt;br /&gt;&amp;lt;complexType&amp;gt;&lt;br /&gt;&amp;lt;sequence&amp;gt;&lt;br /&gt;&amp;lt;element name="inputAap" type="string"/&amp;gt;&lt;br /&gt;&amp;lt;/sequence&amp;gt;&lt;br /&gt;&amp;lt;/complexType&amp;gt;&lt;br /&gt;&amp;lt;/element&amp;gt;&lt;br /&gt;&amp;lt;element name="MultiOperationProcessProcessNootRequest"&amp;gt;&lt;br /&gt;&amp;lt;complexType&amp;gt;&lt;br /&gt;&amp;lt;sequence&amp;gt;&lt;br /&gt;&amp;lt;element name="inputNoot" type="string"/&amp;gt;&lt;br /&gt;&amp;lt;/sequence&amp;gt;&lt;br /&gt;&amp;lt;/complexType&amp;gt;&lt;br /&gt;&amp;lt;/element&amp;gt;&lt;br /&gt;&amp;lt;element name="MultiOperationProcessProcessMiesRequest"&amp;gt;&lt;br /&gt;&amp;lt;complexType&amp;gt;&lt;br /&gt;&amp;lt;sequence&amp;gt;&lt;br /&gt;&amp;lt;element name="inputMies" type="string"/&amp;gt;&lt;br /&gt;&amp;lt;/sequence&amp;gt;&lt;br /&gt;&amp;lt;/complexType&amp;gt;&lt;br /&gt;&amp;lt;/element&amp;gt;&lt;br /&gt;&amp;lt;element name="MultiOperationProcessProcessResponse"&amp;gt;&lt;br /&gt;&amp;lt;complexType&amp;gt;&lt;br /&gt;&amp;lt;sequence&amp;gt;&lt;br /&gt;&amp;lt;element name="result" type="string"/&amp;gt;&lt;br /&gt;&amp;lt;/sequence&amp;gt;&lt;br /&gt;&amp;lt;/complexType&amp;gt;&lt;br /&gt;&amp;lt;/element&amp;gt;&lt;br /&gt;&amp;lt;/schema&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Now you can implement about any WSDL with BPEL.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Multi Initiate&lt;/span&gt;&lt;br /&gt;A BPEL process can have only one Receive with the initiate checkbox checked. So there is just one and only one entry point in the BPEL process. This should also be the very first activity in the process. Actually it isn't. That is, if you have implemented an exception handler (Catch/CatchAll) on the outermost-scope. Then the activities in the fault-handlers are the first in the BPEL process. And I found that there is a little pitfall in it. It might be that you have an exception handling bpel-process that you call from the catch-branches. No worries if it is a logging process (Fire&amp;amp;Forget). But if it returns a value to determine if you have to do a retry or an abort, then you have a Receive activity &lt;span style="font-weight: bold;"&gt;before&lt;/span&gt; the first Initiate-Receive!&lt;br /&gt;&lt;br /&gt;But apparently you can not initiate your BPEL process from the other operations we introduced before. And that makes it only usefull in cases where you initiate your bpel process in one way and have it receive messages over the other operations. If you have to implement a certain WSDL with multiple operations that have to initiate the process: "Houston we have a problem".&lt;br /&gt;&lt;br /&gt;Until yesterday this is what I believed as well. But I under-estimated the use of the Pick activity!&lt;br /&gt;The Pick activity splits up the initiation of the process from the messages it listens to:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyISw-0EU0I/AAAAAAAACOI/bG61stgbsLM/s1600-h/PickMultiReceive.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 371px;" src="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyISw-0EU0I/AAAAAAAACOI/bG61stgbsLM/s400/PickMultiReceive.png" alt="" id="BLOGGER_PHOTO_ID_5413910334757163842" border="0" /&gt;&lt;/a&gt;You can then remove the Timer Branch and add extra Branches. For Aap (Ape):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_myrkQ5dyTYg/SyIVNDHMVhI/AAAAAAAACOQ/hcHDjO05PEk/s1600-h/InitiateAap.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 368px;" src="http://1.bp.blogspot.com/_myrkQ5dyTYg/SyIVNDHMVhI/AAAAAAAACOQ/hcHDjO05PEk/s400/InitiateAap.png" alt="" id="BLOGGER_PHOTO_ID_5413913015970715154" border="0" /&gt;&lt;/a&gt;For Noot (Nut)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyIVkrnZpAI/AAAAAAAACOg/I9bp0_zGsJ4/s1600-h/InitiateNoot.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 371px;" src="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyIVkrnZpAI/AAAAAAAACOg/I9bp0_zGsJ4/s400/InitiateNoot.png" alt="" id="BLOGGER_PHOTO_ID_5413913421980214274" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;For Mies:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyIVNY7uINI/AAAAAAAACOY/LsMUJ25HKQE/s1600-h/InitiateMies.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 366px;" src="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyIVNY7uINI/AAAAAAAACOY/LsMUJ25HKQE/s400/InitiateMies.png" alt="" id="BLOGGER_PHOTO_ID_5413913021828178130" border="0" /&gt;&lt;/a&gt;And in the branches you can for example add an assignment from the corresponding message:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyIV1pz5CoI/AAAAAAAACOo/pl53EfCQ3-Y/s1600-h/CopyAap.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 315px;" src="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyIV1pz5CoI/AAAAAAAACOo/pl53EfCQ3-Y/s400/CopyAap.png" alt="" id="BLOGGER_PHOTO_ID_5413913713553508994" border="0" /&gt;&lt;/a&gt;If you do that for each of the branches, the example process will look like:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_myrkQ5dyTYg/SyIWCQNVcSI/AAAAAAAACOw/XOezKt6eT_o/s1600-h/MultiOperationProcess"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 341px;" src="http://3.bp.blogspot.com/_myrkQ5dyTYg/SyIWCQNVcSI/AAAAAAAACOw/XOezKt6eT_o/s400/MultiOperationProcess" alt="" id="BLOGGER_PHOTO_ID_5413913930019205410" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Don't forget to remove the original InputMessage-variable.&lt;br /&gt;&lt;br /&gt;Unfortunately the BPEL Console does not support the extra porttype for the test screen. I haven't been able to test it with SoapUI yet. So I'm not sure if that works. Deleting the ClientMies parts of the process will work:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_myrkQ5dyTYg/SyIgOY4UksI/AAAAAAAACO4/IMDd_2nib9Y/s1600-h/BPELConsoleInitiate.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 381px;" src="http://2.bp.blogspot.com/_myrkQ5dyTYg/SyIgOY4UksI/AAAAAAAACO4/IMDd_2nib9Y/s400/BPELConsoleInitiate.png" alt="" id="BLOGGER_PHOTO_ID_5413925133621695170" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;That leaves us with this process (belonging with the second WSDL above):&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyIgaZN-TnI/AAAAAAAACPA/XirVU3W5PQg/s1600-h/MultiOperationProcess2Operations.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 276px; height: 400px;" src="http://4.bp.blogspot.com/_myrkQ5dyTYg/SyIgaZN-TnI/AAAAAAAACPA/XirVU3W5PQg/s400/MultiOperationProcess2Operations.png" alt="" id="BLOGGER_PHOTO_ID_5413925339870940786" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;Now you can implement about any WSDL using BPEL, although apparently you're contracted to having one partnerlink-type and one port-type with multiple operations.  For me it was a revelation to be able to initiate your process in multiple ways. It might come in handy when you have a case that has some different initiation message but a common process-part. Normally you would create seperate processes to receive the different messages and have them transform them to a common message-format and call the common process. But apparently we can do it all in one process too.&lt;br /&gt;&lt;br /&gt;You can find my code-examples &lt;a href="http://www.darwin-it.nl/?id=CodeVoorbeelden"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-5914771705935958261?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/5914771705935958261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=5914771705935958261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5914771705935958261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5914771705935958261'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/12/multi-operations-bpel.html' title='Multi Operations BPEL'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_myrkQ5dyTYg/SyIMVdofxRI/AAAAAAAACN4/GpjKA4Tddz0/s72-c/ReceiveInitiateAap.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-4838838155789882389</id><published>2009-11-30T00:23:00.000-08:00</published><updated>2009-11-30T00:57:26.782-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='BPEL PM'/><title type='text'>BPEL Partnerlinks thoughts</title><content type='html'>Today I have a support session with a colleague. One of the questions he came up with was about BPEL-partnerlinks. In his current project they have BPEL Partnerlinks to integrate with Pl/Sql procedures on E-Business Suite. They tend to introduce a partnerlink for every invoke of a Pl/Sql procedure. So how about reuse of partnerlinks?&lt;br /&gt;&lt;br /&gt;Well at first thought the answer is simple: there is no one-to-one relationship between a partnerlink and invokes of that partnerlink. So you can introduce as many invokes on a certain partnerlink as you want.&lt;br /&gt;However at second thought there are a few considerations. I'll give a few that I came up with:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Invokes preferably are done in seperate scopes. That is: I prefer to do so. That provides the possibility to catch exceptions on that scope specifically. Variables are kept local as much as possible. Escpecially when the documents they hold can be large. At least you should think about the scope of variables. So if the invoke's input and output variabables are locally declared then they cannot be reused amongst invokes.&lt;/li&gt;&lt;li&gt;If the input and output variables of the invokes are local and thus not shared, you need to build them up from scratch. This can introduce extra assign steps that might be avoided when declare the variables in a larger spanning scope.  Extra assign activities with copy steps cost time. A little perhaps, but still they do. Shared variables are stored to dehydration store over and over again.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A shared partnerlink has thus shared MCF (managed connection factory)-properties. And possibly other adapter-related properties. Normally you probably want that. So in most cases it is advisable to share partnerlinks escpecially on adapters. Then you have to configure them only once. However in some cases you might (for instance with queues) use other parameters. Maybe you have two EBS-instances and a process calling the same procedure but on seperate instances. Then you need to split them up of course.&lt;/li&gt;&lt;li&gt;Be aware of transactions. The database adapter normally uses connection-pooled datasources. Database sessions are shared amongst instances. You might expect (but I won't rely on it!) that if you share a database-adapter-partnerlink (invoke it multiple times) in a synchronous process, that every invoke would use the same database-session. So for instance your application context settings, package variables, etc. are shared. Although I would check on run-time, you can use that for performance purposes. In a synchronous process you may rely on the fact that this occurs in the same database-transaction.  However, if you use different partnerlinks for in fact the same Pl/Sql procedure/function call, the chance is large that you get another database-session. BPEL might need to rely on XA-transaction mechanisms. I don't think this is functionally a big problem. But might cause issues on processes with high performance requirements.&lt;/li&gt;&lt;li&gt;Maintenance: having multple partnerlinks for the same database procedure or even the same purpose introduces extra maintenance cost and a higher risk. I would not expect that a BPEL-project would have multiple partnerlinks for the same purpose. So in a Change Request or Test-Issue I tend to solve/change the first partnerlink and forget about possible others. And why should I be different from fellow developers? A good developer is a lazy one...&lt;br /&gt;Input and Output variables are based on the message-definitions of the partnerlinks-wsdl's. So changing one partnerlink might change the message definitions. If you reuse your partnerlinks, changing them will effect all the related variables.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;These are thoughts that crossed my mind in thinking it over. To be sure you need to check by testing. But I do think that in most cases you should declare a partnerlink for a certain purpose only once. In principle that's the best practice. And that will prevent a lot of possible issues. Only re-declare a partnerlink if you have good reasons for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-4838838155789882389?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/4838838155789882389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=4838838155789882389' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4838838155789882389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/4838838155789882389'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/11/bpel-partnerlinks-thoughts.html' title='BPEL Partnerlinks thoughts'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-5415880545853169153</id><published>2009-11-25T01:11:00.000-08:00</published><updated>2009-11-25T01:37:36.094-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle AIA'/><title type='text'>Oracle AIA Links</title><content type='html'>At the moment I'm delivering the OPN Bootcamp on AIA. One of the questions from the group is on documentation. So I have taken the time (while the students are busy with the labs) to scan around OTN to findout some of the interesting links on AIA.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;AIA Best Practice Center: &lt;a href="http://www.oracle.com/technology/products/applications/aia/index.html"&gt;http://www.oracle.com/technology/products/applications/aia/index.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Oracle Wiki on AIA: &lt;a href="http://wiki.oracle.com/page/Application+Integration+Architecture"&gt;http://wiki.oracle.com/page/Application+Integration+Architecture&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Official AIA blog: &lt;a href="http://blogs.oracle.com/aia/"&gt;http://blogs.oracle.com/aia/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;AIA OTN Forum: &lt;a href="http://forums.oracle.com/forums/forum.jspa?forumID=577"&gt;http://forums.oracle.com/forums/forum.jspa?forumID=577&lt;/a&gt;&lt;/li&gt;&lt;li&gt;OTN AIA Foundiation pack page: &lt;a href="http://www.oracle.com/technology/products/applications/aia/aia_fp1_index.html"&gt;http://www.oracle.com/technology/products/applications/aia/aia_fp1_index.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;AIA Foundation Pack Tools: &lt;a href="http://www.oracle.com/technology/products/applications/aia/aiatools.html"&gt;http://www.oracle.com/technology/products/applications/aia/aiatools.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;OTN AIA PIP page: &lt;a href="http://www.oracle.com/technology/products/applications/aia/aiapipnew.html"&gt;http://www.oracle.com/technology/products/applications/aia/aiapipnew.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Hope you'll find it usefull as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-5415880545853169153?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/5415880545853169153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=5415880545853169153' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5415880545853169153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5415880545853169153'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/11/at-moment-im-delivering-opn-bootcamp-on.html' title='Oracle AIA Links'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-8976745948064746513</id><published>2009-11-22T06:36:00.000-08:00</published><updated>2011-04-06T00:15:34.690-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Back to OpenSuse 11.1</title><content type='html'>Last week I encountered some troubles with my OpenSuse 11.1 installation. Apparently something in wine and else got corrupt. I had some idea's what might have caused it, but was not sure. Although I found some entries comparable to the errors I had, I could not find a sufficient solution. Since OpenSuse 11.2 turned out to be released recently, I thought: "let's give that one a shot". Everything installed smoothly.&lt;br /&gt;&lt;br /&gt;Of course I had to install the native NVidia driver again using the &lt;a href="http://en.opensuse.org/Nvidia"&gt;one click install&lt;/a&gt;. OpenSuse does not ship the propietry drivers, but does provide a simple install-solution.&lt;br /&gt;The multi-media support (escpecially flash and mp3) for 11.2 is installed via &lt;a href="http://linuxpoison.blogspot.com/2009/11/multimedia-mp3-mpeg-4-avi-divx-etc.html"&gt;this post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;However after some strubbling I came to the conclusion that VMware Server 2.0.x just won't work under 11.2. The rpm does install, but the vmware-config.pl hits several nasty compile-errors. Apperently the kernel is just too new for VMWare. I found some scripts to repair the install, based on the tar.gz-deployment. But they were mainly focussed on Ubuntu, doing some preparartions using the Ubuntu package-manager. So I re-installed  11.1.&lt;br /&gt;First I tried to upgrade KDE to 4.3, but that did not work well. So the third time I just installed 11.1-vanilla.&lt;br /&gt;A one-click-install for multimedia support voor 11.1 I found &lt;a href="http://linuxpoison.blogspot.com/2008/12/multimedia-support-in-opensuse-111-mp3.html"&gt;here &lt;/a&gt;(basically the same blog that posted the one-click-install for 11.2.&lt;br /&gt;&lt;br /&gt;A lass: OpenSuse 11.2 worked really fine: my laptop ran like a sun (there is a great commercial on Wind-energy on Dutch television. With an older man that hosts city-trips for foreigners. He talks really Dutch English with litterly translated Dutch sayings on wind. My favorite: "I think You think they smell an hour in the wind").  But to me VMware is a real must.&lt;br /&gt;Especially this week: I'll deliver an&lt;a href="http://guest.cvent.com/EVENTS/Info/Summary.aspx?i=d771b399-c83b-44f3-b824-cba3e5c60716"&gt; OPN Bootcamp on AIA in De Meern, the Netherlands, from tommorow (mentioned dates are wrong: it's this week)&lt;/a&gt;. It's based on a VMware image with an SoaSuite+AIA installment for the labs. If you're interested: there still are some seats available.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-8976745948064746513?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/8976745948064746513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=8976745948064746513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8976745948064746513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8976745948064746513'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/11/toch-maar-opensuse-111.html' title='Back to OpenSuse 11.1'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-3777008321685422227</id><published>2009-11-16T05:01:00.000-08:00</published><updated>2011-04-06T00:18:32.322-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>VMware Server 2.0.2 on OpenSuse 11.1</title><content type='html'>Today during preparing the OPN Bootcamp on Oracle AIA Foundation Pack, I found out that VMware Server 2.0.2 is out. It has been released on october 26th.&lt;br /&gt;So I downloaded the one for my system (OpenSuse 11.1 x86_64). As well as the windows variant for the bootcamp.&lt;br /&gt;&lt;br /&gt;To upgrade an existing installed vmware server you can do (as root):&lt;br /&gt;&lt;pre&gt;makker-laptop:/usr/bin # rpm -Uhv VMware-server-2.0.2-203138.x86_64.rpm&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To query which VMware Server you have installed:&lt;br /&gt;&lt;pre&gt;makker-laptop:/usr/bin # rpm -q VMware-server&lt;br /&gt;VMware-server-2.0.2-203138&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To install if you're not having VMware Server:&lt;br /&gt;&lt;pre&gt;makker-laptop:/usr/bin # rpm -ihv VMware-server-2.0.2-203138.x86_64.rpm&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then after that you should run vmware-config.pl in /usr/bin folder as root.&lt;br /&gt;&lt;br /&gt;In my case something went wrong in installing the vsock module. I did not see that in an earlier install. This is the message I got:&lt;br /&gt;&lt;pre&gt;make: Entering directory `/tmp/vmware-config6/vsock-only'&lt;br /&gt;make -C /lib/modules/2.6.27.37-0.1-default/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules&lt;br /&gt;make[1]: Entering directory `/usr/src/linux-2.6.27.37-0.1-obj/x86_64/default'                &lt;br /&gt;make -C ../../../linux-2.6.27.37-0.1 O=/usr/src/linux-2.6.27.37-0.1-obj/x86_64/default/. modules&lt;br /&gt;CC [M]  /tmp/vmware-config6/vsock-only/linux/af_vsock.o                                     &lt;br /&gt;CC [M]  /tmp/vmware-config6/vsock-only/linux/driverLog.o                                    &lt;br /&gt;CC [M]  /tmp/vmware-config6/vsock-only/linux/util.o                                         &lt;br /&gt;CC [M]  /tmp/vmware-config6/vsock-only/linux/vsockAddr.o                                    &lt;br /&gt;LD [M]  /tmp/vmware-config6/vsock-only/vsock.o                                              &lt;br /&gt;Building modules, stage 2.                                                                  &lt;br /&gt;MODPOST 1 modules                                                                           &lt;br /&gt;WARNING: "VMCIDatagram_CreateHnd" [/tmp/vmware-config6/vsock-only/vsock.ko] undefined!        &lt;br /&gt;WARNING: "VMCIDatagram_DestroyHnd" [/tmp/vmware-config6/vsock-only/vsock.ko] undefined!       &lt;br /&gt;WARNING: "VMCI_GetContextID" [/tmp/vmware-config6/vsock-only/vsock.ko] undefined!             &lt;br /&gt;WARNING: "VMCIDatagram_Send" [/tmp/vmware-config6/vsock-only/vsock.ko] undefined!             &lt;br /&gt;CC      /tmp/vmware-config6/vsock-only/vsock.mod.o                                          &lt;br /&gt;LD [M]  /tmp/vmware-config6/vsock-only/vsock.ko                                             &lt;br /&gt;make[1]: Leaving directory `/usr/src/linux-2.6.27.37-0.1-obj/x86_64/default'                  &lt;br /&gt;cp -f vsock.ko ./../vsock.o                                                                   &lt;br /&gt;make: Leaving directory `/tmp/vmware-config6/vsock-only'                                      &lt;br /&gt;Unable to make a vsock module that can be loaded in the running kernel:                       &lt;br /&gt;insmod: error inserting '/tmp/vmware-config6/vsock.o': -1 Unknown symbol in module            &lt;br /&gt;There is probably a slight difference in the kernel configuration between the                 &lt;br /&gt;set of C header files you specified and your running kernel.  You may want to                 &lt;br /&gt;rebuild a kernel based on that directory, or specify another directory.  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You might not need it since Vsock is an optional module that is used in communication between guests and hosts. But luckily I found a solution &lt;a href="http://opensuse.swerdna.org/susevmwareserver.html"&gt;here&lt;/a&gt;. Mr. Swerdna states that there is a flaw in the vmware-config.pl, for which he provides a patch. He also explains how to enable USB support in guests. So thank you very much mr. Swerdna.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-3777008321685422227?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/3777008321685422227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=3777008321685422227' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3777008321685422227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/3777008321685422227'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/11/vmware-server-202-on-opensuse-111.html' title='VMware Server 2.0.2 on OpenSuse 11.1'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-746650381293226731</id><published>2009-11-10T23:16:00.000-08:00</published><updated>2009-11-10T23:28:09.747-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='BPEL PM'/><title type='text'>PartnerlinkType not found</title><content type='html'>Yesterday I was struggling in getting a dynamic partnerlink coupling to work in BPEL PM.&lt;br /&gt;I would not say that I invented the principle of dynamic partnerlinks myself. But lets say that it was not my first time. And what I tried and checked, and double checked, I kept hitting the error:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Error while invoking bean "presentation manager": Cannot find partnerLinkType 2.&lt;br /&gt;PartnerLinkType "{http://www.domain.nl/PROJECT/SUBPROJECT/PUB}PROJECT_PUB" is not found in WSDL at&lt;br /&gt; "http://localhost:7777/orabpel/default/MyBpelProcess/1.0/_MyBpelProcess.wsdl".&lt;br /&gt;Please make sure the partnerLinkType is defined in the WSDL.&lt;br /&gt;&lt;br /&gt;ORABPEL-08016&lt;br /&gt;&lt;br /&gt;Cannot find partnerLinkType 2.&lt;br /&gt;PartnerLinkType "{http://www.domain.nl/PROJECT/SUBPROJECT/PUB}PROJECT_PUB" is not found in WSDL at&lt;br /&gt; "http://localhost:7777/orabpel/default/MyBpelProcess/1.0/_MyBpelProcess.wsdl".&lt;br /&gt;Please make sure the partnerLinkType is defined in the WSDL.&lt;br /&gt;&lt;/pre&gt;At the end I was so desperate that I thought: "Okay then, lets google the error". Afterwards I could hit myself with the question: "why didn't I do this earlier?". Because the answer was simple and can be found (amongst others) &lt;a href="http://forums.oracle.com/forums/thread.jspa?messageID=3622325"&gt;here&lt;/a&gt;: Just clear the WSDL cache. Apparently my wsdl updates were deployed but not replacing the occurence in the cache. Ouch.&lt;br /&gt;&lt;br /&gt;To my defense I would say that dynamic partnerlinks aren't hard but a mistake is made easy and the dependencies are very sensitive. And also I had to copy an existing solution to adapt it to a new situation. And that is harder than build it yourself. But may be in the future I should consider Google as  a closer friend...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-746650381293226731?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/746650381293226731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=746650381293226731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/746650381293226731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/746650381293226731'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/11/partnerlinktype-not-found.html' title='PartnerlinkType not found'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-6896164034362803909</id><published>2009-11-10T22:46:00.001-08:00</published><updated>2009-11-10T23:10:57.958-08:00</updated><title type='text'>EU Commitee against Sun-aqcuisition</title><content type='html'>As I, honestly, expected the EU Commitee is against the aqcquistition of Sun by Oracle. This can be read (in Dutch) &lt;a href="http://www.automatiseringgids.nl/markt-monitor/champions-league/2009/46/eu-vooralsnog-tegen-overname-sun-door-oracle.aspx"&gt;here&lt;/a&gt;. Main issue is the position of the MySql database. Oracle wants to keep it, but it would make Oracle not only the biggest in commercial databases but also in OpenSource.&lt;br /&gt;It does impose a significant delay in the acquisition. Oracle expresses that the issues of the European Commitee are based on a misunderstanding on the database and open source marketed.&lt;br /&gt;&lt;br /&gt;I'm curious how they see that, because it is not expressed in the quoted article.&lt;br /&gt;Also the American department of Justice made explicitly clear that it approved while they're convinced that MySql does not damage the competition in the database market.&lt;br /&gt;&lt;br /&gt;I find it curious though that the acquisition of a commercial company by another commercial company is under investigation/restriction because of a non-commercial product. I understand that the MySql holding company is in fact commercial. But you and I and every one who wants to do it can get a fork of the MySql source and start our own database. Provided that we know C++ (I conveniently assume that MySql is written in C++) , what in my case is quite rusty, and understand the sources.&lt;br /&gt;&lt;br /&gt;So I would ask that if Oracle promises that they embrace MySql lovely caring, what would be the issue here then? And EU could just put some preconditions on the take-over. And sanctions if in a later stage Oracle turns out to not meeting those.&lt;br /&gt;But then: I'm not so political. And I'm in a struggle: I'm pretty proud that one of the major forces in these matters on European Level is a Dutch woman, but at the other hand I've a history with Oracle. And I think the take over would be a good one. Or at least an interesting one. For Sun, Oracle and the ICT market.&lt;br /&gt;&lt;br /&gt;Yesterday I found that Oracle wants to keep Sun's Glassfish Appserver as a referential implementation of J2EE. I take it with for example the SOAP toolstack Metro. Which is nice, because then Oracle has three app-servers if I'm counting right:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;OC4j (originally from Orion), still base of the J2EE parts of E-Business Suite, and probably for years to come.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Weblogic (originally from BEA)&lt;/li&gt;&lt;li&gt;Glassfish (originally from Sun)&lt;/li&gt;&lt;/ul&gt;I heard from a colleague who attended the DBA-day of the Dutch Oracle User Grouop that Oracle would not go further with VirtualBox. That would be a pity I think. I don't think it means that it ceases to exist. But a desktop virtualization tool would nicely extent Oracle's virtualization portfolio. Oracle might be focussing on the Server market. But then, what about StarOffice/OpenOffice for example?&lt;br /&gt;&lt;br /&gt;Well questions enough. And a nice subject to philosophize further upon. But to remember/rephrase a phrase from Mike Oldfields "Songs of a distant earth": "Only time will tell"...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-6896164034362803909?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/6896164034362803909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=6896164034362803909' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6896164034362803909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/6896164034362803909'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/11/eu-commitee-against-sun-aqcuisition.html' title='EU Commitee against Sun-aqcuisition'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-5498724529150619615</id><published>2009-10-29T00:37:00.000-07:00</published><updated>2009-10-29T01:12:03.828-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><title type='text'>Next Generation SOA</title><content type='html'>Last week I was on the SoaSymposium in the WorldTrade Center in Rotterdam. The theme of this years episode was apparently "Next Generation SOA". On before hand I wondered what they meant with it. Apparently I missed the blog of Anne Thomas Mane that &lt;a href="http://apsblog.burtongroup.com/2009/01/soa-is-dead-long-live-services.html"&gt;stated that SOA is dead&lt;/a&gt;.&lt;br /&gt;It reminded me of my own &lt;a href="http://darwin-it.blogspot.com/2008/12/eda-successor-of-soa.html"&gt;blog post&lt;/a&gt; on the subject. In that blog-post I opposed to the statement of soa-experts of a Dutch ICT weeklet, where SOA was declared dead in favour of EDA. Because I could not remember exactly on what article I reacted back then, I got a little anxious to get in touch with her. But the reason that Anne declared SOA dead was because of the hype that rose around the acronym by the vendors, customers and media. The acronym got so loaded with pre-assumptions that it did not stand for what it promised anymore. And so many SOA projects fail because customers think they could buy the magic box of a vendor that solve every problem. Or the magic hat of the Pixar Magician &lt;a href="http://www.youtube.com/watch?v=1ryMXVV-b6k"&gt;Presto&lt;/a&gt;. And of course vendor's would love to sell this to them. If they could... To declare SOA dead as a hype with all its false promises and focus on Service Orientation, I second completely. You can't buy or sell SOA, neither as a "Silver bullet", nor as a "Magic hat". It reminded me on this company that would sell an integration product on a blade-server. Put it in a rack and your ERP's are integrated. Yeah, right. I assume that the actual implementation is less magic.&lt;br /&gt;&lt;br /&gt;Thomas Erl and Anne had a session to cast out the "Evil SOA" and welcome the "Good SOA". I liked the music of Mike Oldfield, but after a while it got too pressing and looped through the very first part of Tubular Bells, that it almost cast me out. But it got me the nice Soa Patterns book of Thomas Erl.&lt;br /&gt;&lt;br /&gt;I think with Thomas and Anne that Service Orientation is very important and grow in importance. But together with EDA. Well actually, I think EDA is not an architecture on it self. As with Soa and cloud: if we're going to hype this idea we fall in the same faults again. But as stated in my former post, I think that Events and Services are (or should) two thightly coupled ideas. No loose coupling here. You use these ideas to loosely couple your functionalities. But Services are useless without events. And events (either coming through an esb or as a stream) are quite useless without services that process them.&lt;br /&gt;&lt;br /&gt;For the rest it was a good event to network. Met a few former colleagues and business-partners. Or people with I had co-acquaintances. I saw a nice presentation of Sander Hoogendoorn and Twan van der Broek on agile SOA projects combined with ERP. I'd like to learn more on that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-5498724529150619615?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/5498724529150619615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=5498724529150619615' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5498724529150619615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/5498724529150619615'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/10/next-generation-soa.html' title='Next Generation SOA'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-8536551668464993733</id><published>2009-10-27T11:42:00.001-07:00</published><updated>2009-10-28T00:50:22.987-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Machines'/><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Box'/><title type='text'>VirtualBox: a virtual competitor of VMware?</title><content type='html'>I'm a frequent VMware user for years. Most of my setups are done in a Virtual Machine. It's very convenient because with a new host installation, just installing VMware and restoring the virtual machines gets you up and running.&lt;br /&gt;&lt;br /&gt;One of the names that comes around on Virtualization on Linux is VirtualBox. I did not pay any attention to it since I was quite happy with VMware. I use VMware Server, since it's free and has about every feature VMware Workstation had in the latest version I used. That was Workstation 5.5 and the only thing Server lacked was Shared Folders.&lt;br /&gt;&lt;br /&gt;But products evolve. And Server has become quite big. I found it quite a step to turn from 1.x to 2.0 since the footprint increased about 5 times! From 100MB to about 500MB.&lt;br /&gt;&lt;br /&gt;Last week my colleague Erik asked me if I knew VirtualBox. I said I did, that is by name. A colleague on his project advised him to go for VirtualBox. So I thought I might give it a try.&lt;br /&gt;Some of the features of VirtualBox that interested me were:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;it's about 40MB! That is very small for such a complete product. I like that. I'm fond of small but feature-rich products, like TotalCommander, Xtrans and IrfanView on Windows. Apparently there are still programmers that go for smart and compact products.&lt;/li&gt;&lt;li&gt;I found articles on internet that it would be faster then VMware. I  also found statements that suggest it is slower. But on a simple laptop, performance would be the decision forcing feature.&lt;/li&gt;&lt;li&gt;Seamless mode: VirtualBox can have the applications run in a seperate window along with the native applications on your host. It layers the taskbar on top of the taskbar of your host. Looks neat!&lt;/li&gt;&lt;li&gt;Shared Folders: this was the differating feature between Server and Workstation. I solved that lack by installing a Filezilla Server on the Windows Hosts, or using SFTP over SSH on Linux. But it is handy to have that feature.&lt;/li&gt;&lt;li&gt;It's a client/standalone app: it may seem like a nonsense feature. But VMware Server comes with an Apache Tomcat application server that serves the infrastructure application. That's nice for a server based application, but on a laptop quite over done.&lt;/li&gt;&lt;li&gt;3D Acceleration: this summer I wanted to run a Windows racing game under VMware. It didn't do it. I should try it under VirtualBox with 3D acceleration on.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;But the important feature to have it work for me is that it should be able to run or import VMware images. It turns out that it cannot. You have to create a new VirtualBox image. But luckily you can base it on the virtual disks of a VMware image. Below I tell you how.&lt;/li&gt;&lt;/ul&gt;What I did not know was that Sun Microsystems acquired Innotek last year (2008). And since Oracle is in the run to buy Sun, Oracle gets this Virtualizing tool also. Another crown-jewel I could say. Since Oracle does have a VM tool but it is not a desktop tool. Oracle's VM has to run on the 'bare metal'.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Pre-requisites:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Install VirtualBox: download it from &lt;a href="http://www.virtualbox.org/wiki/Downloads"&gt;http://www.virtualbox.org/wiki/Downloads&lt;/a&gt;. Mark that there is an Open Source and a Closed Source version. Both free, but the Closed Source is the most feature-rich. Importing and exporting is only available in the closed source version. The Open Source is apparently available in many Linux Repositories. But I went for the Closed Source.&lt;/li&gt;&lt;li&gt;De-install VMware tools from the guest os before migrating. VirtualBox can install it's own guest-tools with the own drivers. For windows you can do it from the software pane in the configuration screen. Under linux (rpm based) you can remove it using rpm -e VMwareTools-5.0.0-&lt;xxxx&gt;.i386.rpm. To query the precise version you can do rpm -q VMwareTools&lt;br /&gt;&lt;/xxxx&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Creation of the VM&lt;/span&gt;&lt;br /&gt;Then you can Create a new VirtualMachine in VirtualBox. You can find an how-to with screen-dumps &lt;a href="https://wiki.ubuntu.com/UbuntuMagazine/HowTo/Switching_From_VMWare_To_VirtualBox:_.vmdk_To_.vdi_Using_Qemu_+_VdiTool"&gt;here&lt;/a&gt;.&lt;br /&gt;For the harddisks use the existing disks of your VMware image. If the VM is a Windows Guest, the disks are probably IDE disks. You could try to use SATA as an Additional Controller (check the checkbox) and couple them to a SATA channel in order of the disks. Denote the first one bootable. If it is a Linux guest the disks are probably SCSI- LsiLogic, so choose SCSI as additional disk.&lt;br /&gt;&lt;br /&gt;After adding the disks and other hardware, you can start it. After starting it you can install the Guest addons. These are necessary to have the appropriate drivers. Under windows, an installer is automatically started. Under Linux a virtual cdrom is mounted. Do a 'su -' to root and start the appropriate '.run' file or do a sudo:&lt;br /&gt;&lt;code&gt;sudo /media/cdrom/VBoxLinuxAdditions-x86.run&lt;br /&gt;&lt;/code&gt;In this case it is for a 32-bit Linux. For 64-bit Linux guests it should be the amd64 variant.&lt;br /&gt;&lt;br /&gt;After the install you should restart the guest.&lt;br /&gt;&lt;br /&gt;Then you can reconfigure your display type (resolution, color-depth) and the network adapters.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Experiences&lt;/span&gt;&lt;br /&gt;Well my first experiences are pretty positive. It is sometimes a struggle to get the display and the networking right. It's a pity that you have to recreate the VM instead of importing the VMware image itself. It seems to me that the VMware vmx is convertable to the VirtualBox xml-config file.&lt;br /&gt;&lt;br /&gt;I found it a little inconvenient that on clicking of the VM it starts immediately. Sometimes you just want to reconfigure it.&lt;br /&gt;&lt;br /&gt;I have to experience the peformance still. So I don't know yet if VirtualBox on this is an advantage. But the Seamless mode is really neat.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_myrkQ5dyTYg/SudghD3xKlI/AAAAAAAACNQ/TDCHhrNZS2k/s1600-h/VirtualBoxSeamlessmode.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 250px;" src="http://3.bp.blogspot.com/_myrkQ5dyTYg/SudghD3xKlI/AAAAAAAACNQ/TDCHhrNZS2k/s400/VirtualBoxSeamlessmode.png" alt="" id="BLOGGER_PHOTO_ID_5397388799517993554" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-8536551668464993733?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/8536551668464993733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=8536551668464993733' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8536551668464993733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/8536551668464993733'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/10/virtualbox-virtual-competitor-of-vmware.html' title='VirtualBox: a virtual competitor of VMware?'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_myrkQ5dyTYg/SudghD3xKlI/AAAAAAAACNQ/TDCHhrNZS2k/s72-c/VirtualBoxSeamlessmode.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-366556192807959259</id><published>2009-10-08T12:33:00.000-07:00</published><updated>2009-10-08T13:53:44.266-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JDeveloper'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle Application Server'/><title type='text'>JNDI in your Applications</title><content type='html'>Lately I had to make several services to be used from an application server, as a webservice or a service used from BPEL.&lt;p&gt;&lt;/p&gt; I find it convenient to first build the application or service as a java-application and test it from jDeveloper and/or using an ant-script. Although I know that it's possible to test an application from the application server (but never did it myself) it surely is more convenient to have it tested from an ordinary java-application. Also it enables you to use the service in other topologies. Actually it's my opinion that for example a Webservice should not be more then an interface or just another exposure of an existing service or application.&lt;br /&gt;&lt;br /&gt;If your service need a database then from an application you would just create a connection using a driver, jdbc-connection and username/password. Probably you would get those values from a property-file. But within an Application Server you would use JNDI to get a DataSource and from that retrieve a Connection.&lt;br /&gt;&lt;br /&gt;But the methods that are called from your services within the application server should somehow get a connection in a uniform manner. Because, how would you determine if the method is called from a running standalone application or from an Application Server? The preferred approach, as I see it, is to make the application in fact agnostic of it. The retrieval of a database connection should in both cases be the same. So how to achieve this?&lt;br /&gt;&lt;br /&gt;The solution that I found is to have the methods retrieve the database connection in all cases from a JNDI Context. To enable this, you should take care of having a DataSource registered upfront, before calling the service-implementing-methods.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JNDI Context&lt;/span&gt;&lt;br /&gt;To understand JNDI you could take a look into the &lt;a href="http://java.sun.com/products/jndi/tutorial/"&gt;JNDI Tutorial&lt;/a&gt;.&lt;br /&gt;It all starts with retrieving a JNDI Context. From a context you could retrieve every type of Object that is registered with it. So it not necessarly be a Database connection or DataSource, although I believe this is one of the most obvious usages of JNDI.&lt;br /&gt;&lt;br /&gt;To retrieve a JNDI Context I create a helper class:&lt;br /&gt;&lt;pre  class="source-western"&gt;&lt;br /&gt;package nl.darwin-it.crmi.jndi;&lt;br /&gt;/**&lt;br /&gt;* Class providing and initializing JndiContext.&lt;br /&gt;*&lt;br /&gt;* @author Martien van den Akker&lt;br /&gt;* @author Darwin IT Professionals&lt;br /&gt;*/&lt;br /&gt;import java.util.Hashtable;&lt;br /&gt;&lt;br /&gt;import javax.naming.Context;&lt;br /&gt;import javax.naming.InitialContext;&lt;br /&gt;import javax.naming.NamingException;&lt;br /&gt;&lt;br /&gt;import nl.darwin-it.crmi.CrmiBase;&lt;br /&gt;&lt;br /&gt;import oracle.jdbc.pool.OracleDataSource;&lt;br /&gt;&lt;br /&gt;public class JndiContextProvider extends CrmiBase {&lt;br /&gt;   public static final String DFT_CONTEXT_FACTORY = "com.sun.jndi.fscontext.RefFSContextFactory";&lt;br /&gt;   public static final String DFT = "Default";&lt;br /&gt;   private Context jndiContext = null;&lt;br /&gt;&lt;br /&gt;   public JndiContextProvider() {&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Get an Initial Context based on the jndiContextFactory. If jndiContextFactory is null&lt;br /&gt;    * the Initial context is fetched from the J2EE environment. Otherwise if jndiContextFactory contains the keyword&lt;br /&gt;    * "Default" (in any case) the DFT_CONTEXT_FACTORY is used as an Initial Context Factory. Otherwise&lt;br /&gt;    * jndiContextFactory is used.&lt;br /&gt;    *&lt;br /&gt;    *&lt;br /&gt;    * @param jndiContextFactory&lt;br /&gt;    * @return&lt;br /&gt;    * @throws NamingException&lt;br /&gt;    */&lt;br /&gt;   public Context getInitialContext() throws NamingException {&lt;br /&gt;       final String methodName = "getInitialContext";&lt;br /&gt;       debug("Start "+methodName);&lt;br /&gt;       Context  ctx = new InitialContext();&lt;br /&gt;       debug("End "+methodName);&lt;br /&gt;       return ctx;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Bind the Oracle Datasource to the JndiName&lt;br /&gt;    * @param ods&lt;br /&gt;    * @param jndiName&lt;br /&gt;    * @throws NamingException&lt;br /&gt;    */&lt;br /&gt;   public void bindOdsWithJNDI(OracleDataSource ods, String jndiName) throws NamingException {&lt;br /&gt;       final String methodName = "bindOdsWithJNDI";&lt;br /&gt;       debug("Start "+methodName);&lt;br /&gt;       //Registering the data source with JNDI&lt;br /&gt;       Context ctx = getJndiContext();&lt;br /&gt;       ctx.bind(jndiName, ods);&lt;br /&gt;       debug("End "+methodName);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Unbind jndiName&lt;br /&gt;    * @param jndiName&lt;br /&gt;    * @throws NamingException&lt;br /&gt;    */&lt;br /&gt;   public void unbindJNDIName(String jndiName) throws NamingException {&lt;br /&gt;       final String methodName = "unbindJNDIName";&lt;br /&gt;       debug("Start "+methodName);&lt;br /&gt;       //UnRegistering the data source with JNDI&lt;br /&gt;       Context ctx = getJndiContext();&lt;br /&gt;       ctx.unbind(jndiName);&lt;br /&gt;       debug("End "+methodName);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Set jndiContext;&lt;br /&gt;    */&lt;br /&gt;   public void setJndiContext(Context jndiContext) {&lt;br /&gt;       this.jndiContext = jndiContext;&lt;br /&gt;   }&lt;br /&gt;   /**&lt;br /&gt;    * Get jndiContext&lt;br /&gt;    */&lt;br /&gt;   public Context getJndiContext() throws NamingException {&lt;br /&gt;   if (jndiContext==null){&lt;br /&gt;       Context context = getInitialContext();&lt;br /&gt;       setJndiContext(context);&lt;br /&gt;   }&lt;br /&gt;       return jndiContext;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This package gives a Jndi Context that can be used to retrieve a DataSource kunt ophalen, using JndiContextProvider.getJndiContext().&lt;br /&gt;This method retrieves an InitialContext that is cached in a private variable.&lt;br /&gt;From within the application server the InitialContext is provided by the Application Server.&lt;br /&gt;But when running as a standalone application a default InitialContext is provided. But this one does not have any content. Also it has no Service Provider that can deliver any objects. You could get an InitialContext by providing the InitialContext() constructor with a hash table with the java.naming.factory.initial property set to com.sun.jndi.fscontext.RefFSContextFactory.&lt;br /&gt;&lt;br /&gt;The problem is that if you use the HashTable option, the getting of the InitialContext is not the same as within the Application Server. Fortunately if you don't provide the HashTable, the constructor is looking for the jndi.properties file, within the classpath. This file can contain several properties, but for our situation only the following is needed:&lt;pre&gt;java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This Context factory is one of the jndi-provider-factories delivered with the standard JNDI implementation. It is a simple FileSystemContextFactory,a JNDI factory that refers to the filesystem.&lt;br /&gt;&lt;br /&gt;Now the only thing you need to do is to bind a DataSource to the Context, right before your call the possible method, for example in the main method of your applicatoin.&lt;br /&gt;That DataSource you should create using the properties from the configuration file.&lt;br /&gt;&lt;br /&gt;To create a datasource I created another helper class: JDBCConnectionProvider:&lt;br /&gt;&lt;pre class="source-western"&gt;&lt;br /&gt;package nl.darwin-it.crmi.jdbc;&lt;br /&gt;/**&lt;br /&gt; * Class providing JdbcConnections&lt;br /&gt; * &lt;br /&gt; * @author Martien van den Akker&lt;br /&gt; * @author Darwin IT Professionals&lt;br /&gt; */&lt;br /&gt;import java.sql.Connection;&lt;br /&gt;import java.sql.DriverManager;&lt;br /&gt;import java.sql.SQLException;&lt;br /&gt;&lt;br /&gt;import java.util.Hashtable;&lt;br /&gt;&lt;br /&gt;import javax.naming.Context;&lt;br /&gt;&lt;br /&gt;import javax.naming.InitialContext;&lt;br /&gt;&lt;br /&gt;import javax.naming.NamingException;&lt;br /&gt;&lt;br /&gt;import javax.naming.NoInitialContextException;&lt;br /&gt;&lt;br /&gt;import oracle.jdbc.pool.OracleDataSource;&lt;br /&gt;&lt;br /&gt;public abstract class JDBCConnectionProvider {&lt;br /&gt;    public static final String ORCL_NET_TNS_ADMIN = "oracle.net.tns_admin";&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Create a database Connection&lt;br /&gt;     * &lt;br /&gt;     * @param connectString&lt;br /&gt;     * @param userName&lt;br /&gt;     * @param Password&lt;br /&gt;     * @return&lt;br /&gt;     * @throws ClassNotFoundException&lt;br /&gt;     * @throws SQLException&lt;br /&gt;     */&lt;br /&gt;    public static Connection createConnection(String driver, String connectString, String userName, &lt;br /&gt;                                              String password) throws ClassNotFoundException, SQLException {&lt;br /&gt;        Connection connection = null;&lt;br /&gt;        Class.forName(driver);&lt;br /&gt;        // DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());&lt;br /&gt;        // @machineName:port:SID, userid, password&lt;br /&gt;        connection = DriverManager.getConnection(connectString, userName, password);&lt;br /&gt;        return connection;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Create a database Connection after setting TNS_ADMIN property.&lt;br /&gt;     * &lt;br /&gt;     * @param driver&lt;br /&gt;     * @param tnsNames&lt;br /&gt;     * @param connectString&lt;br /&gt;     * @param userName&lt;br /&gt;     * @param password&lt;br /&gt;     * @return&lt;br /&gt;     * @throws ClassNotFoundException&lt;br /&gt;     * @throws SQLException&lt;br /&gt;     */&lt;br /&gt;    public static Connection createConnection(String driver, String tnsAdmin, String connectString, String userName, &lt;br /&gt;                                              String password) throws ClassNotFoundException, SQLException {&lt;br /&gt;        if (tnsAdmin != null) {&lt;br /&gt;            System.setProperty(ORCL_NET_TNS_ADMIN, tnsAdmin);&lt;br /&gt;        }&lt;br /&gt;        Connection connection = createConnection(driver, connectString, userName, password);&lt;br /&gt;        return connection;&lt;br /&gt;    }&lt;br /&gt;    /**&lt;br /&gt;     * Create an Oracle DataSource&lt;br /&gt;     * @param driverType&lt;br /&gt;     * @param connectString&lt;br /&gt;     * @param dbUser&lt;br /&gt;     * @param dbPassword&lt;br /&gt;     * @return&lt;br /&gt;     * @throws SQLException&lt;br /&gt;     */&lt;br /&gt;    public static OracleDataSource createDataSource(String driverType, String connectString, String dbUser, &lt;br /&gt;                                                 String dbPassword) throws SQLException {&lt;br /&gt;        OracleDataSource ods = new OracleDataSource();&lt;br /&gt;        ods.setDriverType(driverType);&lt;br /&gt;        ods.setURL(connectString);&lt;br /&gt;        ods.setUser(dbUser);&lt;br /&gt;        ods.setPassword(dbPassword);&lt;br /&gt;        return ods;&lt;br /&gt;    }&lt;br /&gt;    public static Connection getConnection(Context context, String jndiName) throws NamingException, SQLException {&lt;br /&gt;        //Performing a lookup for a pool-enabled data source registered in JNDI tree&lt;br /&gt;        Connection conn = null;&lt;br /&gt;        OracleDataSource ods = (OracleDataSource)context.lookup(jndiName);&lt;br /&gt;        conn = ods.getConnection();&lt;br /&gt;        return conn;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The method createDataSource will create an OracleDataSource. Today with trial&amp;error I discovered that from a BPEL 10.1.2 server, you should get a plain java.sql.DataSource.&lt;br /&gt;&lt;br /&gt;Then with JndiContextProvider.bindOdsWithJNDI(OracleDataSource ods, String jndiName) you can bind the DataSource with the Filesystem Context Provider.&lt;br /&gt;&lt;br /&gt;Having done that from your implementation code you can get a database connection using JDBCConnectionProvider.getConnection(Context context, String jndiName)&lt;br /&gt;&lt;br /&gt;I haven't discovered how yet, but somewhere (in the filesystem I presume) the DataSource is registered. So a subsequent bind will throw an exception. But since you might want to change your connection in your property file, it might be convenient to unbind the DataSource afterwards at the end of the main-method.The method JndiContextProvider.unbindJNDIName(String jndiName) takes care of that.&lt;br /&gt;&lt;br /&gt;What took me also quite a long time to figure out is what jar-files you need to get this working when running in a standalone application. Somehow I found quite a lot examples but no list of jar-files. I even understood (wrongly as it turned out) that the base J2SE5 or 6 should deliver these packages.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The jars you need are: &lt;ul&gt;&lt;li&gt;jndi.jar&lt;/li&gt;&lt;li&gt;fscontext.jar&lt;/li&gt;&lt;li&gt;providerutil.jar&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;You can find them from the   BPEL PM 10.1.2 tree and probably also in a Oracle 10.1.3.x Application Server or Weblogic 10.3 (or nowadays 11g). But the JSE ones can be found via &lt;a href="http://java.sun.com/products/jndi/downloads/index.html"&gt;&lt;br /&gt;http://java.sun.com/products/jndi/downloads/index.html&lt;/a&gt;&lt;br /&gt;There you'll find the following packages: &lt;ul&gt;&lt;li&gt;jndi-1_2_1.zip&lt;/li&gt;&lt;li&gt;fscontext-1_2-beta3.zip&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;This approach gave me a database connection within the application server or from a standalone application. The name of the JNDI I fetched from a property file still. That way it is configurable from which JNDI source the connection have to be fetched (I don't like hardcodings).&lt;br /&gt;In my search I found that from Oracle 11g onwards you can use the Universal Connection Pool library:&lt;a href=" http://www.oracle.com/technology/pub/articles/vasiliev-oracle-jdbc.html"&gt; http://www.oracle.com/technology/pub/articles/vasiliev-oracle-jdbc.html&lt;/a&gt; to have a connection pool from your application.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-366556192807959259?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/366556192807959259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=366556192807959259' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/366556192807959259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/366556192807959259'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/10/jndi-in-your-applications.html' title='JNDI in your Applications'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://4.bp.blogspot.com/_myrkQ5dyTYg/SumoQRjDiqI/AAAAAAAACNY/vz6mJ0PTT5w/S220/MartienInStoomtreinAnduze2009.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4533777417600103698.post-2439591089543842336</id><published>2009-09-21T05:12:00.000-07:00</published><updated>2009-09-21T05:45:42.339-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle AIA'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle BPM Suite'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle BI'/><category scheme='http://www.blogger.com/atom/ns#' term='OPN'/><title type='text'>OPN Bootcamps delivered by Darwin-iT</title><content type='html'>Tomorrow and wednesday (22nd-23th of september) I deliver the first OPN Bootcamp in De Meern, the Netherlands  on Oracle BPM Suite. The course is a two day hands-on workshop on BPM Suite Studio, addressing the basics on developing Business Processes.&lt;br /&gt;There are still seats available so if you would like to join and are in the position to do so then it is still possible. More info on the course is found &lt;a href="http://guest.cvent.com/EVENTS/Info/Summary.aspx?i=38aab592-181d-4e0d-ab88-d7da003eab09"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Other bootcamps in October that will be delivered by us in De Meern are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://guest.cvent.com/EVENTS/Info/Summary.aspx?i=1cc8c5ff-ff97-4b8d-9411-71529d435052"&gt;Oracle BI Enterprise Edition&lt;/a&gt;, on 6 -8 October 2009.&lt;/li&gt;&lt;li&gt;&lt;a href="http://guest.cvent.com/EVENTS/Info/Summary.aspx?i=d771b399-c83b-44f3-b824-cba3e5c60716"&gt;AIA Implementation Boot Camp&lt;/a&gt;, on 27 - 29 October 2009&lt;/li&gt;&lt;/ul&gt;There is a "register now" button on the summary-pages of the boot camps.&lt;br /&gt;The bootcamps are also open for foreign partners, that is foreign to the Netherlands.&lt;br /&gt;We're looking forward to meet you on one of these courses. For Dutch potential participants check-out the training pages on our &lt;a href="http://www.darwin-it.nl"&gt;website&lt;/a&gt; regularly. More detailed info on these courses and more dates planned are expected soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4533777417600103698-2439591089543842336?l=blog.darwin-it.nl' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.darwin-it.nl/feeds/2439591089543842336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4533777417600103698&amp;postID=2439591089543842336' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2439591089543842336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4533777417600103698/posts/default/2439591089543842336'/><link rel='alternate' type='text/html' href='http://blog.darwin-it.nl/2009/09/opn-bootcamp-bpm-suite-delivered-by.html' title='OPN Bootcamps delivered by Darwin-iT'/><author><name>Martien van den Akker</name><uri>http://www.blogger.com/profile/05183907832966359401</uri><email>noreply@blogger.com</email><gd:image rel='
