Saturday, July 31, 2010

Bash shell tricks

Tarring files recursively with filter

to create:
find . -name *.out | xargs tar cvf cohservernodes.tar

to append:
find . -name *.log | xargs tar rvf cohservernodes.tar

to list:
tar tf cohservernodes.tar


Find a text in files, recursively:

find . | xargs grep -s whatever



find and replace recursively

for file in $(grep -il "whatever" *.txt)
do
sed -e "s/Hello/Goodbye/ig" $file > /tmp/tempfile.tmp
mv /tmp/tempfile.tmp $file
done

how about:

perl -p -i -e 's/oldstring/newstring/g' `find ./ -name *.html`

the above command works very well, but if you try

perl -p -i -e 's/oldstring/newstring/g' `find ./ -name *`

you get the error:

Can't do inplace edit: bla is not a regular file, <> line

because it tries to change also the directories

To do a find excluding directories you must do this (add -type f):

perl -p -i -e 's/oldstring/newstring/g' `find ./ -name * -type f`

Thursday, July 29, 2010

Eclipse Tigris plugin and built-in plugin

Apparently there is a conflict when you install Tigris plugin on top of Eclipse:

http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA

I click on "accept license" and it doesn't proceed.

If you remove these jars (put them in a directory different from C:\bea11\oepe_11gR1PS2\plugin), and you restart, Tigris allows you to proceed.


org.eclipse.team.svn.core.nl1_0.7.9.I20100512-1900.jar
org.eclipse.team.svn.core_0.7.9.I20100512-1900.jar
org.eclipse.team.svn.help_0.7.9.I20100512-1900.jar
org.eclipse.team.svn.nl1_0.7.9.I20100512-1900.jar
org.eclipse.team.svn.resource.ignore.rules.jdt_0.7.9.I20100512-1900.jar
org.eclipse.team.svn.revision.graph_0.7.9.I20100512-1900.jar
org.eclipse.team.svn.ui.nl1_0.7.9.I20100512-1900.jar
org.eclipse.team.svn.ui_0.7.9.I20100512-1900.jar
org.eclipse.team.svn_0.7.9.I20100512-1900.jar


Tuesday, July 27, 2010

Dynamically Populating Java Beans with some data

Very often one needs to populate a bean with some dummy data. It's EXTREMELY boring to do it manually.

This is only the first cut of a utility to do it in an automated way:



TAGD result = new TAGD();

Map properties = BeanUtils.describe(result);

for (Object property : properties.keySet()) {

BeanUtils.setProperty(result, property.toString(), property.toString());

}

return result;



This works only if you have only strings in the bean.

BeanUtils is from Apache Commons.

Sunday, July 25, 2010

Shell script to find all ports open by WL servers running

ST is a string which distinguishes all servers belonging to a ST domain


for i in `ps -ef | grep java | grep -v grep | grep ST | awk '{print $2}'`
do
    netstat -nap | grep "$i" | grep java
done


Ten most important aspects of life in IT

http://www.taylor.se/reddit.html

just sharing these pearls of wisdom:

Object orientation is much harder than you think
The difficult part of software development is communication
Learn to say no
If everything is equally important, then nothing is important
Don't over-think a problem
Dive really deep into something, but don't get hung up
Learn about the other parts of the software development machine
Your colleagues are your best teachers
It all comes down to working software
Some people are assholes

OSB presentation by its creators

Oracle Service Bus 11g—Extending Oracle SOA Suite Leadership


http://w.on24.com/r.htm?e=228299&s=1&k=E2F7C1598E122A01954E6E39F141F85B


not a technical analysis, but extremely interesting to get familiar with the architectural mumbo jumbo:

the cloud of service providers
mission critical infrastructure
center of excellence
performance degradation in use of Internet communication
scalability
agility
service enablement
brittle architecture
redundant services
shared services infrastructure
reusable service
mediating interactions
service virtualization
failover
reduce risk
offload repetitive load

process management
long lived process orchestration

Monday, July 19, 2010

MFL+JAXB versus pure Java parsing

Disclaimer:   this test was done in Eclipse using WLXT. The test proves to be INCREDIBLY slower compared to running the same MFL transformation inside OSB. In fact, inside OSB reading 418 binary files (5 KB each) and writing them in XML format took roughly 8 seconds - a LOT better than the 155 seconds using WLST.
I am curious now to understand where lies the HUGE difference in performance of the Format Builder libraries when run in OSB and in Eclipse.

Morale: don't benchmark MFL using a out of container test.

I have 417 files containing "binary" messages, fixed length fields, to be parsed into Java objects. Each file is some 5 KB each. Total some 2 MB.

Doing the transformation:
Binary -> XML (with MFL) followed by
XML -> Java (with JAXB)

inside Eclipse takes a whopping 157 seconds, out of which 101 in MFL and 56 in JAXB.
The same transformation run on a OSB proxy service takes some 5 seconds (!!!).

Doing the transformation Binary -> Java directly in Java takes 3.5 seconds - that is some 50 times faster. I assume the memory garbage produced would be also immensely lower by parsing directly in Java.

The Java parser took 4 hours to build and test. MFL took 2 hours to make and 2 hours to troubleshoot.

Saturday, July 17, 2010

JPA and primary key sequence generation

Nothing is easy...

I do:
create sequence GEO_MESSAGES_LOG_SEQ;

and I assign the primary key as "sequence generated".
This entails these annotations:

@Id
@SequenceGenerator(name="GEO_MESSAGES_LOG_ID_GENERATOR", sequenceName="GEO_MESSAGES_LOG_SEQ", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="GEO_MESSAGES_LOG_ID_GENERATOR")


I immediately get this error:

Exception [TOPLINK-7027]

Exception Description: The sequence named [GEO_MESSAGES_LOG_SEQ] is setup incorrectly. Its increment does not match its pre-allocation size.



in @SequenceGenerator I add allocationSize=1

and things magically work... I suspect performance will not be great...

JPA persistence: a wrapper to make your life a bit easier

EntityManager is not exactly the friendliest beast... it acts of its own will, and its inferface is very restricted to few methods.

Here
http://javatoolsforweblogic.googlecode.com/svn/trunk/JPAPersistence/GEOPersistenceHandler.java

and here
http://javatoolsforweblogic.googlecode.com/svn/trunk/JPAPersistence/GEOPersistenceHandlerTest.java

a wrapper to enable you to use the JPA interface with more understandeable behaviour.

