Monday, August 31, 2009

Java Bi-directional Maps: Apache commons or Google collections ?

In case you need a bi-directional Map in Java, you can, of course, easily roll your own.
But this is a common problem, so others have done this work already.
Here's a simple how-to on bi-directional maps with Apache and Google commons.
Apache commons collections offers a BidiMap interface with various implementations.
For example:
public class TestBidiMap
{
static BidiMap bimap = new DualHashBidiMap();
public static void main(String[] args)
{
bimap.put("D", 3);
System.out.println("D -> " + bimap.get("D") );
System.out.println("3 -> " + bimap.inverseBidiMap().get(3) );
}
}
Nice and easy, but unfortunately this version of BidiMap doesn't use Java generics, which I have learned to like over time (bimpap.get(3) will not show a compile error) !
Google collections has an alternative that uses generics: BiMap
public class TestBiMap
{
static BiMap<String,Integer> bimap = HashBiMap.create();
public static void main(String[] args)
{
 bimap.put("D", 3);
 System.out.println("D -> " + bimap.get("D") );
 System.out.println("3 -> " + bimap.inverse().get(3) );
}
}
Also nice and easy, what's interesting is the factory method HashBiMap.create(). This removes the need to duplicate the generics type specification of String, Integer. Kiss rules, so two points for Google collections here.
Summary: any mid-size Java project probably shouldn't live without Apache commons, but as a useful addition, Google collections is definitely worth a look.

Monday, August 17, 2009

Amazon S3 intro

Started to look into Amazon EC2/S3 recently (technology you should know about).
Here's a short S3 intro, one with lots of screenshots and therefore easy to digest:

Monday, August 10, 2009

Spring and Pipes&Filters

Finally an IoC container that almost everyone agrees on: Spring.
After many inhouse, half-baked attempts and 'framework wars' a default solution. TIBCO folks might remember the days of TAF (1996), GAF, XXTAF or PushBeans. Also
openadaptor.org should be noted here.

Now Spring certainly is nice and generic, but for building EAI adapters or 'message processing pipelines' it is not ideal. In case of these pipelines, the message path is very structured: from a source bean through several transformation beans until it finally reaches one (or many) sinks. XML already imposes an 'order of things' so an ideal configuration language of a little adapter might look something like this:
<pipelines> <pipe name="Jdbc2JMSPipe"> <jdbc dbref="db1" querysql="select * from table1"> <concatenate method1="getFirstName" method2="getLastName" result="setName"> <jmsObject2MapMessage> <jmsPublish topic="PERSON"> </pipe> </pipelines> This example configures a processing pipeline to get rows from a JDBC connection, invoke the concatenation filter, convert an object to a JMS MapMessage and finally publish the result to a JMS topic named 'T.PERSON'.

The configuration above is easy to understand and manipulate. One can imagine extensions with for-loops, if-clauses etc.  For example:<pipelines>
<pipe name="Jdbc2JMSPipe"> <jdbc dbref="db1" querysql="select * from table1"> <concatenate method1="getFirstName" method2="getLastName" result="setName"> <jmsObject2MapMessage> <if method="getName" startswith="a-z"> <jmsPublish topic="PERSON.LOWERCASE"> <else> <jmsPublish topic="PERSON.UPPERCASE"> </else> </if> </pipe> </pipelines> Configuring the first example pipeline with Spring could look like this: <beans> <bean id="1" class="com.abc.jdbc" dbRef="db1" querySql="select * from table1"> <property name="next"> <ref bean="2"> </property> </bean> <bean id="2" class="com.abc.concatenate" method1="getFirstName" method2="getLastName" result="setName"> <property name="next"> <ref bean="3"> </property> </bean> <bean id="3" class="com.abc.jmsObject2MapMessage> <property name="next"> <ref bean="4"> </property> </bean> <bean id="4" class="com.abc.jmsPublish" topic="T.PERSON"/> </beans> The order of beans is defined explicitly although XML already provides an order.
A nasty user of this system could even reorder the beans in a different order :-(
So maybe some XSLT to transform from a 'pipes&filters' language to a Spring configuration ?
Or extend Spring with this kind of processing step ?
Or how about a XML-aware bean reference: <beans> <bean id="1" class="com.abc.jdbc" dbRef="db1" querySql="select * from table1"> <property name="next"> <ref bean="following-sibling"> </property> </bean> <bean id="2" class="com.abc.concatenate" method1="getFirstName" method2="getLastName" result="setName"> <property name="next"> <ref bean="following-sibling"> </property> </bean> <bean id="3" class="com.abc.jmsObject2MapMessage> <property name="next"> <ref bean="following-sibling"> </property> </bean> <bean id="4" class="com.abc.jmsPublish" topic="T.PERSON"/> </beans>
Currently, I think XSLT would be the best solution since it keeps the clarity of the pipes&filters language.

Good books on EAI and Agile Programming

  • Head First "Design Patterns" - 26 pages on the Decorator ? Finally the space it deserves ! If you found the "Consequences, Forces, Solutions, Implementation, Related Patterns"structure of other Patterns book too rigid. This one is for you. Finally an entertaining read on Patterns. "Patterns in Java" and even the GoFs books loose their glory after reading this one.
  • "Client/Server Survival Guide" - Very old, but I liked the writing. (use Steven's "Unix Network Programming" as a reference)
  • "Extreme Programming Explained" - there you go, little Agile programmer. Also some good tips on how to convince upper management of the benefits.
  • "Java Extreme Programming Cookbook" - nice intro to a all the good technologies (as of 2005).
  • "Java Message Service" (Monson-Haefel&Chappel) - no thrills, but all you really need. Writing concise books is a great virtue.

Ajax: Xpath-enabled Json queries

In the Ajax world, there is a big discussion about XML versus Jsonas a means of transporting data from the Server to the Browser. After looking at the first examples of using a DOM API in Javascript, I knew, I'll not be using XML in Javascript. Using Json instead, feels very nice and natural. But Json is just a means of transport. Nothing else. The simplisticclasses work, but no query language to select the interesting data before sending it over. If you structure your Web-Gui well, the resulting data should be simple. Hence no need for the complex XML structure. XML offers however, two goodies, I wouldn't want to miss: Object to XML serializers (e.g. XStream) and XPath to select parts of the XML. So my idea is this: why not marry both approaches ? Transform the Java object into XML, apply an XPath query to select what you really want and then transform the result to Json to send it over. Even more flexible, support a 'class' and 'method' (and an optional 'args') parameter to select which data to get. Here is how it works: 1) Ajax Request: On the Browser, request a Json object with parameters class,method, xpath:
requestList( "class=TibjmsAdmin&method=getTopics&xpath=/*/*/name",
"name",
isAsync,
topicList );
2) Java Method call: On the Server-side, this request will execute the method TibjmsAdmin.getTopics() and create a Java object with some code similar to this:

