Sunday, July 31, 2011

ssh connect to host port 22 connection refused

I got this message while trying to ssh into my VMWare Ubuntu 10.4:

ssh connect to host xxx port 22 connection refused

I do this:

sudo apt-get update
sudo apt-get install openssh-server

and.... it works again! cool!


I get the same message with the Oracle VirtualBox Linux: here is a suggested solution

http://www.wiredrevolution.com/virtualbox/setup-ssh-access-between-virtualbox-host-and-guest-vms

it works!

OSB and Log4J

Objective: enable custom logging from OSB with Log4J

Libraries:
in C:\Oracle\Middleware\Oracle_OSB1\lib\external\log4j_1.2.8.jar you find the libraries

OSB Logger code:

package com.acme.osb;

public class OSBLogger {
 static java.util.logging.Logger loggerJava = java.util.logging.Logger.getLogger(OSBLogger.class.getName());
 static org.apache.log4j.Logger loggerLog4j = org.apache.log4j.Logger.getLogger(OSBLogger.class.getName());
 
 public static String logMessage(String message) {
  String messageout = "the message is " + message;
  System.out.println(messageout);
  loggerJava.log(java.util.logging.Level.SEVERE, messageout);
  loggerLog4j.debug("log4j" + messageout);
  return messageout;
 }
 
 public static String reloadConfiguration(String configFilename) throws Exception {
  String messageout = "reloading configuration from " + configFilename;
  System.out.println(messageout);
  URL url = Thread.currentThread().getContextClassLoader().getResource(configFilename);
  if (url == null) {
   throw new IllegalArgumentException("unable to locate resource " + configFilename);
  }
  String file = url.getFile();
  System.out.println("file=" + file);
  BufferedReader in = new BufferedReader(new FileReader(file));
  String text = "";
  while (in.ready()) {
   text = in.readLine();
   System.out.println(text);
  }
  //LogManager.resetConfiguration();
  PropertyConfigurator.configure(url);
  PropertyConfigurator.configureAndWatch(file);
  System.out.println("done reloading");
  return messageout;
 }
 
 
}



Extra configuration:

put your log4j.xml file in $DOMAIN_HOME/config/osb
(another example here)


Log4j 1.2.13 source here

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PropertyConfigurator.html

"The hierarchy will be reset before configuration when log4j.reset=true is present in the properties file. " but this is available only for log4j 1.2.15

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd

This great post on logging best practices

See http://forums.oracle.com/forums/thread.jspa?threadID=932901


My conclusion: configureAndWatch doesn't simply work. I am fed up investigating on this issue. Probably upgrading to the latest version of log4j would help.

I had to add an extra logger:

<logger name="org.apache.commons" additivity="false">
<level value="WARN"/>
<appender-ref ref="FILEAPACHE"/>
</logger>

to avoid my own log file being cluttered by org.apache.commons messages (no clue why they end up in my own com.acme.osb logger).


Appendix: custom xpath definitions:

<?xml version="1.0" encoding="UTF-8"?>
<xpf:xpathFunctions xmlns:xpf="http://www.bea.com/wli/sb/xpath/config">
    <xpf:category id="logMessage">
        <xpf:function>
            <xpf:name>logMessage</xpf:name>
            <xpf:comment>logMessage</xpf:comment>
            <xpf:namespaceURI>http://www.bea.com/xquery/xquery-functions</xpf:namespaceURI>
            <xpf:className>com.acme.osb.OSBLogger</xpf:className>
            <xpf:method>java.lang.String logMessage(java.lang.String)</xpf:method>
            <xpf:isDeterministic>true</xpf:isDeterministic>
            <xpf:scope>Pipeline</xpf:scope>
            <xpf:scope>SplitJoin</xpf:scope>
        </xpf:function>
        <xpf:function>
            <xpf:name>reloadConfiguration</xpf:name>
            <xpf:comment>reloadConfiguration</xpf:comment>
            <xpf:namespaceURI>http://www.bea.com/xquery/xquery-functions</xpf:namespaceURI>
            <xpf:className>com.acme.osb.OSBLogger</xpf:className>
            <xpf:method>java.lang.String reloadConfiguration(java.lang.String)</xpf:method>
            <xpf:isDeterministic>true</xpf:isDeterministic>
            <xpf:scope>Pipeline</xpf:scope>
            <xpf:scope>SplitJoin</xpf:scope>
        </xpf:function>
    </xpf:category>
</xpf:xpathFunctions>




Best XML editor

I have used Altova XML Spy, but it's not free http://www.altova.com/xmlspy.html
I hear good things about Oxygen - also not free http://www.oxygenxml.com/

I have been recommended Komodo Edit http://www.activestate.com/komodo-edit/downloads

I will start using it from today.

Eclipse XML Buddy plugin is so-and-so http://download.cnet.com/XMLBuddy/3000-7241_4-10405546.html

Also Eclipse WTP is so-and.so http://www.eclipse.org/webtools/index.php

As reported in the comments, a star also for  Liquid XML editor ( http://www.liquid-technologies.com/xml-editor.aspx )

Friday, July 29, 2011

ubuntu on vmware: network is unreachable

Crap, yesterday my Ubuntu 10.4 on VMPlayer was working ALMOST filne,
today I get "network is unreachable" whenever I ping anything.
My VM is set to use NAT.

I do:

cat /etc/network/interfaces

auto lo
iface lo inet loopback



hey, where is eth0?

Here some example, so I "chmod 777" and I add to the file:

auto eth0
iface eth0 inet dhcp


and I
sudo /etc/init.d/networking restart
(it takes a while)

(same can be done with the menu Preferences/Network)

This seems to take care of some issues.

OSB find which Proxy Service is being invoked

I am a bit unsure how better to identify the Message Flow which is currently being executed;
The $inbound variable is:

<con:endpoint name="ProxyService$pierreTests$identifyFlow$identifyFlowPS" xmlns:con="http://www.bea.com/wli/sb/context">
      <con:service/>
      <con:transport>
        <con:uri>/pierreTests/identifyFlow/identifyFlowPS</con:uri>
        <con:mode>request-response</con:mode>
         <bla/>
</con:transport>
</con:endpoint>


so, if you use the name attribute of inbound you have this Xquery:


xquery version "1.0" encoding "Cp1252";
(:: pragma  parameter="$anyType1" type="xs:anyType" ::)

declare namespace xf = "http://tempuri.org/PVTests/getOriginFromInbound/";
declare namespace con = "http://www.bea.com/wli/sb/context";
declare namespace tran = "http://www.bea.com/wli/sb/transports";

declare function xf:getEndpointFromInbound($inbound1 as element())
    as xs:string {
       let $myendpoint := $inbound1/./@name
       return
       fn:tokenize($myendpoint, '\$')[last()]
};

declare variable $inbound1 as element() external;

xf:getEndpointFromInbound($inbound1)


result=identifyFlowPS

This method is far better than using the transport/uri, since the latter is present only in HTTP Proxies, while the inbound/@name is present in ALL proxies.

Thursday, July 28, 2011

Oracle Service Bus Configuration Jar Build and Export reloaded

After a lot of tears shed (see here for my previous post)
I have come up with my own version of the OSBExportFromWorkspace tool.

It is really primitive, especially for the way it parses XSDs and WSDLs, but I have successfully used on my project and it worked - besides it's blazing fast and makes no use of external libraries (esp. NO USE OF ECLIPSE-bleah).

Here goes the link to the code.

Of course there are no comments in the code :o) and it's the good old monolithic-all_in_one procedural coding style

WSDL parser reloaded

Here a previous post on the topic

Here the WSDL 1.1 Schema:
http://schemas.xmlsoap.org/wsdl/


Import it into a Eclipse Web Service project (it has all the facets needed for JAXB)
and generate JAXB classes (I use org.example.wsdl package)

Trying to unmarshal a WSDL, I get a

java.lang.ClassCastException: javax.xml.bind.JAXBElement

(see here)