"Force" means: insert if it doesn't exist, update if it exists
"Insert" means: insert if it doesn't exist, exception if it exists
"Update" means: update if it exist, exception if it doesn't exist
"Delete" means: delete if it exist, exception if it doesn't exist

Implementing inheritance in XSDs

this structure:


 



 
  
  
  
   
    

   
   
  
   



will generate this Java code:

@XmlType(name = "TAG")
public class TAG {


}

@XmlRootElement(name = "TAGA")

public class TAGA
    extends TAG
{
    @XmlElement(name = "TransactionType", required = true)
    protected String transactionType;

}



This is an excellent way to model in XSD while keeping good OO practices.

You can also factor out in TAG the elements common to all subclasses, exactly as you should do in Java. Be careful with sequence ordering though.

Friday, July 16, 2010

How to recover weblogic password - or encrypt a password

Put the SerializedSystemIni.dat in the current directory.

run
java weblogic.WLST

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

import weblogic.security.internal.SerializedSystemIni
import weblogic.security.internal.encryption.ClearOrEncryptedService

es=weblogic.security.internal.SerializedSystemIni.getEncryptionService(".")
ces=weblogic.security.internal.encryption.ClearOrEncryptedService(es)
ces.decrypt("{AES}9P7z/8D7ccvDWhBmqa0NEhR1b65BlFuBeVQ3WpwJHTI=")
'weblogic'
ces.decrypt("{AES}Tlxc7yoE4BGQS2k5XBsMX/Kx4XgEBAcPqzXH7PP5zSI=")
'weblogic22'



the 2 strings used as parameters to decrypt should be copied from boot.properties file

very appreciated courtesy of Simon Vans-Colina


You could receive this exception:

weblogic.security.internal.encryption.EncryptionServiceException: weblogic.security.internal.encryption.EncryptionServiceException: com.rsa.jsafe.JSAFE_PaddingException: Could not perform unpadding: invalid pad byte.

In this case, I have no clue.


An alternative approach could be this:

http://weblogictips.wordpress.com/wls-security/

just replacing the LDIF file with a brand new one


To encrypt a paassword:

dom
cd bin
. ./setDomainEnv.sh
java weblogic.security.Encrypt
Password: (enter password here)
{AES}aRC9klq8c5CljKpshacfrsc7WFNB49mfQG+MtuCDgFg=

you can now use the AES password in all weblogic files.

HookedJarClassLoader.assertOpen

In a Java Callout in OSB I get this.... no clue why... no trace in google..


java.lang.IllegalStateException: Already closed
 at com.bea.wli.sb.resources.archive.classloader.HookedJarClassLoader.assertOpen(HookedJarClassLoader.java:345)
 at com.bea.wli.sb.resources.archive.classloader.HookedJarClassLoader.getResource(HookedJarClassLoader.java:174)
 at com.tangosol.util.ExternalizableHelper.loadResource(ExternalizableHelper.java:3020)
 at com.tangosol.io.pof.ConfigurablePofContext.loadResource(ConfigurablePofContext.java:1224)
 at com.tangosol.io.pof.ConfigurablePofContext.createPofConfig(ConfigurablePofContext.java:792)
 at com.tangosol.io.pof.ConfigurablePofContext.initialize(ConfigurablePofContext.java:754)
 at com.tangosol.io.pof.ConfigurablePofContext.setContextClassLoader(ConfigurablePofContext.java:324)
 at com.tangosol.coherence.component.util.daemon.queueProcessor.Service.ensureSerializer(Service.CDB:45)

investigating...

Five things to avoid in SOA....

Funny speech and politically incorrect...
Here is his blog http://www.infoworld.com/blogs/dave-linthicum


VDA= Vendor Driven Architecture

Rabbit Consulting.... you bring in a couple of guys from a consulting company, then 2 more show up, then 4, then 6...

Architecture is not something to BUY, it's something to BUILD, there is no magic bullet... it takes a lot of hard work.













Thursday, July 15, 2010

VMWare and Ubuntu

Download image here
http://www.thoughtpolice.co.uk/vmware/

login as notroot thoughtpolice
ctrl-alt-del to exit if you are in full screen mode
ctrl-g and ctrl-alt to get or lose focus

to become root:
sudo su
root ubuntu


to add users:
adduser osbuser


More info (copied from their website):

Change default language for the console:

1. Edit /home/USERNAME/.bash_profile
2. Add the line export LANG=de (example given for German)

Change keyboard for the console:
sudo dpkg-reconfigure console-setup

Apply software updates
sudo aptitude update # refresh apt's cache
sudo aptitude upgrade # run the upgrade

Install new software
sudo aptitude update # refresh apt's cache
aptitude search pkgnames # lists all available software containing
aptitude search pkgnames | grep -i WORD # lists all software containing WORD
sudo aptitude install PACKAGE # installs PACKAGE (found from list above)

Where is the GUI?
It's not installed. This is a server installation. If you still want a gui, run:
sudo aptitude install xorg gnome

Planning Poker

http://www.planningpoker.com/

I highlight here some interesting sentences. The idea is that, during a session of poker planning, you do not discuss but simply mechanically throw an estimate, you have missed the goal of the exercise. The goal IS the estimate but most of all the open exchange of ideas on the story.



After a period of discussion, each participant chooses from his own deck the numbered card that represents his estimate of how much work is involved in the story under discussion.


It allows, or forces, people to voice their opinions, thoughts and concerns.




...they can talk and discuss the story...


...it lets the people who are actually going to be completing the work do the estimating. Estimates derived from Planning Poker are more accurate because of the emphasis on lively discussion and the fact that estimators are called upon by their peers to justify their estimates....



On the same topic, http://en.wikipedia.org/wiki/Planning_poker highlights the importance of Planning Poker to avoid ANCHORING, that is everyone aligning on the estimate expressed by an influential member of the team. When you express an estimate, you should MOTIVATE it with some rational thinking.

Wednesday, July 14, 2010

Deprecating the OSB EJB Business Service plugin for Eclipse

in favour of the well tested Web Console sbconsole.


After having used the Eclipse plugin for EJB BS I am under PTSD - my hands are shaking and I can hardly think of something motivating me to keep working with OSB.
The plugin is incredibly slow, it overrides continuously any change you make, it gives strange errors  which go away after you restart eclipse, it is simply a nightmare.

Luckily the SB Web Console is a very well tested product.