if( className.equals("TibjmsAdmin") ) { // TODO: use ClassLoader (security?)
 Object invokee = jmsAdmin;
}
... others ...

// get specified method on specified class
className = invokee.getClass().getName();
Class c = Class.forName(className); // className is TibjmsAdmin
Method m = c.getMethod(method,argClasses); // method is getTopics, argClasses is null

// invoke method and get return object
  returnObj = m.invoke(invokee, argObs);
3) Java to XML: the next step is now to serialize this Java object to XML. I like to use XStream for this purpose because its extremly simple and straight-forward.

XStream xstream = new XStream();
String xml = xstream.toXML(returnObj);
If the returned object does not produce the required results, you can do some magic by plugging in an XStream 'Converter' (not shown here). 4) Apply Xpath: Now that that we have the XML, we can apply the specified XPath to fiddle out the data that is really interesting for us. The following code will create a list of selected XML nodes.
    NodeList nl = XmlUtils.selectNodeList(docBuilder,xmlString,xpath);
StringBuffer sb = new StringBuffer("");
for( int i=0;i<nl.getLength();i++ ) {

  Node node = nl.item(i);
  sb.append("<" + node.getNodeName() + ">" );
  sb.append( node.getTextContent() );
  sb.append("" );
}
sb.append("\n");
5) Return Json result: finally return the Json object back to the Browser using the Json tools.
JSONObject json = XML.toJSONObject(xml);
  response.setContentType("text/plain");
if( out.equals("pretty") ) // pretty JSON
  response.getWriter().print( json.toString(2) );
else // or not
  response.getWriter().print( json.toString() );

Windows NT Service configuration

To debug current Windows Service configuration, try 'sc' on a command console.

For example 'sc query' pretty much shows the same configuration information as the registry tree which defines Windows services:

My Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

There's an interesting Windows Resource Kist that includes service configuration tools.

For example instsrv.exe to run ANY other .exe application as Windows service

C:\Program Files\Windows Resource Kits\Tools>instsrv.exe AAA "C:\Program Files\Windows Resource Kits\Tools\srvany.exe"

The service was successfuly added!

C:\Program Files\Windows Resource Kits\Tools>instsrv.exe AA REMOVE

Consistent Subversion icons in Windows and Eclipse

With the latest version of Tortoise SVN (1.6.x) the default icon set changed to be different from the icons in Eclipse (subclipse).
To justify that again, so SVN icons look the same in Eclipse and in Windows folders, choose a TortoiseSVN directory, right mouse-click, TortoiseSVN -> Settings and choose the Subclipse icon set as shown below.

Debugging Visual C++ applications

Sometimes, the simplest trick is the best. I'm sure you all know this, but to debug a Windows application (for exampe a Windows NT Service), call 'DebugBreak'. In many situations this can be more handy than setting a breakpoint.

int main(int argc, char** argv)

{

DebugBreak();

How to spawn a command shell under windows 'system' user

This trick can be useful if you want to debug user permission issues with a Windows NT service that logs on under "Local System account" (the default).

First, figure out your current system time:

C:\>time

The current time is: 6:15:18.57

Second, use the 'at' command to start an interactive command shell when the next minute starts:

C:\>at 6:16 /interactive cmd

Now inside this new command shell, try your command which is run under this new user.

Windows DLL load order

So when you work with Windows NT services, you might want to make sure the right DLLs are loaded at the proper time. When debugging issues on NT service startup time, this becomes important. On Windows, the order of DLL loading is as follows (see also Visual C++'s help on LoadLibrary()):

  1. The directories listed in the App Path registry key (if any)
  2. The directory where the executable module for the current process is located.
  3. The current directory.
  4. The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
  5. The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
  6. The directories listed in the PATH environment variable.
To set an 'App Path' for your application (text.exe), set the (Default) value of
KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\test.exe
to the full path of your executable, for example:
C:\Program Files\Test\test.exe

Add a sub-key named Path, set it's value to the full path of the DLL, for example:

C:\Program Files\Test\lib
Use regedit see examples of other applications, and how they setup their App Path keys.