so I choose a better API for Unmarshaller (don(t try to understand; just make it work)


And.... here is the WSDLParser!

In reality as you start working with TDefinitions you realize that it's quite difficult to extract the information you need, because the http://schemas.xmlsoap.org/wsdl schema is VERY abstract.

As usual, simple things made complicated by academics.

Wednesday, July 27, 2011

How to tell if Oracle XE is running on your box

you should have these processes running on your box:


/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/tnslsnr LISTENER -inherit
xe_pmon_XE
xe_psp0_XE
xe_mman_XE
xe_dbw0_XE
xe_lgwr_XE
xe_ckpt_XE
xe_smon_XE
xe_reco_XE
xe_cjq0_XE
xe_mmon_XE
xe_mmnl_XE
xe_d000_XE
xe_s000_XE
xe_s001_XE
xe_s002_XE
xe_s003_XE
xe_qmnc_XE
xe_q000_XE
xe_q001_XE




and if you do
netstat -an | grep 1521
you should get:

tcp 0 0 0.0.0.0:1521 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:54868 127.0.0.1:1521 ESTABLISHED
tcp 0 0 127.0.0.1:1521 127.0.0.1:54868 ESTABLISHED


Tuesday, July 26, 2011

Mysterious new Threads in WebLogic

oracle.dfw.impl.incident


oracle.dfw.incident.FloodController


oracle.dfw.incident.IncidentCreatorThread


for a quick intro to Diagnostic Framework, read here and more in details here



process reaper

for some explanation on this thread, read here

OSB Read Timeout and Connection Timeout, stuck threads

This morning the server was hanging (even sbconsole was not responding) and the automated tests were stuck since little after midnight. Maybe something has happened around midnight on that box.

Since I would much rather have a request fail than hanging forever, I have reviewed all the timeouts associated with my Business Services.

There are 2 parameters:

HTTP Transport Configuration:

Read Timeout (30s default)
"Enter the read timeout interval in seconds.
A zero (0) value indicates no timeout."


Connection Timeout (0=disabled by default)
"Enter the connection timeout interval in seconds. If the timeout expires before the connection can be established, Oracle Service Bus raises a connection error."


see here the Oracle OSB doc.

My threads were stuck waiting for a Response from a Web Service... I wonder why the "Read Timeout" didn't trigger a fault.

This was the complete stacktrace for the stuck thread:
(I see a similar problem reported here)

"[STUCK] ExecuteThread: '30' for queue: 'weblogic.kernel.Default (self-tuning)'" - Thread t@141
   java.lang.Thread.State: WAITING
 at java.lang.Object.wait(Native Method)
 - waiting on <6f34d9fb> (a java.lang.Object)
 at java.lang.Object.wait(Object.java:485)
 at com.bea.wli.sb.pipeline.PipelineContextImpl$SynchronousListener.waitForResponse(PipelineContextImpl.java:1569)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.dispatchSync(PipelineContextImpl.java:553)
 at stages.transform.runtime.WsCalloutRuntimeStep$WsCalloutDispatcher.dispatch(WsCalloutRuntimeStep.java:1391)
 at stages.transform.runtime.WsCalloutRuntimeStep.processMessage(WsCalloutRuntimeStep.java:236)
 at com.bea.wli.sb.pipeline.StatisticUpdaterRuntimeStep.processMessage(StatisticUpdaterRuntimeStep.java:41)
 at com.bea.wli.sb.stages.StageMetadataImpl$WrapperRuntimeStep.processMessage(StageMetadataImpl.java:346)
 at com.bea.wli.sb.pipeline.PipelineStage.processMessage(PipelineStage.java:84)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.execute(PipelineContextImpl.java:1055)
 at com.bea.wli.sb.pipeline.Pipeline.processMessage(Pipeline.java:141)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.execute(PipelineContextImpl.java:1055)
 at com.bea.wli.sb.pipeline.PipelineNode.doRequest(PipelineNode.java:55)
 at com.bea.wli.sb.pipeline.Node.processMessage(Node.java:67)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.execute(PipelineContextImpl.java:1055)
 at com.bea.wli.sb.pipeline.Router.processMessage(Router.java:214)
 at com.bea.wli.sb.pipeline.MessageProcessor.processRequest(MessageProcessor.java:96)
 at com.bea.wli.sb.pipeline.RouterManager$1.run(RouterManager.java:593)
 at com.bea.wli.sb.pipeline.RouterManager$1.run(RouterManager.java:591)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
 at com.bea.wli.sb.security.WLSSecurityContextService.runAs(WLSSecurityContextService.java:55)
 at com.bea.wli.sb.pipeline.RouterManager.processMessage(RouterManager.java:590)
 at com.bea.wli.sb.transports.TransportManagerImpl.receiveMessage(TransportManagerImpl.java:375)
 at com.bea.wli.sb.transports.local.LocalMessageContext$1.run(LocalMessageContext.java:179)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
 at weblogic.security.Security.runAs(Security.java:61)
 at com.bea.wli.sb.transports.local.LocalMessageContext.send(LocalMessageContext.java:174)
 at com.bea.wli.sb.transports.local.LocalTransportProvider.sendMessageAsync(LocalTransportProvider.java:322)
 at sun.reflect.GeneratedMethodAccessor655.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at com.bea.wli.sb.transports.Util$1.invoke(Util.java:83)
 at $Proxy106.sendMessageAsync(Unknown Source)
 at com.bea.wli.sb.transports.LoadBalanceFailoverListener.sendMessageAsync(LoadBalanceFailoverListener.java:148)
 at com.bea.wli.sb.transports.LoadBalanceFailoverListener.sendMessageToServiceAsync(LoadBalanceFailoverListener.java:603)
 at com.bea.wli.sb.transports.LoadBalanceFailoverListener.sendMessageToService(LoadBalanceFailoverListener.java:538)
 at com.bea.wli.sb.transports.TransportManagerImpl.sendMessageToService(TransportManagerImpl.java:558)
 at com.bea.wli.sb.transports.TransportManagerImpl.sendMessageAsync(TransportManagerImpl.java:426)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.doDispatch(PipelineContextImpl.java:670)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.dispatch(PipelineContextImpl.java:585)
 at stages.routing.runtime.DynamicRouteRuntimeStep.processMessage(DynamicRouteRuntimeStep.java:161)
 at com.bea.wli.sb.stages.StageMetadataImpl$WrapperRuntimeStep.processMessage(StageMetadataImpl.java:346)
 at com.bea.wli.sb.pipeline.RouteNode.doRequest(RouteNode.java:106)
 at com.bea.wli.sb.pipeline.Node.processMessage(Node.java:67)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.execute(PipelineContextImpl.java:1055)
 at com.bea.wli.sb.pipeline.Router.processMessage(Router.java:214)
 at com.bea.wli.sb.pipeline.MessageProcessor.processRequest(MessageProcessor.java:96)
 at com.bea.wli.sb.pipeline.RouterManager$1.run(RouterManager.java:593)
 at com.bea.wli.sb.pipeline.RouterManager$1.run(RouterManager.java:591)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
 at com.bea.wli.sb.security.WLSSecurityContextService.runAs(WLSSecurityContextService.java:55)
 at com.bea.wli.sb.pipeline.RouterManager.processMessage(RouterManager.java:590)
 at com.bea.wli.sb.transports.TransportManagerImpl.receiveMessage(TransportManagerImpl.java:375)
 at com.bea.wli.sb.transports.local.LocalMessageContext$1.run(LocalMessageContext.java:179)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
 at weblogic.security.Security.runAs(Security.java:61)
 at com.bea.wli.sb.transports.local.LocalMessageContext.send(LocalMessageContext.java:174)
 at com.bea.wli.sb.transports.local.LocalTransportProvider.sendMessageAsync(LocalTransportProvider.java:322)
 at sun.reflect.GeneratedMethodAccessor655.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at com.bea.wli.sb.transports.Util$1.invoke(Util.java:83)
 at $Proxy106.sendMessageAsync(Unknown Source)
 at com.bea.wli.sb.transports.LoadBalanceFailoverListener.sendMessageAsync(LoadBalanceFailoverListener.java:148)
 at com.bea.wli.sb.transports.LoadBalanceFailoverListener.sendMessageToServiceAsync(LoadBalanceFailoverListener.java:603)
 at com.bea.wli.sb.transports.LoadBalanceFailoverListener.sendMessageToService(LoadBalanceFailoverListener.java:538)
 at com.bea.wli.sb.transports.TransportManagerImpl.sendMessageToService(TransportManagerImpl.java:558)
 at com.bea.wli.sb.transports.TransportManagerImpl.sendMessageAsync(TransportManagerImpl.java:426)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.doDispatch(PipelineContextImpl.java:670)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.dispatch(PipelineContextImpl.java:585)
 at stages.routing.runtime.RouteRuntimeStep.processMessage(RouteRuntimeStep.java:128)
 at com.bea.wli.sb.stages.StageMetadataImpl$WrapperRuntimeStep.processMessage(StageMetadataImpl.java:346)
 at com.bea.wli.sb.pipeline.RouteNode.doRequest(RouteNode.java:106)
 at com.bea.wli.sb.pipeline.Node.processMessage(Node.java:67)
 at com.bea.wli.sb.pipeline.PipelineContextImpl.execute(PipelineContextImpl.java:1055)
 at com.bea.wli.sb.pipeline.Router.processMessage(Router.java:214)
 at com.bea.wli.sb.pipeline.MessageProcessor.processRequest(MessageProcessor.java:96)
 at com.bea.wli.sb.pipeline.RouterManager$1.run(RouterManager.java:593)
 at com.bea.wli.sb.pipeline.RouterManager$1.run(RouterManager.java:591)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
 at com.bea.wli.sb.security.WLSSecurityContextService.runAs(WLSSecurityContextService.java:55)
 at com.bea.wli.sb.pipeline.RouterManager.processMessage(RouterManager.java:590)
 at com.bea.wli.sb.transports.TransportManagerImpl.receiveMessage(TransportManagerImpl.java:375)
 at com.bea.wli.sb.transports.http.generic.RequestHelperBase.invokePipeline(RequestHelperBase.java:179)
 at com.bea.wli.sb.transports.http.wls.HttpTransportServlet$RequestHelperWLS.invokePipeline(HttpTransportServlet.java:227)
 at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:154)
 at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:152)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
 at com.bea.wli.sb.transports.http.generic.RequestHelperBase.securedInvoke(RequestHelperBase.java:151)
 at com.bea.wli.sb.transports.http.generic.RequestHelperBase.service(RequestHelperBase.java:107)
 at com.bea.wli.sb.transports.http.wls.HttpTransportServlet.service(HttpTransportServlet.java:129)
 at weblogic.servlet.FutureResponseServlet.service(FutureResponseServlet.java:24)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
 at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
 at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
 at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
 at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:183)
 at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3717)
 at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
 at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
 at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
 at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
 at weblogic.work.ExecuteThread.execute(ExecuteThread.java:207)
 at weblogic.work.ExecuteThread.run(ExecuteThread.java:176)