Edit your BS in sbconsole and then import it into Eclipse. If you do the other way round, you will face the 1000 cuts death.

Troubleshooting JPA with Eclipse and Toplink

The error messages provided by JPA demand some interpretation.

Case 1: wrong persistence unit name

make sure that in persistence.xml the persistence-unit name matches what you use in your code, otherwise you get this error:

javax.persistence.PersistenceException: No Persistence provider for EntityManager named GEO_OSB_Persistences:  The following providers:
oracle.toplink.essentials.PersistenceProvider
org.eclipse.persistence.jpa.PersistenceProvider
oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
Returned null to createEntityManagerFactory.

 at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:154)


Case 2: you did not specify correctly the jta-data-source properties in persistence.xml

SEVERE: Exception in PersistenceManager.getEntityManager: Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0 (Build b41-beta2 (03/30/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
Error Code: 0


well, in my case it was because I was using as provider Toplink but the properties were still the Eclipse ones:

eclipselink.jdbc.url instead of toplink.jdbc.url

Monday, July 12, 2010

The DB is the foundation

Call me archaic or protozoic, but I still believe that the design of any application starts from the DB.

I like to get the DB structure first, then do:

for all columns:

select * FROM USER_TAB_COLUMNS;

for all tables:

select unique(table_name) FROM USER_TAB_COLUMNS;

you can stick the result in an Excel and generate from it plenty of useful stuff...

Sunday, July 11, 2010

OSB: passing a OSB variable to a Java Callout

If you declare a Java static function with an input parameter of type Employee, and your $body contains a valid Employee structure, and you try to pass it to the Java callout as it is, you will get a wonderful:

Value of type 'org.apache.xmlbeans.impl.values.XmlAnyTypeImpl' cannot be type-cast to Employee

The reason being that internally OSB represents every variable (including $body) as a
https://www.docjar.com/docs/api/org/apache/xmlbeans/impl/values/XmlAnyTypeImpl.html

which implements the XmlObject interface, as specified here in the OSB Java Callout doc:

http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/eclipsehelp/ui_ref.html#sj_uiSplitJoinJavaCalloutProperties



No fear! In your Java code, you can use my fantastic XMLLoader class, do a toString on the XmlObject and parse it into the Java class using JAXB:

http://javatoolsforweblogic.googlecode.com/svn/trunk/xmlLoader/XMLLoader.java

Saturday, July 10, 2010

Coherence tutorial

The Coherence tutorial starts here, it's really good:

http://download.oracle.com/docs/cd/E14526_01/coh.350/e14527/installcoh.htm

Here is a list of points and concepts to retain:

cache servers

define COHERENCE_HOME

cache-server.cmd

coherence.jar!/tangosol-coherence.xml
coherence.jar!/tangosol-coherence-override-dev.xml

custom-mbeans.xml

coherence.cmd = cache client
Map(?)
enter help
enter cache mycache

-Dtangosol.coherence.distributed.localstorage=true
-Dtangosol.coherence.cacheconfig=contacts-cache-config.xml




NamedCache interface
mycache is defined in coherence-cache-config.xml

in tangosol-coherence.xml you find tangosol.coherence.clusteraddress and port

NamedCache
CacheFactory
CacheService

PortableObject (POF: PofReader PofWriter, optimized serialization algorythm)



More on Coherence:
http://www.oracle.com/technology/pub/articles/vohra-coherence.html

replicated cache (fast read, slow write)
distributed (partitioned) cache

OSB export in Eclipse fails: org.eclipse.core.runtime.AssertionFailedException: null argument

I have reorganized my stuff in folders, and here is what I get...
the amount of time wasted and frustration accumulated using this Eclipse Plugin for OSB is simply overwhelming....

Even if I create an empty project in a new configuration, it fails export with the same message...

I am trying a "eclipse -clean", and then reimporting an old version of the same project after deleting the "refactored" one.... this seems to fix the problem.


!ENTRY org.eclipse.ui 4 0 2010-07-10 13:40:56.302
!MESSAGE Unhandled event loop exception
!STACK 0
org.eclipse.core.runtime.AssertionFailedException: null argument:
 at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
 at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
 at org.eclipse.jface.viewers.StructuredViewer.assertElementsNotNull(StructuredViewer.java:593)
 at org.eclipse.jface.viewers.StructuredViewer.getRawChildren(StructuredViewer.java:960)
 at org.eclipse.jface.viewers.ColumnViewer.getRawChildren(ColumnViewer.java:703)
 at org.eclipse.jface.viewers.AbstractTreeViewer.getRawChildren(AbstractTreeViewer.java:1330)
 at org.eclipse.jface.viewers.TreeViewer.getRawChildren(TreeViewer.java:390)
 at org.eclipse.jface.viewers.AbstractTreeViewer.getFilteredChildren(AbstractTreeViewer.java:636)
 at org.eclipse.jface.viewers.AbstractTreeViewer.getSortedChildren(AbstractTreeViewer.java:602)
 at org.eclipse.jface.viewers.AbstractTreeViewer$1.run(AbstractTreeViewer.java:799)
 at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
 at org.eclipse.jface.viewers.AbstractTreeViewer.createChildren(AbstractTreeViewer.java:776)
 at org.eclipse.jface.viewers.TreeViewer.createChildren(TreeViewer.java:640)
 at org.eclipse.jface.viewers.AbstractTreeViewer.internalInitializeTree(AbstractTreeViewer.java:1490)
 at org.eclipse.jface.viewers.TreeViewer.internalInitializeTree(TreeViewer.java:829)
 at org.eclipse.jface.viewers.AbstractTreeViewer$5.run(AbstractTreeViewer.java:1474)
 at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1392)
 at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:402)
 at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1354)
 at org.eclipse.jface.viewers.CheckboxTreeViewer.preservingSelection(CheckboxTreeViewer.java:418)
 at org.eclipse.jface.viewers.AbstractTreeViewer.inputChanged(AbstractTreeViewer.java:1480)
 at org.eclipse.jface.viewers.ContentViewer.setInput(ContentViewer.java:275)
 at org.eclipse.jface.viewers.StructuredViewer.setInput(StructuredViewer.java:1639)
 at com.bea.alsb.ui.repositories.jar.ConfigJarContentViewer.onContainerChanged(Unknown Source)
 at com.bea.alsb.ui.repositories.jar.ConfigJarContentViewer.access$1(Unknown Source)
 at com.bea.alsb.ui.repositories.jar.ConfigJarContentViewer$1.propertyChange(Unknown Source)
 at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:339)
 at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:347)
 at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:278)
 at com.bea.alsb.ui.containers.selection.ContainerSelector.fireSelectionEvent(Unknown Source)
 at com.bea.alsb.ui.containers.selection.ContainerSelector.setSelectedContainer(Unknown Source)
 at com.bea.alsb.ui.repositories.jar.ConfigJarContentViewer.(Unknown Source)
 at com.bea.alsb.ui.repositories.jar.JarContextWizardPage.createResourcesGroup(Unknown Source)
 at com.bea.alsb.ui.repositories.jar.JarContextWizardPage.createControls(Unknown Source)
 at com.bea.alsb.ui.repositories.common.BaseWizardPage.createControl(Unknown Source)
 at com.bea.alsb.ui.repositories.jar.JarContextWizardPage.createControl(Unknown Source)
 at org.eclipse.jface.wizard.WizardDialog.updateForPage(WizardDialog.java:1161)
 at org.eclipse.jface.wizard.WizardDialog.access$2(WizardDialog.java:1149)
 at org.eclipse.jface.wizard.WizardDialog$5.run(WizardDialog.java:1139)
 at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
 at org.eclipse.jface.wizard.WizardDialog.showPage(WizardDialog.java:1136)
 at org.eclipse.jface.wizard.WizardDialog.nextPressed(WizardDialog.java:831)
 at org.eclipse.jface.wizard.WizardDialog.buttonPressed(WizardDialog.java:369)
 at org.eclipse.jface.dialogs.Dialog$2.widgetSelected(Dialog.java:625)
 at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:229)
 at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
 at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
 at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3910)
 at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3504)
 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.handlers.WizardHandler$Export.executeHandler(WizardHandler.java:98)
 at org.eclipse.ui.internal.handlers.WizardHandler.execute(WizardHandler.java:273)
 at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:294)
 at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
 at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
 at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
 at org.eclipse.ui.internal.handlers.SlaveHandlerService.executeCommand(SlaveHandlerService.java:241)
 at org.eclipse.ui.internal.actions.CommandAction.runWithEvent(CommandAction.java:157)
 at org.eclipse.ui.internal.actions.CommandAction.run(CommandAction.java:172)
 at org.eclipse.ui.actions.ExportResourcesAction.run(ExportResourcesAction.java:117)
 at org.eclipse.ui.actions.BaseSelectionListenerAction.runWithEvent(BaseSelectionListenerAction.java:168)
 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:1003)
 at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3910)
 at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3504)
 at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405)
 at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369)
 at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221)
 at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
 at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
 at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
 at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
 at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:119)
 at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
 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:368)
 at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(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:559)
 at org.eclipse.equinox.launcher.Main.basicRun(Main.java:515)
 at org.eclipse.equinox.launcher.Main.run(Main.java:1312)
 at org.eclipse.equinox.launcher.Main.main(Main.java:1287)