Monday, July 25, 2011

Oracle Service Bus Configuration Jar Build and Export

I was wondering how to generate a sbconfig.jar - yes I know there is a ALSBConfigurationMBean API here but it works only if the projects are deployed in OSB, not if they exist in the OEPE workspace.

so while running an Export operation of my projects defined in Eclipse I took this beautiful stacktrace (thank you, VisualVM):


at ZwWaitForSingleObject+21()@0x770BF8C1
    at RtlIntegerToUnicodeString+523()@0x770D8CB8
    at block_for_safepoint+163(safepoint.c:872+10)@0x0232ABA4
    at tsCheckTransitToJava+19(execution.c:236+19)@0x02330944
    at java/util/zip/ZipFile.getEntry(ILjava/lang/String;Z)I(Native Method)
    at java/util/zip/ZipFile.getEntry(ZipFile.java:150)
    at org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleFile.getZipEntry(ZipBundleFile.java:118)
    at org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleFile.getEntry(ZipBundleFile.java:248)
    ^-- Holding lock: org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleFile@0x1193ADF8[thin lock]
    at org/eclipse/osgi/baseadaptor/loader/ClasspathManager.findClassImpl(ClasspathManager.java:531)
    at org/eclipse/osgi/baseadaptor/loader/ClasspathManager.findLocalClassImpl(ClasspathManager.java:481)
    at org/eclipse/osgi/baseadaptor/loader/ClasspathManager.findLocalClass_LockClassLoader(ClasspathManager.java:469)
    ^-- Holding lock: org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader@0x118AF488[recursive]
    at org/eclipse/osgi/baseadaptor/loader/ClasspathManager.findLocalClass(ClasspathManager.java:449)
    at org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
    at org/eclipse/osgi/internal/loader/BundleLoader.findLocalClass(BundleLoader.java:393)
    at org/eclipse/osgi/internal/loader/BundleLoader.findClassInternal(BundleLoader.java:469)
    at org/eclipse/osgi/internal/loader/BundleLoader.findClass(BundleLoader.java:422)
    at org/eclipse/osgi/internal/loader/BundleLoader.findClass(BundleLoader.java:410)
    at org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    at java/lang/ClassLoader.loadClass(ClassLoader.java:248)
    at jrockit/vm/Classes.loadClassInternal(Classes.java:76)
    ^-- Holding lock: org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader@0x118AF488[thin lock]
    at jrockit/vm/RNI.c2java(IIIII)V(Native Method)
    at jrockit/vm/RNI.initializeClass(I)V(Native Method)
    at com/bea/wli/sb/resources/alertdestination/AlertDestinationTypeDef.getPersistedValueRepresentation(AlertDestinationTypeDef.java:574)
    at com/bea/wli/config/persistence/BinaryIndexedFile.getValueRepresentation(BinaryIndexedFile.java:586)
    at com/bea/wli/config/persistence/BinaryIndexedFile.readData(BinaryIndexedFile.java:444)
    at com/bea/wli/config/component/impl/DataCache.evaluateKey(DataCache.java:97)
    at com/bea/wli/config/component/impl/DataCache.evaluateKey(DataCache.java:35)
    at com/bea/wli/config/component/impl/LazyValueCache$DataCacheEntry.evaluate(LazyValueCache.java:30)
    at com/bea/wli/config/component/impl/LazyValue.getValue(LazyValue.java:91)
    at com/bea/wli/config/component/impl/DataCache.getValue(DataCache.java:87)
    at com/bea/wli/config/component/impl/ComponentTypeImpl.getValue(ComponentTypeImpl.java:776)
    at com/bea/wli/config/impl/ConfigContextImpl.getResourceData(ConfigContextImpl.java:899)
    at com/bea/wli/config/importexport/ConfigJar$CanonicalForm.(ConfigJar.java:336)
    at com/bea/wli/config/task/impl/ExportTask._execute(ExportTask.java:172)
    at com/bea/wli/config/task/impl/ExportTask._execute(ExportTask.java:62)
    at com/bea/wli/config/task/impl/SessionedTask$1.execute(SessionedTask.java:233)
    at com/bea/wli/config/transaction/TransactionalTask._doExecute(TransactionalTask.java:217)
    at com/bea/wli/config/transaction/TransactionalTask._doExecuteWithRetry(TransactionalTask.java:162)
    at com/bea/wli/config/transaction/TransactionalTask.doExecute(TransactionalTask.java:142)
    at com/bea/wli/config/task/impl/SessionedTask.doExecute(SessionedTask.java:236)
    at com/bea/wli/config/task/impl/SessionedTask.doExecute(SessionedTask.java:191)
    at com/bea/wli/config/task/impl/ExportTask.exportProjectLevel(ExportTask.java:137)
    at com/bea/wli/config/mbeans/Config.exportProjects(Config.java:482)
    at com/bea/alsb/core/internal/repositories/jar/ConfigFactory.createForProjects(Ljava/util/Collection;Z)[B(Unknown Source)
    at com/bea/alsb/ui/repositories/jar/ConfigJarContentViewer.createJar()[B(Unknown Source)
    at com/bea/alsb/ui/repositories/jar/JarContextWizardPage.createContext()Lcom/bea/alsb/core/repositories/jar/IWorkspaceConfigRepository$IWorkspaceRepositoryContext;(Unknown Source)
    at com/bea/alsb/ui/repositories/jar/JarExportWizard.performFinish()Z(Unknown Source)
    at org/eclipse/jface/wizard/WizardDialog.finishPressed(WizardDialog.java:811)
    at org/eclipse/jface/wizard/WizardDialog.buttonPressed(WizardDialog.java:430)
    at org/eclipse/jface/dialogs/Dialog$2.widgetSelected(Dialog.java:624)
    at org/eclipse/swt/widgets/TypedListener.handleEvent(TypedListener.java:234)
    at org/eclipse/swt/widgets/EventTable.sendEvent(EventTable.java:84)
    at org/eclipse/swt/widgets/Widget.sendEvent(Widget.java:1053)
    at org/eclipse/swt/widgets/Display.runDeferredEvents(Display.java:4066)
    at org/eclipse/swt/widgets/Display.readAndDispatch(Display.java:3657)
    at org/eclipse/jface/window/Window.runEventLoop(Window.java:825)
    at org/eclipse/jface/window/Window.open(Window.java:801)
    at org/eclipse/ui/internal/navigator/wizards/WizardShortcutAction.run(WizardShortcutAction.java:98)
    at org/eclipse/jface/action/Action.runWithEvent(Action.java:498)
    at org/eclipse/jface/action/ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
    at org/eclipse/jface/action/ActionContributionItem.access$2(ActionContributionItem.java:501)
    at org/eclipse/jface/action/ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
    at org/eclipse/swt/widgets/EventTable.sendEvent(EventTable.java:84)
    at org/eclipse/swt/widgets/Widget.sendEvent(Widget.java:1053)
    at org/eclipse/swt/widgets/Display.runDeferredEvents(Display.java:4066)
    at org/eclipse/swt/widgets/Display.readAndDispatch(Display.java:3657)
    at org/eclipse/ui/internal/Workbench.runEventLoop(Workbench.java:2640)
    at org/eclipse/ui/internal/Workbench.runUI(Workbench.java:2604)
    at org/eclipse/ui/internal/Workbench.access$4(Workbench.java:2438)
    at org/eclipse/ui/internal/Workbench$7.run(Workbench.java:671)
    at org/eclipse/core/databinding/observable/Realm.runWithDefault(Realm.java:332)
    at org/eclipse/ui/internal/Workbench.createAndRunWorkbench(Workbench.java:664)
    at org/eclipse/ui/PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at org/eclipse/ui/internal/ide/application/IDEApplication.start(IDEApplication.java:115)
    at org/eclipse/equinox/internal/app/EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org/eclipse/core/runtime/internal/adaptor/EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org/eclipse/core/runtime/internal/adaptor/EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org/eclipse/core/runtime/adaptor/EclipseStarter.run(EclipseStarter.java:369)
    at org/eclipse/core/runtime/adaptor/EclipseStarter.run(EclipseStarter.java:179)
    at jrockit/vm/RNI.c2java(IIIII)V(Native Method)
    at jrockit/vm/Reflect.invokeMethod(Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;(Native Method)
    at sun/reflect/NativeMethodAccessorImpl.invoke0(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;(Native Method)
    at sun/reflect/NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun/reflect/DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java/lang/reflect/Method.invoke(Method.java:597)
    at org/eclipse/equinox/launcher/Main.invokeFramework(Main.java:619)
    at org/eclipse/equinox/launcher/Main.basicRun(Main.java:574)
    at org/eclipse/equinox/launcher/Main.run(Main.java:1407)
    at org/eclipse/equinox/launcher/Main.main(Main.java:1383)
    at jrockit/vm/RNI.c2java(IIIII)V(Native Method)
    -- end of trace



Everything seems to start from com.bea.alsb.ui.repositories.jar.JarExportWizard, which is part of the alsbui.jar (eclipse plugin).

in fact I am trying to generate a sbconfig.jar file directly from the SVN content of the OSB artifacts, without having to do a manual export from Eclipse of from the OSB Web Console....


Anyway here the solution... see the exportFromWorkspace target which uses the com.bea.alsb.core.ConfigExport class... which is documented here ... great job, Edwin.

With the PS3, in the build.xml replace:
org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar
with
org.eclipse.equinox.launcher_1.1.0.v20100507.jar

and:
oepe_11gR1PS2
with
oepe_11gR1PS3

and make sure you DO NOT DELETE your .metadata in the WORKING COPY workspace - otherwise you have to reconstruct it again!


Problem is, the machine where you do the exportFromWorkspace must have OEPE installed - which is normally not part of the server installation for a non-dev environment...


Just to recap, I am reporting the build.property file and the ant task here:


fmw.home=C:/Oracle4/Middleware

wls.username=weblogic
wls.password=welcome1
wls.server=t3://localhost:7009

#properties for workspace export
config.project="OSBConfiguration1"
config.jar=c:/tmp/sbconfigPV.jar
config.subprojects="InterfacesA,InterfacesB,GlobalResources,ATools,MockB"
config.includeDependencies=true
workspace.dir=C:/pierre/workspaceSVN


# export properties  
  
# specify a project or use None  
#export.project=EJB  
export.project=None
export.jar=c:/tmp/exportPV.jar
#export.customFile = c:/temp/cust.xml  
export.customFile=None
  
# import properties  
  
# specify a project or use None  
import.project=None
#import.project=EJB
import.jar=c:/tmp/exportPV.jar
#import.customFile=None  
import.customFile=c:/tmp/cust.xml



and the build.xml

<?xml version="1.0" encoding="windows-1252" ?>
<project name="ConfigExport">

   <property file="./build.properties"/>

   <property name="eclipse.home" value="${fmw.home}/oepe_11gR1PS3"/>
   <property name="weblogic.home" value="${fmw.home}/wlserver_10.3"/>
   <property name="metadata.dir" value="${workspace.dir}/.metadata"/>
   <property name="osb.home" value="${fmw.home}/Oracle_OSB1"/>

   <property name="domain.export.script" value="export.py" />
   <property name="domain.import.script" value="import.py" />


   <target name="exportFromWorkspace">
      <!--delete failonerror="false" includeemptydirs="true"
              dir="${metadata.dir}"/-->
      <java dir="${eclipse.home}"
            jar="${eclipse.home}/plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar" 
            fork="true" failonerror="true" maxmemory="768m">
         <jvmarg line="-XX:MaxPermSize=256m"/>   
         <arg line="-data ${workspace.dir}"/>
         <arg line="-application com.bea.alsb.core.ConfigExport"/>
         <arg line="-configProject ${config.project}"/>
         <arg line="-configJar ${config.jar}"/>
         <arg line="-configSubProjects ${config.subprojects}"/>
         <arg line="-includeDependencies ${config.includeDependencies}"/>
         <sysproperty key="weblogic.home" value="${weblogic.home}"/>
         <sysproperty key="osb.home" value="${osb.home}"/>
         <sysproperty key="osgi.bundlefile.limit" value="500"/>
         <sysproperty key="harvester.home" value="${osb.home}/harvester"/>
         <sysproperty key="osgi.nl" value="en_US"/>
         <sysproperty key="sun.lang.ClassLoader.allowArraySyntax" value="true"/>
      </java>
   </target>
</project>


and it works like magic, even without deleting the .metadata directory...

thank you soooo much Edwin!!!


Incidentally, an attempt to run the task WITHOUT Eclipse (removing the "dir" parameter and providing the JAR as a local copy) aborted with this message:

!SESSION Tue Jul 26 11:47:56 CEST 2011 -----------------------------------------
!ENTRY org.eclipse.equinox.launcher 4 0 2011-07-26 11:47:56.430
!MESSAGE Exception launching the Eclipse Platform:
!STACK
java.lang.RuntimeException: Could not find framework
 at org.eclipse.equinox.launcher.Main.getBootPath(Main.java:975)
 at org.eclipse.equinox.launcher.Main.basicRun(Main.java:554)
 at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
 at org.eclipse.equinox.launcher.Main.main(Main.java:1383)



Conversely, if you copy your workspace and OEPE from your Windows machine to your Linux hudson build server, you might get this:

org.eclipse.equinox.p2.core.ProvisionException: No repository found at file:/opt/app/bla/mumble/oepe_11gR1PS3/C:/Oracle4/Middleware/Oracle_OSB1/eclipse120

try adding an extra / at the end of your workspace.dir variable in build.properties

and if you get

java.lang.RuntimeException: Application "com.bea.alsb.core.ConfigExport" could not be found in the registry

then edit
$ORACLE_HOME/oepe_11gR1PS3/dropins/oracle.osb.ide.link
to point it to your right value (/opt/app/bla/mumble/Oracle_OSB1/eclipse120/)

and make sure the $ORACLE_HOME/Oracle_OSB1/eclipse120/ directory exists with all the plugins



PS for 10.3.5, use

property name="eclipse.home" value="${fmw.home}/oepe_11gR1PS4"

and

jar="${eclipse.home}/plugins/org.eclipse.equinox.launcher_1.1.1.R36x_v20101122_1400.jar"

wlst execfile sys.argv

execfile('import.py')

fails with a exceptions.IndexError because the import.py does a

importToALSBDomain(sys.argv[1])


and nothing is specified for sys.argv[1]

Unfortunately

execfile('import.py import.properties')

doesn't work
IOError: File not found - import.py import.properties (No such file or directory)

nor

execfile('import.py', 'import.properties')

it gives me a
sequence subscript must be integer or slice

(god only knows what it is trying to do)


All in all, it seems that the only way to pass parameters to a script is by invoking it directly from the command line (java weblogic.WLST import.py import.properties)
or using the Ant equivalent.

It could be worse... it could be raining...



Sunday, July 24, 2011

A good manager has to be tactful



Saturday, July 23, 2011

Managing Thread Pools

I have copied and run a sample program as from here

Here is the source code:

http://javatoolsforweblogic.googlecode.com/svn/trunk/Executor/RunnableTester.java

http://javatoolsforweblogic.googlecode.com/svn/trunk/Executor/PrintTask.java


and here the ExecutorService

particularly valuable are the isTerminated() and awaitTermination(long timeout, TimeUnit unit) methods.

Fantastic also the possibilily to submit a task and monitor its execution with a Future object.

There is also an API to schedule a task in the future, without having to use a java.util.Timer or a framework like Quartz:

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html


Anyway using a ThreadPoolExecutor is far superior to allocating and managing directly Threads yourself (never again a new Thread(this) !)

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html

In praise of Far Manager

I personally hate Windows Explorer - it's very unsafe (you can't disable the drag and drop, which is a major source of trouble) and buggish. It lacks even the fundamental feature of displaying 2 directories side by side.

The almost first thing I do when I have a new computer is to install Far Manager
http://www.farmanager.com/download.php?l=en

with its WinSCP plugin.
For those who have used Norton Commander in the old DOS days, it's basically the same.

The WinSCP plugin lets you seamlessly connect to a remote system through SSH and operate as it was a local filesystem - it even acts as a terminal.

Some love Total Commander, my experience still favours Far Manager.

Initiation to GitHub

I was feeling very ignorant because I have never used Git.

Here instructions on how to setup a GitHub client

First I educate myself on Git here.
It's conceptually very clear.

This video is awesome:


I install Git For Windows and follow the tutorial to check in a README file.
Things go smoothly, the only funny thing is that "commit" doesn't actually push data to the GIT server, you must issue "git push origin master" to see changes reflected in the GIT Web Console.

So now I got my GIT initiation and I can boast about it :o)

Wednesday, July 20, 2011

javax.management.NotCompliantMBeanException: MBean class bla does not implement DynamicMBean, neither follows the Standard MBean conventions

javax.management.NotCompliantMBeanException: MBean class com.acme.osb.CachesService does not implement DynamicMBean, neither follows the Standard MBean conventions (javax.management.NotCompliantMBeanException: Class com.acme.osb.CachesService is not a JMX compliant Standard MBean) nor the MXBean conventions (javax.management.NotCompliantMBeanException: com.acme.osb.CachesService: Class com.acme.osb.CachesService is not a JMX compliant MXBean)
at com.sun.jmx.mbeanserver.Introspector.checkCompliance(Introspector.java:160)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:305)
at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:482)