Friday, July 9, 2010

Unable to activate changes in a WebLogic console session

If one of the servers in the cluster is in an inconsistent state (FAILED, ADMIN),
you might find out that the "changes activation" will hang forever, with no error message.

Workaround:

a) don't fail servers :o)
b) if you have failed servers, before you make any configuration change shut them down

How to merge jar files

I have done that painfully by hand as a part of a delivery process, then I have discovered that in Ant the "jar" task can do that for you:

This will merge source1.jar and source2.jar into target.jar


 
     
       
     
     
    
     
     
  





Wednesday, July 7, 2010

OSB, Coherence threads

I am getting familiar now with the new Threads which appear in a Thread Dump when the built-in Coherence clustering is activated:

Here are the Thread names... they are a LOT!

Logger@9257178 3.5.3/465p2 (com/tangosol/coherence/component/util/Daemon.onWait(Daemon.CDB:18))

PacketListener1 (com/tangosol/coherence/component/net/socket/UdpSocket.receive(UdpSocket.CDB:20))

PacketListenerN (com/tangosol/coherence/component/net/socket/UdpSocket.receive(UdpSocket.CDB:20))


PacketReceiver (com/tangosol/coherence/component/util/daemon/queueProcessor/packetProcessor/PacketReceiver.onWait(PacketReceiver.CDB:2))

PacketPublisher (com/tangosol/coherence/component/util/daemon/queueProcessor/packetProcessor/PacketPublisher.onWait(PacketPublisher.CDB:2))


PacketSpeaker (com/tangosol/coherence/component/util/queue/ConcurrentQueue.remove(ConcurrentQueue.CDB:7))


Cluster|Member(Id=1....) (com/tangosol/coherence/component/util/daemon/queueProcessor/service/Grid.onWait(Grid.CDB:6))


TcpRingListener  (com/tangosol/coherence/component/net/socket/TcpSocketAccepter.accept(TcpSocketAccepter.CDB:18))


Invocation:Management:EventDispatcher (com/tangosol/coherence/component/util/daemon/queueProcessor/Service$EventDispatcher.onWait(Service.CDB:7))


Invocation:Management (com/tangosol/coherence/component/util/daemon/queueProcessor/service/Grid.onWait(Grid.CDB:6))


DistributedCache:ORA-OSB-deployments  (com/tangosol/coherence/component/util/daemon/queueProcessor/service/Grid.onWait(Grid.CDB:6))



Unix redirection

command 2>&1 > output.log (stdout and error to output.log)
command 2> output.log (error to output.log, stdout to console)
command 1> output.log 2> error.log (error to error.log, stdout to output.log)


Tuesday, July 6, 2010

OSB: Changing the JNDIProvider for EJB

This is what happens if you change target to a EJB, then upgrade the JNDIProvider to point to the new target.... it looks like OSB is caching the remote reference to the EJB, and doesn't clear the cache when you change the JNDIProvider... this doesn't happen so often, but still it's an operational issue and the only workaround I could figure out is restarting the Admin and the MS!
The other solution is to disable JNDI Cache on the JNDIProvider.



 
  env:Server
  Failed to invoke end component com.bea.wli.sb.transports.ejb.Jws (POJO), operation=getLocationsByName
 -> Failed to invoke method
 -> The object identified by: '324' could not be found.  Either it was has not been exported or it has been collected by
 the distributed garbage collector.; nested exception is: java.rmi.NoSuchObjectException: The object identified by: '324
' could not be found.  Either it was has not been exported or it has been collected by the distributed garbage collector
.
  
   javax.ejb.EJBException: The object identified by: '324' could not be found.  Eit
her it was has not been exported or it has been collected by the distributed garbage collector.; nested exception is: ja
va.rmi.NoSuchObjectException: The object identified by: '324' could not be found.  Either it was has not been exported o
r it has been collected by the distributed garbage collector.
java.rmi.NoSuchObjectException: The object identified by: '324' could not be found.  Either it was has not been exported
 or it has been collected by the distributed garbage collector.
  
 




Monday, July 5, 2010

OSB: The import failed with exception: com.bea.wli.config.component.NotFoundException: Failed to create temporary jar file

The import failed with exception: com.bea.wli.config.component.NotFoundException: Failed to create temporary jar file

 
This happens in Linux.

This thread http://forums.oracle.com/forums/message.jspa?messageID=4390710#4390710 covers the issue, with no solution.

Here same thing:
http://forums.oracle.com/forums/thread.jspa?threadID=1092747&tstart=30

The full stacktrace is:

Caused By: java.io.IOException: Permission denied
 at java.io.UnixFileSystem.createFileExclusively(Native Method)
 at java.io.File.checkAndCreate(File.java:1704)
 at java.io.File.createTempFile(File.java:1792)
 at com.bea.wli.sb.util.IOUtils.storeToTempFile(IOUtils.java:245)
 at com.bea.wli.sb.resources.archive.classloader.ArchiveClassLoaderDerivedTypeDef.computeData(ArchiveClassLoaderDerivedTypeDef.java:120)
 at com.bea.wli.sb.resources.archive.classloader.ArchiveClassLoaderDerivedTypeDef.computeData(ArchiveClassLoaderDerivedTypeDef.java:34)
 at com.bea.wli.config.derivedcache.DerivedCache.deriveTheValue(DerivedCache.java:453)
 at com.bea.wli.config.derivedcache.DerivedCache.get(DerivedCache.java:273)
 at com.bea.wli.config.derivedcache.DerivedResourceManager.getDerivedValueInfo(DerivedResourceManager.java:341)
 at com.bea.wli.config.derivedcache.DerivedResourceManager.get(DerivedResourceManager.java:386)
 at com.bea.wli.sb.resources.cache.DefaultDerivedTypeDef.getDerivedValue(DefaultDerivedTypeDef.java:106)
 at com.bea.wli.sb.resources.archive.classloader.ArchiveClassLoaderCache.get(ArchiveClassLoaderCache.java:38)
 at com.bea.wli.sb.resources.archive.summary.ArchiveSummaryDerivedTypeDef.computeData(ArchiveSummaryDerivedTypeDef.java:46)
 at com.bea.wli.sb.resources.archive.summary.ArchiveSummaryDerivedTypeDef.computeData(ArchiveSummaryDerivedTypeDef.java:23)
 at com.bea.wli.config.derivedcache.DerivedCache.deriveTheValue(DerivedCache.java:453)
 at com.bea.wli.config.derivedcache.DerivedCache.get(DerivedCache.java:273)
 at com.bea.wli.config.derivedcache.DerivedResourceManager.getDerivedValueInfo(DerivedResourceManager.java:341)
 at com.bea.wli.config.derivedcache.DerivedResourceManager.get(DerivedResourceManager.java:386)
 at com.bea.wli.sb.resources.cache.DefaultDerivedTypeDef.getDerivedValue(DefaultDerivedTypeDef.java:106)
 at com.bea.wli.sb.resources.archive.summary.ArchiveSummaryCache.getArchiveSummary(ArchiveSummaryCache.java:31)
 at com.bea.wli.sb.resources.archive.ArchiveResourceTypeDef.validate(ArchiveResourceTypeDef.java:85)
 at com.bea.wli.config.validation.ResourceValidator.validateContents(ResourceValidator.java:118)
 at com.bea.wli.config.validation.ResourceValidator.call(ResourceValidator.java:64)
 at com.bea.wli.config.validation.SequentialValidator.validate(SequentialValidator.java:34)
 at com.bea.wli.config.validation.ValidationService.validate(ValidationService.java:171)
 at com.bea.wli.config.impl.CoreToSessionPropagator.doValidation(CoreToSessionPropagator.java:239)
 at com.bea.wli.config.impl.CoreToSessionPropagator.handleBeforePrepare(CoreToSessionPropagator.java:118)
 at com.bea.wli.config.impl.CoreToSessionPropagator.beforePrepare(CoreToSessionPropagator.java:77)
 at com.bea.wli.config.transaction.TransactionListenerWrapper.beforePrepare(TransactionListenerWrapper.java:64)
 at com.bea.wli.config.transaction.TransactionManager.notifyBeforePrepare(TransactionManager.java:1094)
 at com.bea.wli.config.transaction.TransactionManager._prepareForCommit(TransactionManager.java:654)
 at com.bea.wli.config.transaction.TransactionManager.endTransaction(TransactionManager.java:782)
 at com.bea.wli.config.transaction.TransactionalTask._doExecute(TransactionalTask.java:226)
 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.ImportTask.doImport(ImportTask.java:114)
 at com.bea.wli.config.mbeans.Config.importUploaded(Config.java:467)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(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 com.bea.alsb.console.support.ConsoleSideMBeanInvocationHandler.__invoke(ConsoleSideMBeanInvocationHandler.java:113)
 at com.bea.alsb.console.support.ConsoleSideMBeanInvocationHandler.invoke(ConsoleSideMBeanInvocationHandler.java:71)
 at $Proxy183.importUploaded(Unknown Source)
 at com.bea.alsb.console.deployment.actions.UpdateImportRepositoryAction.execute(UpdateImportRepositoryAction.java:181)
 at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)




This http://java.sun.com/javase/6/docs/api/java/io/File.html#createTempFile%28java.lang.String,%20java.lang.String%29

tells me that we are trying to write to the "default temporary directory"...

http://www.idevelopment.info/data/Programming/java/io/Files/CreateTemporaryFile.java

The default temporary-file directory is specified by the system property java.io.tmpdir. On UNIX systems the default value of this property is typically "/tmp" or "/var/tmp"; on Win32 systems it is typically "c:\\temp".


Most likely your /tmp/alsbTempJars has a owner different from the user that starts WebLogic.


See here http://download.oracle.com/docs/cd/E14148_02/wlcp/ocsg41_otn/installguide/soa-install.html