http://download.oracle.com/javase/tutorial/jmx/mbeans/standard.html

"A standard MBean is defined by writing a Java interface called SomethingMBean and a Java class called Something that implements that interface. "


Stupid me, I had an implementation CachesService but the Interface was called CachesServiceIF... I have renamed it to CachesServiceMBean and everything works!

Throwing exceptions in XQuery - fn:error()

Generating proper error messages is the foundation for a well maintainable application.

One should embed proper assertions in XQuery, using fn:error()

See chapter 3 in here http://www.w3.org/TR/xpath-functions/

A (dummy)example is here:

xquery version "1.0" encoding "Cp1252";
(:: pragma parameter="$anyType1" type="xs:anyType" ::)
(:: pragma type="xs:anyType" ::)

declare namespace xf = "http://tempuri.org/PVTests/raiseTest/";

declare function xf:raiseTest($anyType1 as element(*))
as element(*) {
if ($anyType1/id/text() = 23) then
fn:error(xs:QName('localnameblablabla'), '23 is not a good id')
else
};

declare variable $anyType1 as element(*) external;

xf:raiseTest($anyType1)


and you test it with



23




In OSB only the xs:QName($someString) constructor is supported, and the someString must be the localname (don't use a http://acme.com/errorcode1234 style, it will raise an exception)
although the normal QName constructor supports all possible variations:

http://download.oracle.com/javase/1.5.0/docs/api/javax/xml/namespace/QName.html#QName%28java.lang.String,%20java.lang.String,%20java.lang.String%29


Your error handler will receive a fault:

weblogic.xml.query.exceptions.XQueryUserException: line 1, column 1: localnameblablabla: 23 is not a good id:


<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
<con:errorCode>BEA-382510</con:errorCode>
<con:reason>
OSB Assign action failed updating variable "bla": weblogic.xml.query.exceptions.XQueryUserException: line 1, column 1: localnameblablabla: 23 is not a good id
</con:reason>
<con:location>
<con:node>PipelinePairNode1</con:node>
<con:pipeline>PipelinePairNode1_request</con:pipeline>
<con:stage>stage1</con:stage>
<con:path>request-pipeline</con:path>
</con:location>
</con:fault>

How to tell which flavour of Linux I am running

When you telnet, you get it all:

login as: a087
*---------------------------------------*
Host: blahost
Company: ACME
Type: PHYSICAL
Zone: INTRANET
Environment: PRODUCTION
Location: Block

In case of problems, contact
linux@acme.com

*---------------------------------------*
a087@acme.com's password:
Last login: Tue Jul 19 17:20:14 2011 from bla.acme.com
Welcome to blahost.
This system is managed by Puppet 2.6.7.

Running Red Hat Enterprise Linux Server release 5.6 (Tikanga).



also, uname -a tells you a lot:

Linux blahost 2.6.18-238.1.1.el5 #1 SMP Tue Jan 4 13:32:19 EST 2011 x86_64 x86_64 x86_64 GNU/Linux


and in case of RedHat

cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.6 (Tikanga)

otherwise just do
ls /etc/*release

Tuesday, July 19, 2011

This is just too funny

sorry but I have to post it




and these code comments are really hilarious

http://www.javacodegeeks.com/2011/07/funny-source-code-comments.html


and read also there

http://stackoverflow.com/questions/184618/what-is-the-best-comment-in-source-code-you-have-ever-encountered


this one is pure poetry:

/**
* For the brave souls who get this far: You are the chosen ones,
* the valiant knights of programming who toil away, without rest,
* fixing our most awful code. To you, true saviors, kings of men,
* I say this: never gonna give you up, never gonna let you down,
* never gonna run around and desert you. Never gonna make you cry,
* never gonna say goodbye. Never gonna tell a lie and hurt you.
*/

A mini-framework for Performance Monitoring

Minimalistic set of 3 classes:

import java.util.Collection;

public class PerformanceMeasurement {
 
 RecordByTypeContainer recordByTypeContainer = new RecordByTypeContainer();

 public void record(String type, long elapsed) {
  RecordByType recordByType = recordByTypeContainer.getRecordByType(type);
  recordByType.addEntry(elapsed);
 }

 public long averageExecutionTime() {
  long sum = 0;
  for (RecordByType recordByType : recordByTypeContainer.getAllRecordByType()) {
   sum += recordByType.averageExecutionTime();
  }
  return recordByTypeContainer.size() > 0 ? sum / recordByTypeContainer.size() : 0;
 }

 public Collection getRecordByTypes() {
  return recordByTypeContainer.getAllRecordByType();
 }

 public void reset() {
  for (RecordByType recordByType : recordByTypeContainer.getAllRecordByType()) {
   recordByType.clear();
  }  
 }


}






import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

public class RecordByType {
 private String type;
 private List measurements = Collections.synchronizedList(new ArrayList());

 public RecordByType(String type) {
  this.type = type;
 }

 public synchronized void addEntry(long elapsed) {
  measurements.add(elapsed);
 }

 public long averageExecutionTime() {
  long result = 0;
  synchronized (measurements) {
   for (Long item : measurements) {
    result += item;
   }  
  }

  return measurements.size() > 0 ? result / measurements.size() : 0;
 }

 public int numberOfRecordsAboveThreshold(long i) {
  int count = 0;
  synchronized (measurements) {
   for (Long item : measurements) {
    if (item > i)
     count++;
   }
  }
  return count;
 }

 public synchronized void clear() {
  measurements.clear();
 }

 public String getType() {
  return type;
 }

 public void setType(String type) {
  this.type = type;
 }


}




import java.util.Collection;
import java.util.HashMap;

@SuppressWarnings("serial")
public class RecordByTypeContainer extends HashMap {

 public RecordByType getRecordByType(String type) {
  RecordByType result = get(type);
  if (result == null) {
   result = new RecordByType(type);
   this.put(type, result);
  }
  return result;
 }
 
 public Collection getAllRecordByType() {
  return values();
 }

}






How to use it:

// create tooling
static final PerformanceMeasurement performanceMeasurement = new PerformanceMeasurement();


// reset to a know state
performanceMeasurement.reset();


// do all the tests each of which records the elapsed type

long now = System.currentTimeMillis();
// .... RUN YOUR TEST HERE
long elapsed = (System.currentTimeMillis() - now);
performanceMeasurement.record("TEST_TYPE", elapsed);


// print stats or do asserts

assertTrue("global averageExecutionTime", performanceMeasurement.averageExecutionTime() < 1600);


for (RecordByType recordByType : performanceMeasurement.getRecordByTypes()) {
 assertTrue("individual averageExecutionTime for type "  + recordByType.getType(), recordByType.averageExecutionTime() < 1600);

 assertTrue("execution threshold  for type " + recordByType.getType(), recordByType.numberOfRecordsAboveThreshold(2000) < 10);
}



Works like magic!

JMS Resources using JMX

here the original code

here the same code after some fixes

weblogic-wonders.com is a great site for WebLogic users... check out also http://middlewaremagic.com

OutOfMemoryError running Ant from Hudson

java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:640)
at java.util.concurrent.ThreadPoolExecutor.addIfUnderCorePoolSize(ThreadPoolExecutor.java:703)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:652)