After installing Oracle Service Bus on a UNIX or Linux system, make sure that the directory /tmp/alsbTempJars has the same access privileges as the BEA Home directory. Alternatively, remove the directory /tmp/alsbTempJars after the installation if the directory exists.

Architectus Reloadus and Architectus Oryzus

http://martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf

funny and thought-provoking.... the kind of IT literature I like the most...

"Software is not limited by physics, like
buildings are. It is limited by imagination,
by design, by organization. In
short, it is limited by properties of people,
not by properties of the world."

"I think that one of an architect’s
most important tasks is to remove
architecture by finding ways to eliminate
irreversibility in software designs."

How brilliantly thought and expressed!

Enterprise Integration Patterns

I have bought the PAPER book, so I can read it in the park...

http://www.eaipatterns.com/

by Gregor Hohpe

I really love this book, it's an endless source of inspiration.
Germans really excel at classification, they are braniacs!
We Italians excel at fantasy instead.

Here http://camel.apache.org/enterprise-integration-patterns.html a very good list of these patterns and how to use them.

I would like to share some very meaningful phrases:

"The solution is not the first approach that comes in mind, but one that has evolved through actual use over time" (preface).






Toplink

In Eclipse Workshop 11g, just do a New Project / JPA and follow the wizard.
It's excellent and it builds all Java classes from DB Schema.

Here some info on how to handle entities in JPA:
http://www.oracle.com/technology/products/ias/toplink/jpa/howto/create-modify-delete.html



If you want to ose other tools (not recommended)

Download:
http://www.oracle.com/technology/products/ias/toplink/index.html

Tutorial standalone:
http://www.oracle.com/technology/products/ias/toplink/doc/11110/tutorial/intro/standalone/intro_tutorial.htm



Run Workbench :
C:\apps\toplink_111130_en\utils\workbench\workbench.cmd

Unfortunately Workbench is not JPA aware.

This http://download.oracle.com/docs/cd/E13224_01/wlw/docs103/guide/ormworkbench/conGeneratingEJB3Mappings.html#creating_mappings_from_schema will explain you how to generate the JPA annotated Java classes from an existing database schema.


This is a JDeveloper demo on JPA
http://www.oracle.com/technology/products/jdev/viewlets/1013/ejb_30_viewlet_swf.html

An interesting JPA plugin for Eclipse (99 USD)
http://objectgeneration.com/eclipse/index.html

EclipseLink gives you JPA in Eclipse
http://wiki.eclipse.org/EclipseLink



Now let's setup a standalone application; I am using a schema SCOTT with username SCOTT and password TIGER on my local machine

CREATE TABLE test_entity  (
    entity_id               NUMBER(10),
    entity_name             VARCHAR2(30),
    entity_description      VARCHAR2(50)
);



The JPA entity class:

package my.entity;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Id;

/** JPA Annotation linking DB table to Java Class. */
@Entity
@Table(name = "TEST_ENTITY", schema = "SCOTT")

public class TestEntity implements Serializable {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The testEntity id. */
    @Id
    @Column(name = "ENTITY_ID")
    private int entityId;

    /** The testEntity name. */
    @Column(name = "ENTITY_NAME")
    private String entityName;

    /** The testEntity description. */
    @Column(name = "ENTITY_DESCRIPTION")
    private String entityDescription;

    /**
     * Instantiates a new testEntity.
     */
    public TestEntity() {}

    /**
     * Setter for the testEntity variable.
     *
     * @param entityId - the new value
     */
    public void setTestEntityId(int entityId) {
        this.entityId = entityId;
    }

    /**
     * Getter for the testEntity variable.
     *
     * @return int
     */
    public int getEntityId() {
        return entityId;
    }

    /**
     * Setter for the entityName variable.
     *
     * @param entityName - the new value
     */
    public void setEntityName(String entityName) {
        this.entityName = entityName;
    }

    /**
     * Getter for entityName variable.
     *
     * @return String
     */
    public String getEntityName() {
        return entityName;
    }

    /**
     * Setter for entityDescription variable.
     *
     * @param entityDescription - the new value
     */
    public void setEntityDescription(String entityDescription) {
        this.entityDescription = entityDescription;
    }

    /**
     * Gettter for entityDescription variable.
     *
     * @return String
     */
    public String getEntityDescription() {
        return entityDescription;
    }

}




use these jars:
commons-logging-api.jar
commons-logging.jar
odbc14.jar
toplink-essentials.jar


the persistence.xml should be:


   
    oracle.toplink.essentials.PersistenceProvider
    jdbc/localXE
    my.entity.TestEntity
    
      
      
      
      
      
      
      
      
      
      
    
  



and this is the test client:


package my.entity;

import java.io.Serializable;

import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityNotFoundException;
import javax.persistence.Persistence;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class TestEntityHandler implements Serializable {

    /** Default Serial Version UID. */
    private static final long serialVersionUID = 1L;

    /** The Default Class LOGGER. */
    private static final Log LOGGER = LogFactory.getFactory().getInstance(
            TestEntityHandler.class.getName());

    /** The entity manager factory. */
    private static EntityManagerFactory entityManagerFactory = null;

    /** The Entity Manager for JAXB container managed persistence. */
    protected EntityManager em = null;

    /** The testEntity. */
    private TestEntity testEntity = null;

    /**
     * Public constructor.
     */
    public TestEntityHandler() { testEntity = new TestEntity(); }

    /**
     * Initialise and return the JAXB EntityManager to be used by this Class instance.
     *
     * @return - a valid [initialised] EntityManager instance
     */
    private EntityManager initialiseEntityManager() {
        try {
            if (em == null) {
                em = getEntityManager();
                LOGGER.info("Initialised Entity Manager: " + em);
            }
        } catch (Exception e) {
            LOGGER.error("Failed to initialise EntityManager instance! ... " + e, e);
        }
        return em;
    }

    /**
     * Persist a new instance of the Entity.
     */
    public void create() {
        initialiseEntityManager();
        em.getTransaction().begin();
        em.persist(testEntity);
        em.getTransaction().commit();
        //em.close();
    }

    /**
     * Persist updated details of an existing instance of the Entity.
     */
    public void update() {
        initialiseEntityManager();
        em.getTransaction().begin();
        em.merge(testEntity);
        em.getTransaction().commit();
        // This next step should not be necessary; but sometimes update is not propagated !??
        em.getTransaction().begin();
        refreshEntity(testEntity);
        em.getTransaction().commit();
        //em.close();
    }

    /**
     * Delete an existing instance of the Entity from the system.
     */
    public void delete() {
        initialiseEntityManager();
        em.getTransaction().begin();
        em.remove(testEntity);
        em.getTransaction().commit();
        //em.close();
    }


    /**
     * Gets the testEntity.
     *
     * @return the testEntity
     */
    public TestEntity getTestEntity() {
        return testEntity;
    }

    /**
     * Sets the testEntity.
     *
     * @param testEntity_ the new testEntity
     */
    public void setTestEntity(TestEntity testEntity_) {
        this.testEntity = testEntity_;
    }

    // Everything below belongs in other Class(es), reproduced here for simplicity.

    /**
     * Gets the entity manager.
     *
     * @return the entity manager
     */
    private EntityManager getEntityManager () {
        try {
            if (entityManagerFactory == null) {
                LOGGER.info("Attempting to create EntityManger ... ");
                Map override = new HashMap();
                // Override the provider used for persistence
                override.put("provider", "oracle.toplink.essentials.PersistenceProvider");
                // This name must correspond to value in META-INF/persistence.xml
                entityManagerFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");
            }

            EntityManager entityManager = null;
            entityManager = entityManagerFactory.createEntityManager();
            LOGGER.info("Returning EntityManger instance:= " + entityManager);
            return entityManager;
        } catch (Exception e) {
            LOGGER.error("Exception in PersistenceManager.getEntityManager: " + e, e);
        }
        return null;
    }

    /**
     * Refresh the entity from database.
     *
     * @param TestEntity - abstract class (substituted at runtime) that is to be refreshed
     */
    protected void refreshEntity(TestEntity testEntity) {
        try {
              em.refresh(testEntity);
            } catch(EntityNotFoundException ex){
              LOGGER.debug("Failed to refresh entity; this may not be a problem");
            }
    }

    /**
     * Close the EntityManager instance.
     */
    public void closeEM() {
        em.close();
    }

    public static void main(String args[]) {
        TestEntityHandler testEntityHandler = new TestEntityHandler();
        TestEntity testEntity = new TestEntity();
        testEntity.setTestEntityId(500);
        testEntity.setEntityName("PierreLuigi");
        testEntity.setEntityDescription("This is a test");
        testEntityHandler.setTestEntity(testEntity);
        testEntityHandler.create();
        LOGGER.info("Created new TestEntity; check database now ... ");

        try {
            Thread.sleep(10000);
            LOGGER.info("Resuming ... ");
        } catch(InterruptedException e) {
            e.printStackTrace();
        }

        // Before continuing check database to ensure that object was created.

        testEntity.setEntityName("PierreLuigi Vernetto");
        testEntityHandler.setTestEntity(testEntity);
        testEntityHandler.getTestEntity().setEntityDescription("This is a second test (UPDATE)");
        testEntityHandler.update();
        LOGGER.info("Updated new TestEntity; check database now ... ");

        try {
            Thread.sleep(10000);
            LOGGER.info("Resuming ... ");
        } catch(InterruptedException e) {
            e.printStackTrace();
        }


        // Before continuing check database to ensure that object was updated.

        testEntity.setEntityName("Pierluigi Vernetto is stupid");
        testEntity.setEntityDescription("This is a second test (UPDATE)");
        testEntityHandler.delete();
        LOGGER.info("Deleted new TestEntity.");

        testEntityHandler.closeEM();

        // Now check that the object was deleted.

    }
}




Sunday, July 4, 2010

OSB: error handling, fault

First read the posts of my friend Jan and of Eric Elzinga (whom I have never had the pleasure to meet).

Here http://www.javamonamour.org/2010/04/soap-fault-in-osb.html I have taken some notes.

Here a full explanation on the topic:
http://download.oracle.com/docs/cd/E14571_01/doc.1111/e15867/modelingmessageflow.htm#i1040168


When a fault is handled in the fault handler, you have this:

$body

<env:Body xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 <env:Fault>
  <faultcode>env:Server</faultcode>
  <faultstring/>
  <detail>
   <java:CacheStateException xmlns:java="java:com.acme.cache.commons">
    <java:CacheName>geo-data-geographic-area</java:CacheName>
    <java:Status>Not initialized</java:Status>
   </java:CacheStateException>
  </detail>
 </env:Fault>
</env:Body>


$fault

<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
 <con:errorCode>BEA-380001</con:errorCode>
 <con:location>
  <con:node>RouteNodeToEJBBS</con:node>
  <con:path>response-pipeline</con:path>
 </con:location>
</con:fault>

Not necessarily "reason" and "details" are populated! Details should be retrieved from the $body variable. Reason is nowhere to be found.

(see also here http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/userguide/context.html#wp1051816 for $fault definition)


To access individual info in the fault:
$fault/ctx:errorCode/text()

Error codes are here http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/consolehelp/errorcodes.html

NB:
the body uses the namespace http://schemas.xmlsoap.org/soap/envelope/
here http://schemas.xmlsoap.org/soap/envelope/ you can find the XSD for the env:Fault

the fault uses the namespace http://www.bea.com/wli/sb/context



If you terminate the Error Handler with "Reply with failure", you return a HTTP 500 status. In SOAPUI, in the response panel click in RAW, you will see "HTTP/1.1 500 Internal Server Error".

The ambiguity is that if you get a fault internal to OSB - rather than from an external service - the $body doesn't contain the fault, but rather the original request message. In this case the $fault will contain the info required:

<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
 <con:errorCode>BEA-382513</con:errorCode>
 <con:reason>OSB Replace action failed updating variable "body": Error parsing XML: {err}XP0006: "text '
      '": bad value for type element {http://www.acme.com/schema/GeoServicePS/v1}getLocationsByLocationIds { {http://www.w3.
org/2001/XMLSchema}anyType }</con:reason>
 <con:location>
  <con:node>RouteNodeToEJBBS</con:node>
  <con:path>request-pipeline</con:path>
 </con:location>
</con:fault>