Increasing Hudson heap will do no good, since Hudson runs Ant tasks in a separate JVM (I think!).

Rather define

export ANT_OPTS="-Xmx1024m -Xms1024m"

and ant_exec_debug=true



In any case - after a lot of tears and pain - we discovered by running "free" that the Unix box memory was simply totally occupied by running processes.... :o(

Java doesn't differentiate between an OutOfMemory caused by hitting the Heap limit imposed by the -Xms and -Xmx flags, and one caused by hitting physical limits of the host.

Sun JVM heap dump on OutOfMemory

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html


-XX:+HeapDumpOnOutOfMemoryError does the job!!!!


better to add also -XX:HeapDumpPath=/your/path/to/heapdump/dir

(it should be a dir, not a file)


Ad the end of setDomainEnv.sh, put:


if [[ "${SERVER_NAME}" == *as ]]
then
MEM_ARGS="-Xms1g -Xmx1g -XX:MaxPermSize=512m"
else
MEM_ARGS="-Xms2g -Xmx2g -XX:MaxPermSize=768m"
fi

MEM_ARGS="${MEM_ARGS} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${DOMAIN_HOME} -Xloggc:/opt/var/log/weblogic/server/${SERVER_NAME}gc.log"
export JAVA_OPTIONS MEM_ARGS



(this loggc option has the disadvantage that gc of multiple servers ends up in the same file... it can be improved... )

More on Oracle Service Bus Split Join

Unsurprisingly Split Join use some BPEL constructs:

xmlns:bpel="http://docs.oasis-open.org/wsbpel/2.0/process/executable"

bpel:partnerLinks
bpel:variables
bpel:sequence
bpel:receive
and bpel:flow to implement the parallel execution of branches

In fact I can't wait to see the BPEL engine of SOA Suite seamlessly merged into the Oracle Service Bus.




Funny thing is that a SplitJoin is defined only for 1 operation on a target service, but the Business Service you originate from it exposes ALL operations n the WSDL. If by mistake you invoke the wrong operation, you get:

The invocation resulted in an error: Split-Join is configured for operation "bla" but received request for operation "mumble". Make sure the correct operation is selected in route, publish or service callout actions in the proxy message Split-Join..


And unlike in the traditional OSB where you can access a uninitialized variable without getting any error, in BPEL if you forget to assign a value to response you get

[BEA-2031518] Variable 'response' is being referenced before it has been initialized with a value.

OSB Split Join.... Split !Join! Sit!

"Split-Join allows you to send message requests to multiple services concurrently"


This is a Split-Join Halloween dog


The official documentation:

http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/userguide/splitjoin.html

and

http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/eclipsehelp/tasks.html#wp1145066


Designing a split join documentation

What is a Mediator Pattern :

http://en.wikipedia.org/wiki/Mediator_pattern


I have done a quick minimalistic example to test the parallel execution:

http://javatoolsforweblogic.googlecode.com/svn/trunk/OSBArtifacts/OSBSplitJoinExample_sbconfig.jar





simply import the sbconfig.jar, test/debug the BS, enter whatever you want in input, and watch the 3 parallel log statements being executed in no particular order

noNamespaceSchemaLocation

I do an xsd:import

xsd:import namespace="" schemaLocation="bla.xsd"

and bla.xsd doesn't define a namespace for its elements.

No way. I get an error

Imported schema has a target namespace "null" that does not match the specified ""

If you specify a namespace, Eclipse complains that it's different from the one used in bla.xsd.
If you leave it empty, "", still it complains. If you omit the namespace="" clause, again it complains. I have tried xsd:nil, no way.

The only way is to use

xsd:include schemaLocation="bla.xsd"

or

xsd:import xsi:noNamespaceSchemaLocation="bla.xsd"

Monday, July 18, 2011

synchronizedList

I have created an attribute

private List measurements = new ArrayList();

and I keep getting an exception:

java.lang.ArrayIndexOutOfBoundsException: 10
at java.util.ArrayList.add(ArrayList.java:352)


whenever I do

public void addEntry(long elapsed) {
measurements.add(elapsed);
}



In fact, ArrayList constructor does:

public ArrayList() {
this(10);
}


and its "add" method verifies that there is enough capacity:

public boolean add(E e) {
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
}



it is self evident that this code is not thread safe.... so if you plan to use an ArrayList in a concurrent scenario, you better synchronize here and there...
otherwise use http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList%28java.util.List%29

List list = Collections.synchronizedList(new ArrayList());

BPM and VirtualBox

I am reading the book "Getting Started with Oracle BPM Suite 11gR1"

For the tutorials, they point you to this page:

http://www.oracle.com/technetwork/middleware/bpm/learnmore/index.html


Download VirtualBox from here
http://www.virtualbox.org/wiki/Downloads
or here http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html

(in my case, VirtualBox-4.0.12-72916-Win.exe)

Download the VB image as shown here
http://www.oracle.com/technetwork/middleware/soasuite/learnmore/vmsoa-172279.html

it's a HUGE download, each file is 1GB...

Then download the Sales Quote Demo.

When importing the appliance into VirtualBox, I get VERR_VD_VMDK_INVALID_HEADER vbox-oel5u4-soabpm-11gr1ps2-bp1-root.vmdk


Being an idiot, at first I swear against Oracle.... then I check all the MD5 checksums...in fact the vbox-oel5u4-soabpm-11gr1ps2bp1-root.vmdk checksum was wrong.... redownload it again.... the second time around it works!

Importing appliance in VBOX takes forever... 37 minutes.... zzzz...

Once started, it gives me an error about the USB controller.... I disable USB and start again.

Virtual Box captures mouse and keyboard, they say that I should use the "host key" = H0JRE CTRL, no clue what this means.... I panic and finally manage to uncapture by hitting every possible combination of keys.

I get a "memory for crash kernel (0x0 to 0x0) not within permissible range"

I discover that I should "enable IO APIC if you want to run a 64-bit guest"
http://forums.virtualbox.org/viewtopic.php?f=5&t=24988

This is really depressing.

I enable the blessed "IO APIC" in the VM options, and restart.
This time it seems to start.

I get this other message:


I think I can survive to this one.

Login as oracle with password as oracle

and.... lo and behold, I am in!

Sunday, July 17, 2011

What is new in Java 7

http://download.oracle.com/javase/7/docs/technotes/guides/language/enhancements.html


basically, nothing noticeable.
To get something really useful, like CLOSURES, you will have to wait for Java 8

http://en.wikipedia.org/wiki/Java_version_history

Friday, July 15, 2011

Where is Java more popular?

these are the pageviews of my blog (my guess is that almost only people working with Java end up on this blog)

United States
 42,406
India
 14,991
United Kingdom
 6,944
France
 6,556
Germany
 6,446
Canada
 3,490
Spain
 2,319
Netherlands
 2,264
Australia
 1,823
Brazil
 1,303



By far most pageview on this blog are from USA, then India. I am surprised by Brasil, my guess is that soon Brasil will outreach most EU nations.



Bruxelliser

I am glad to see that Urbanists have minted a word to describe the sense of horror and squalor you have while walking in some streets of Bruxelles:

http://fr.wiktionary.org/wiki/bruxelliser

If you go to any other Belgian city, you feel the beauty, the poetry and harmony of the pristine medieval settings.

Here in Bruxelles in the 1960-1970 they covered everything with concrete. Attila would not have done a better job at making sure no grass grows here.



This is Brussels at its best: concrete, grey, dirt, squalor, desert.

I have heard that Amsterdam was about to follow the same destiny, with bulldozers knocking down 400 years old quarters to replace them with concrete blocks and parking lots; but the Dutch people rioted against the speculators, and after many clashes with Police the speculators had to abandon their plans. Kudos, Dutchmen!

The result is that Amsterdam is one of the main tourist destinations in Europe, while Bruxelles is a city where only students and immigrants live, record-high crime and curfew after 7pm. Most Belgians come here only to work, and commute back to a better place to live.

OSB and the Test Message Pattern

I want to be able to treat differently "test" messages from "normal" messages, so as to be able to monitor my application without disrupting the normal business.

Headers are very good at this.

In my test Java client:

HttpPost httppost = new HttpPost(FACADE_URL);
httppost.addHeader("ORIGIN", "TEST");

In my Facade Proxy Service, enable "get all headers".


log $inbound:


  
    
      
        
        Keep-Alive
        102
        text/plain; charset=ISO-8859-1
        acme.com:7009
        Apache-HttpClient/4.1.1 (java 1.5)
      
    
  
  
    
      <anonymous>
    
  
>



The problem is how to propagate the headers to other Proxies (http or local).

Use "Set Transport Headers for outbound Destination" with the option "Pass all Headers through Pipeline" to copy the headers to the destination.
When you route to a LOCAL Proxy Service, the header changes slightly, it uses xsi:type="loc:LocalRequestHeaders" instead of xsi:type="http:HttpRequestHeaders" :


        
        
      


You can extract the header with

$inbound1//tran:user-header[@name="ORIGIN"]


see here for a discussion on the topic, and here for OSB documentation.

Thursday, July 14, 2011

Hudson Fun Plugins

I have installed the following plugins, just for fun:

Hudson Speaks! Plugin http://wiki.hudson-ci.org/display/HUDSON/Hudson+Speaks!+Plugin (first, you must go to the /configure page and test if your server supports sound... unfortunately it doesn't support remote notification on another server...)

Hudson Sounds plugin

Radiator View Plugin http://wiki.hudson-ci.org/display/HUDSON/Radiator+View+Plugin

To enable the Radiator View, click on myViews and add a view of type "Radiator"
(even if you are blind you will see if your build failed)



For sound and tray monitoring, you can still use the CruiseControl trick:

"An alternative to this is to use the CCTray app that comes with CruiseControl.NET and have it monitor your Hudson server. You can set this up on a shared machine or on individual developer machines. To have CCTray monitor Hudson, set it up to monitor a custom URL that looks like http://hudsonserver:hudsonport/hudsonpath/cc.xml

Basically, appending cc.xml to almost any Hudson URL (project, view, etc.) will return an XML document that CCTray can parse. You can then use CCTray to play .wav files, speak, or even control X10 devices.

CCTray is available at http://sourceforge.net/projects/ccnet/files/"


I will do it first thing tomorrow...

Hudson integration with JUnit

my ANT build.xml :




  
      
           
      
  


  
    
      
      
      
          
      
    

    

    
  
  
    
  


 





Once I configure Hudson with a valid ANT installation, running the test produces a
junitreport under the /home/a087/.hudson (hudson's home dir)

In fact the "Publish JUnit test result report " Hudson option accepts the parameter
"Test report XMLs" with the notation **/reports/*.xml relative to the /home/a087/.hudson directory! (it took some time to figure out)

The TESTS-TestSuites.xml file produced contains aggregate info on all the tests run:


  
      
      

      

....

  





And it happily appears on the "Test Result" tab


If you get
Fingerprinting not enabled on this build. Test aggregation requires fingerprinting

in Post-build Actions, enable "Record fingerprints of files to track usage "
and enter **/reports/*.xml in "Files to fingerprint"



More on TESTS-TestSuites.xml and JUnitReport

Hudson Tray Application failing with "multiple points" NumberFormatException

java.lang.NumberFormatException: multiple points
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Float.parseFloat(Unknown Source)
at org.hudson.trayapp.model.Server.isHudsonBuild173orGreater(Server.java:300)



If anybody has a clue, please help.

I was trying to install it from the Hudson Update Center...

Here http://issues.hudson-ci.org/browse/HUDSON-5557?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel it says that you must be logged in in order to make Hudson Tray Application work.... =:o(

I had to "Enable security" in Hudson configuration, "Hudson's own user database"

At this point I login and.... I still get the exception :o(((


Here http://wiki.hudson-ci.org/display/HUDSON/Hudson+Tray+Application is a preview of what I would get if only it was working.

When I click on the link to Issue Tracker I get a "404" at http://java.net/jira/browse/HUDSON

very depressing.... one hour wasted...

OSB Custom XPath: XQuery expression validation failed: {err}FONS0003: : prefix not defined in static context

I have created a Custom XPath function, and the entry in osb-built-in.xml is:


            initTSSArray
            Fills the TSScache with all elements, using Id as a key
            http://acme.com/Nis
            com.acme.osb.CachesService
            java.lang.String initTSSArray(java.lang.String, [Lorg.apache.xmlbeans.XmlObject;)
            true
            Pipeline
            SplitJoin
        



When using the new XPath function, I have to precede it with the Namespace prefix generated by OSB :

nisnx:initTSSArray(...)


Problem is, in Eclipse this nisnx is not defined. So I add nisnx as a static prefix in the Proxy Workflow, and next thing I get is:

XQuery expression validation failed: {err}XQ0017: unknown function (or number of arguments (0) is wrong)

The problem now is how to register the custom function in Eclipse.

I will find out one day....


The official documentation says nothing on the topic:

http://download.oracle.com/docs/cd/E17904_01/doc.1111/e15866/custom_xpath.htm

It turns out that, if Eclipse is installed in
C:\Oracle4\Middleware\oepe_11gR1PS3

you must copy the XML and JAR file to
C:\Oracle4\Middleware\Oracle_OSB1\config\xpath-functions

at this point Eclipse will recognize the Custom XPath functions (after restart and clean).

My problem was that I had deployed the JAR and XML only to my remote installation, not to the local OSB installation. So Eclipse could not see the definition of the XPath Functions.


see also:

http://www.xenta.nl/blog/2010/07/14/oracle-service-bus-custom-xpath-functions-prefix-not-defined-in-static-context/

http://forums.oracle.com/forums/thread.jspa?threadID=1118538&tstart=30

http://www.xenta.nl/blog/2010/05/10/oracle-service-bus-11g-using-custom-xpath-functions/


and watch this cool video


Wednesday, July 13, 2011

JMS: delete (remove) all messages from a JMS Queue

public static final String WEBLOGIC_JMS_XA_CONNECTION_FACTORY = "weblogic/jms/XAConnectionFactory";


 public static Context createInitialContext() throws NamingException {
  Hashtable ht = new Hashtable();
  ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
  ht.put(Context.PROVIDER_URL, "t3://acme.com:7009");     
  Context ctx = new InitialContext(ht);
  return ctx;
 }


 public void init(String jndiname) throws Exception {
  // get the initial context
  Context ctx = createInitialContext();
  // lookup the queue object
  queue = (Queue) ctx.lookup(jndiname);
  
  // lookup the queue connection factory
  queueConnFactory = (QueueConnectionFactory) ctx.lookup(WEBLOGIC_JMS_XA_CONNECTION_FACTORY);
  // create a queue connection
  queueConn = queueConnFactory.createQueueConnection();
  // create a queue session
  queueSession = queueConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
  // create a queue browser
  queueBrowser = queueSession.createBrowser(queue);
  
  // start the connection
  queueConn.start();
 }


 public void deleteAllMessagesFromQueue(String jndiname) throws Exception {
    init(jndiname);
    MessageConsumer consumer = queueSession.createConsumer(queue);
    Message message = null;
    do {
        message = consumer.receiveNoWait();
     if (message != null) message.acknowledge();
    } 
    while (message != null);
  
    consumer.close();
    queueConn.close();
 }






150 thousand visits to this blog!



Jack Daniels - 150th Birthday Flag


To celebrate, I will send a (small) bottle of Jack Daniels to the first person to put a comment on this post - please provide your mailing address (actually, I would rather send you the money, you buy it and drink it to my health)

Eclipse: generate JAXB classes: Please insure that a JAXB implementation is available ....

The classpath for this project does not appear to contain the necessary libraries to proceed with class generation. Please insure that a JAXB implementation is available on the classpath.


What you need is available in a Web Services project:




Quote of the Day

If you really want to do something, you'll find a way. If you don't, you'll find an excuse.

Tuesday, July 12, 2011

XmlObject, XmlCursor and how to replace XPath with "hardcoded" queries

I was under the impression that a given XPath search was too slow, so I implemented the same search in Java.

It's not that difficult.
The main tools are:

a XmlCursor:

XmlCursor cursor = xmlObject.newCursor();

moving to first element inside a node:

cursor.toFirstChild();

moving to a child identified by its QName:

static QName qnameLongNames = new QName("http://acme.com", "LongNames");
boolean found1 = cursor.toChild(qnameLongNames);


eventually using an index if there are multiple elements with same QName:

int count = 0;
boolean found1 = cursor.toChild(qnameLongNames, count);


saving a cursor for later use:

cursor.push();
...do some other navigation with the cursor....
cursor.pop();



get the text of an element:

cursor.getTextValue();

move to adjacent sibling:

cursor.toNextSibling();

With this, you can achieve a lot, and at amazing speed.

Monday, July 11, 2011

IT and the Gulag Archipelago

"Don't ever be the first to stop applauding!"

I am reading The Gulag Archipelago, the book is a bit boring but rich in anecdotes which have some parallel in real life.




Here goes the quote from The Gulag Archipelago:

Here is one vignette from those years as it actually occurred. A district Party conference was under way in Moscow Province. It was presided over by a new secretary of the District Party Committee, replacing one recently arrested. At the conclusion of the conference, a tribute to Comrade Stalin was called for.
Of course, everyone stood up (just as everyone had leaped to his feet during the conference at every mention of his name). The small hall echoed with "stormy applause, rising to an ovation." For three minutes, four minutes, five minutes, the "stormy applause, rising to an ovation," continued. But palms were getting sore and raised arms were already aching. And the older people were panting from exhaustion. It was becoming insufferably silly even to those who really adored Stalin. However, who would dare be the first to stop? The secretary of the District Party Committee could have done it. He was standing on the platform, and it was he who had just called for the ovation. But he was a newcomer. He had taken the place of a man who'd been arrested. He was afraid! After all, NKVD men were standing in the hall applauding and watching to see who quit first! And in that obscure, small hall, unknown to the Leader, the applause went on - six, seven, eight minutes! They were done for! Their goose was cooked! They couldn't stop now till they collapsed with heart attacks! At the rear of the hall, which was crowded, they could of course cheat a bit, clap less frequently, less vigorously, not so eagerly-but up there with the presidium where everyone could see them? The director of the local paper factory, an independent and strong-minded man, stood with the presidium.




Aware of all the falsity and all the impossibility of the situation, he still kept on applauding! Nine minutes! Ten! In anguish he watched the secretary of the District Party Committee, but the latter dared not stop. Insanity! To the last man! With make- believe enthusiasm on their faces, looking at each other with faint hope, the district leaders were just going to go on and on applauding till they fell where they stood, till they were carried out of the hall on stretchers! And even then those who were left would not falter. . . .Then, after eleven minutes, the director of the paper factory assumed a businesslike expression and sat down in his seat. And, oh, a miracle took place! Where had the universal, uninhibited, indescribable enthusiasm gone? To a man, everyone else stopped dead and sat down. They had been saved! The squirrel had been smart enough to jump off his revolving
wheel.

That, however, was how they discovered who the independent people were. And that was how they went about eliminating them. That same night the factory director was arrested. They easily pasted ten years on him on the pretext of something quite different. But after he had signed Form 206, the final document of the interrogation, his interrogator reminded him:
"Don't ever be the first to stop applauding!"

Now that's what Darwin's natural selection is. And that's also how to grind people down with stupidity.




IT Consulting companies in Denmark and Sweden

Please allow me to list here some IT consulting companies operating in Denmark:

www.konsulenter.dk
www.prodata.dk
www.7n.dk
www.scr.dk
www.elanit.dk

this one to advertise yourself as a freelancer:

http://www.findfreelancer.dk/

and Sweden:


www.eworks.se

Denmark and Sweden offer excellent salaries and working conditions,
the only blocker being the language and the weather in winter ...
I was in Copenhagen in March and the lakes were covered with ice.... brrrrr....
but in summer it's the Garden of Earthly Delight

Managing concurrent R/W access to a single resource

I have a cache which can be reloaded by client threads.
The problem is to avoid having 2 (or 20!) threads reloading it at the same time.

The solution is pretty simple:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

....

private static final Lock lock = new ReentrantLock();

public static boolean acquireLock() throws InterruptedException {
return lock.tryLock(TIMEOUT_FOR_LOCK, TimeUnit.SECONDS);
}


public static String releaseLock() {
lock.unlock();
return "OK";
}


And I have exposed these 2 functions as custom XPaths.

In my pipeline, I acquire the lock, then check again if the cache still needs to be reloaded (it might have been reloaded while trying to acquire the lock!)...

VERY important:

a) remember to release the lock, under all circumstances (i.e. do it also in error handler)
b) don't put your acquireLock in a synchronized method, otherwise a deadlock is guaranteed

There might be a case where a thread acquires the lock and then dies without executing the error handler... in this case, the lock will NEVER be released.
I still must think about this scenario, very unlikely but you never know...

Oracle books at Packtpub

http://www.packtpub.com/article/50th-oracle-book-offer


"To celebrate the publication of its 50th Oracle book, Packt is offering a series of attractive discounts on all Oracle books.

Buy any Oracle print book and get 20% off
Buy any Oracle eBook and get 30% off"


They ask to spread the word, which I gladly do.

XQuery, convert a dateTime into a date

Stealing almost all the code from http://www.xqueryfunctions.com/xq/fn_year-from-datetime.html I managed to convert a dateTime into a date (dateTimeToDate)...

guys, this is insane...

declare namespace functx = "http://www.functx.com";

declare function functx:repeat-string
( $stringToRepeat as xs:string? ,
$count as xs:integer ) as xs:string {

string-join((for $i in 1 to $count return $stringToRepeat),
'')
} ;

declare function functx:pad-integer-to-length
( $integerToPad as xs:integer? ,
$length as xs:integer ) as xs:string {

if ($length < string-length(string($integerToPad))) then error(xs:QName('functx:Integer_Longer_Than_Length')) else concat (functx:repeat-string( '0',$length - string-length(string($integerToPad))), string($integerToPad)) } ; declare function functx:date ( $year as xs:integer , $month as xs:integer , $day as xs:integer) as xs:date { xs:date( concat( functx:pad-integer-to-length(xs:integer($year),4),'-', functx:pad-integer-to-length(xs:integer($month),2),'-', functx:pad-integer-to-length(xs:integer($day),2))) } ; declare function functx:dateTimeToDate($dateTime1 as xs:dateTime) as xs:date {
functx:date(fn:year-from-dateTime($dateTime1), fn:month-from-dateTime($dateTime1), fn:day-from-dateTime($dateTime1))
};



There is this alternative way, slightly simpler :o)

xs:date(substring-before($dateTime,'T'))

(thanks David for the suggestion, it helps a lot!)

Organizational Charts





I don't know it's true, but I love making fun of Microsoft

(reblogged from http://www.bonkersworld.net )

Optional Attributes in XQuery

I have to return some optional attributes in a XQuery.
There are too many of them, so I cannot return a separate XML for each case. Things have to be done dynamically.

This post explains how:

http://forums.oracle.com/forums/thread.jspa?threadID=785203&tstart=1335

It works like a charm! Yet I wish there was a simpler way...in fact there is, just use Groovy XmlBuilder :o)

Thursday, July 7, 2011

OSB, side effects of caching Xqueries

One instance of "com.bea.wli.config.derivedcache.DerivedCache" loaded by "sun.misc.Launcher$AppClassLoader @ 0x7812ef450" occupies 1,090,992,792 (72.62%) bytes. The memory is accumulated in one instance of "weblogic.xml.query.xdbcimpl.XQueryPreparedStatementImpl" loaded by "sun.misc.Launcher$AppClassLoader @ 0x7812ef450".


apparently, OSB internally "precompiles" and caches XQuery, which sound pretty reasonable for performance issues.

The side effect is that, if your XQuery is nothing but a huge XML, the format by which this XML is saved in memory is very inefficient.

Our XQuery was simply returning a 10k elements XML, each element being 1K, so a total of 10M on file.

This XQuery ends up taking 1GB of memory, and the performance of my server drops dramatically because very less RAM is available afterwards.

If took a heap dump and Eclipse MAT to discover that.

I think in future we will do a Java Callout returning the content of a file, and converting it to XmlObject with fn-bea:inlinedXML() - that should not put anything in a Cache!

updates: in the custom XPath I read a xml file (. path is relative to user.dir = domain home), using XmlObject.parse(File), and returing XmlObject to OSB.... it works very well without any caching side effect.

This inspires me an interesting pattern: in my Mock Service, I use the unique ID of the request to identify a specific XML file on disk (eg id=408 retrieves file train408.xml). This will enable us to easily serve different data for different IDs.

OSB encoding in XQuery

All the XQuery files in $domain/osb/config/core are stored in UFT-8 encoding:

?xml version="1.0" encoding="UFT-8"?

When you edit the XQuery through the OSB console, the application will take care of encoding weird characters (â, é, ü...) into a sequence of bytes (3 bytes, I guess).

If you have to edit manually the XQuery, and deploy it directly, YOU are responsible to encode the file.

The simplest option is to use Notepad++ and do Encode/Convert to UTF-8

If you deploy the XQuery with improper encoding, the server will not even start and throw horrible UTF8Decoder exceptions (!!!!).


Another alternative for encoding could be using the "file" Linux utility, but I haven't tested this.

http://mindspill.net/computing/linux-notes/determine-and-change-file-character-encoding.html

Wednesday, July 6, 2011

OSB executing XQuery defined in an external file

Let's admit it, support for reusability of XQuery code is EXTREMELY limited in OSB.
One has to play some trick.

One of them is using custom XPath function - defined in Java - and read and execute dynamically a XQuery, binding parameters dynamically.

Example:

This is the Java code:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;


static String BASE_DIR = "/path/to/config/osb/";

public static XmlObject trainWithParams(XmlObject[] parameters, String[] name) throws Exception {
String xquery = readFile(BASE_DIR + "train.xq"); 
XmlOptions options = new XmlOptions();
// see http://xmlbeans.apache.org/docs/2.2.0/reference/org/apache/xmlbeans/XmlOptions.html#setXqueryVariables%28java.util.Map%29
Map map = new HashMap();
for (int i = 0; i < name.length; i++) {
   map.put(name[i], parameters[i]);
  }
  options.setXqueryVariables(map);
  return runXQuery(xquery, options)[0];
}


private static XmlObject[] runXQuery(String xquery, XmlOptions options) {
  XmlObject xmlObject = XmlObject.Factory.newInstance();
  XmlObject[] results = xmlObject.execQuery(xquery, options);
  return results;
} 



private static String readFile(String fFileName) throws Exception {
  StringBuilder text = new StringBuilder();
  String NL = System.getProperty("line.separator");
  Scanner scanner = new Scanner(new FileInputStream(fFileName));
  try {
   while (scanner.hasNextLine()){
    text.append(scanner.nextLine() + NL);
   }
  }
  finally{
   scanner.close();
  }
  return text.toString(); 
}

This is the entry in the osb-built-in.xml

trainWithParams
Run a XQuery function returning XmlObject, passing many parameters
http://acme.com
com.acme.osb.XQueryExecutor
org.apache.xmlbeans.XmlObject trainWithParams([Lorg.apache.xmlbeans.XmlObject;, [Ljava.lang.String;)
true
Pipeline
SplitJoin
        




and this is how to invoke it from any XQuery context in OSB:

return acmxk:trainWithParams(($Train), ('Train'))


You can chain multiple parameters:

return acmxk:trainWithParams(($Train, $Bus), ('Train', 'Bus'))



Of course you can pass the Xquery file name in the call itself, by adding an extra parameter to the signature.

I am not sure if the XQuery will be recompiled every time, or it the XQuery engine keeps a cache. This mechanism exists in SQL engines, perhaps it's there also in XQuery engines.

Also I don't know if this compiled statement caching is in place for all XQuery defined in OSB.