The rule for a "universal error handler" could be:
merge whatever information comes from $body (if it's a env:Fault) and from $fault, to build a meaningful env:Fault object to return to the caller with a HTTP 500 status.


This can be used to merge env:Fault and ctx:fault into a meaningful env:Fault:

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

declare namespace xf = "http://tempuri.org/GEO_OSB_MARIA_EJBProxyProject/XQ/generateFault/";
declare namespace env = "http://schemas.xmlsoap.org/soap/envelope/";
declare namespace con = "http://www.bea.com/wli/sb/context";

declare function xf:generateFault($theBody as element(*),
    $theFault as element(*))
    as element(*) {
  
   
    {fn:concat($theBody/env:Fault/faultcode/text(), ' ', $theFault/con:errorCode/text())}
    {fn:concat($theBody/env:Fault/faultstring/text(), ' ' , $theFault/con:reason/text())}
    
    {$theBody/env:Fault/detail/*} { $theFault/con:location} 
   
  
  
};

declare variable $theBody as element(*) external;
declare variable $theFault as element(*) external;

xf:generateFault($theBody, $theFault) 



Using Axis2 as a client, during unmarshalling of the response Axis will generate a org.apache.axis2.AxisFault Java exception upon reception of a env:Fault in the body;
reason, code and details are populated.
This is optional and can be disabled.
All this takes place in Axis2 kernel, org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(...)


When unittesting for SOAP Fault, assert that an AxisFault exception is generated.

SOAPUI, JUnit and functional tests

Lovely tutorials by Meera Subbarao on SOAP-UI for functional tests:

http://soa.dzone.com/articles/functional-web-services-1

http://soa.dzone.com/articles/draft-functional-web-services--0

http://soa.dzone.com/articles/functional-web-services-testin-1


More here
http://www.soapui.org/Getting-Started/functional-testing.html

and with Maven:

http://technology.amis.nl/blog/7408/automatic-testing-oracle-service-bus-using-hudson-maven-and-soapui



On running SOAPUI tests from JUnit (Hudson):

where every SOAPUI project is executed in its own JUnit test, to make it easier to identify problems:

package dk.acme.dmr.service.test.integration;

import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import com.eviware.soapui.tools.SoapUITestCaseRunner;

/**
 * Run SOAPUI project files as test cases.
 * 
 * @author Acme A/S
 * @version 1.0
 * @since 1.0
 */
@RunWith(value = Parameterized.class)
public class SoapUITest {
  // The folder must be relative to this project
  private final static String SOAPUI_PROJECT_DIR = "src/test/resources/";

  private final static String ENDPOINT_VAR       = "endpoint";

  private final String        soapUiFileName;

  public SoapUITest(String soapUiFileName) {
    this.soapUiFileName = soapUiFileName;
  }

  @Parameterized.Parameters
  public static Collection<Object[]> soapUIprojectFiles() {
    File folder = new File(SOAPUI_PROJECT_DIR);
    OnlyExt onlyXml = new OnlyExt(".xml");
    String[] soapuiProjs = folder.list(onlyXml);
    List<Object[]> ret = new ArrayList<Object[]>();
    for (String s : soapuiProjs) {
      ret.add(new Object[] { s });
    }
    return ret;

  }

  @Test
  public void soapUITest() throws Exception {

    SoapUITestCaseRunner runner = new SoapUITestCaseRunner();
    runner.setProjectProperties(new String[] { new String(ENDPOINT_VAR + "=http://myserver:9001") });
    runner.setOutputFolder(System.getProperty("user.dir") + "/soapui-errors");
    runner.setProjectFile(SOAPUI_PROJECT_DIR + "/" + soapUiFileName);

    runner.run();

  }

  static class OnlyExt implements FilenameFilter {
    private final String ext;

    public OnlyExt(String _ext) {
      ext = _ext;
    }

    public boolean accept(File dir, String name) {

      return name.endsWith(ext);
    }
  }

}







I am still NOT persuaded that using SOAPUI for functional tests is better than using JUnit and Java stubs. If you go beyond the basics, SOAPUI and Groovy can be even more complex than the Java solution. I simply cannot accept writing complex code in a language that cannot be compiled and easily refactored.

Saturday, July 3, 2010

JAXB generate Java classes from xsd

Using Excel, I have mapped a MFL to a XSD; now I want to generate the Java classes corresponding to the XSDs. JAX-WS uses JAXB as data binding, so:

http://java.sun.com/webservices/docs/1.6/jaxb/xjc.html

I use xjc.bat to generate the Java classes.

The alternative is: create a WebLogic WebService project, copy there your XSD, right click and "WebLogic WebServices / generate JAXB types", which internally invokes the XJC2Task Ant task.

To parse the XML into the Java classes you can use this Java utility:

http://javatoolsforweblogic.googlecode.com/svn/trunk/xmlLoader/XMLLoader.java

here
http://javatoolsforweblogic.googlecode.com/svn/trunk/xmlLoader/XMLLoaderTest.java

an example of how to use it.

XSD, specify sequence of OPTIONAL elements in ANY order

<xs:element name="GEOMQFeed">
 <xs:complexType>
  <xs:all>
   <xs:element ref="HEADER" minOccurs="1" maxOccurs="1"/>
   <xs:element ref="TAGA" minOccurs="0" maxOccurs="1"/>
   <xs:element ref="TAGB" minOccurs="0" maxOccurs="1"/>
   <xs:element ref="TAGC" minOccurs="0" maxOccurs="1"/>
  </xs:all>
 </xs:complexType>
</xs:element>


xs:all allows you to specify TAGA,TAGB,TAGC as well as TAGC,TAGB as well as TAGB,TAGA.
HEADER is the only compulsory element

The only problem, with xs:all, maxOccurs can be either 0 or 1!

If you want maxOccurs to be unbounded, you will have to use some workaround, as explained here:
http://xsd.stylusstudio.com/2003Mar/post09004.htm

The easiest one IMHO is to introduce a new type TAGAList defined as a unbounded sequence of TAGA. GEOMQFeed will be made by a xs:all of TAG?List.
Reality is that expressing a true arbitrary formal grammar in XSD is wishful thinking.


In other words..... with XSD you are only allowed to do what the XSD designers had in mind, not what you actually need :o(

In future I will look into http://www.relaxng.org/  which seems a more flexible language than XSD.

Friday, July 2, 2010

Windows Explorer cannot find files

http://support.microsoft.com/default.aspx?scid=kb;en-us;309173


set the FilterFilesWithUnknownExtensions DWORD value to 1 in the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ContentIndex

Remember also to enable the "find hidden files" advanced option.

This is one of those jaw-dropping things ... why on earth would you NOT want to find files with unregistered extension...