Monday, March 18, 2013

Java - Apache Digester and Enums

I was having trouble with Digester and converting enums.  So I've come up with this handy hack...

A converter for enums - really hacky:


package binky.moobs.referencedata.digesters;

import org.apache.commons.beanutils.Converter;

/**
 * @author daniel
 * Really hacky converter to manage enums in digester
 */
public class EnumConverter implements Converter {



@Override
public Object convert(@SuppressWarnings("rawtypes") Class type, Object value) {
if (type.isEnum()) 
for(Object o  :type.getEnumConstants()) 
if (o.toString().equalsIgnoreCase(value.toString())) return o;

return null;
}

}




Before you start digesting you need to register the converter:

ConvertUtils.register(new EnumConverter(), YourEnum.class);

Tuesday, January 22, 2013

Couchbase and Windows 8 - Failing to Start

Couchbase and Windows 8 don't play well together.  

I installed the 64 bit version of 2.0.0 community and enterprise and had issues.

The two workarounds I found I needed to do were:

1) Replace c:\Program Files\Couchbase\Server\bin\libtcmalloc_minimal-4.dll with the file from here http://www.mediafire.com/?xc8nurnxjqr8klb.   Then restart the service using the services control panel (under Administrive Tools)

[As described here: http://www.couchbase.com/issues/browse/MB-6395]

2) I couldn't access the console after restarting the service.  I could see this in a file called erlang_version.txt  in the Couchbase directory:  Could not load module C:\erl5.8.5\erts-5.8.5\bin\erlexec.dll.

So I copied the directory c:\Program Files\Couchbase\Server\erts-5.8.5 to c:\erl5.8.5\ and then restarted the service.  Everything then worked fine.

Sunday, January 20, 2013

Java Directory Watcher

Another quick example...

This is how I've implemented a directory watcher that sits in a thread an looks for changes in a directory.

You create DirectoryWatcher* with the parameter of the path to watch and then an instance of the WatchListener* interface.  The WatchListener then receives events with a File object.  With that you can then do whatever is needed.

If you use a WatchListener for more than one DirectoryWatcher then you'll need to synchronise the methods.

*in the code at the link below

http://pastebin.com/kfyxrAgJ

Saturday, January 5, 2013

Java - Interesting Little Puzzle

I was reading an interview with Joshua Bloch (from Effective Java fame) and it had this puzzle:


Josh’s Puzzle: “The Story of O”

The following Java program is not quite complete; it’s missing a parameter declaration for o. Can you provide a declaration that makes the program print “O noes!”? (The program must compile without generating any warnings.)

public class Story {
   public static void main(String[] args) {
       Object o = null;
       story(o);
   }

   private static void story(<you provide the declaration> o) {
       if (o != null)
           System.out.println("O noes!");
   }


The answer was in the comments and is Object... - in other-words Varargs (http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html).

To understand why this is correct you need to look at what happens.

Object o = null;  //this creates a reference that is pointed at null - it is still a reference however.

story(o); // this calls the story method that expects one or more Objects - it then constructs an array called o containing these object references

The array o, inside the story method, is an array with one element - the reference to null.  Therefore when it reaches the conditional:  if (o!=null), it evaluates as true because o (in this context) is a reference to an instantiated array with 1 element - i.e. not null.

http://google-opensource.blogspot.co.uk/2011/04/geek-time-with-josh-bloch.html

Wednesday, January 2, 2013

Java - SWIFT MT Parsing

Just a quick post for anyone interested in parsing SWIFT MT messages in Java.

I tried a framework (that will remain nameless) and found it had a serious bug (infinite looping) and it didn't capture all the fields.

So I've written a very basic, but functional, parser.  Pass it a byte array (and string encoding - e.g. "UTF-8") and it will return an object with all the header fields etc and a map of the value fields.

Doing .toString() will return a formatted SWIFT MT message.

The source is here: http://pastebin.com/5FHiCDx6

Some good primers on SWIFT MT:
http://pic.dhe.ibm.com/infocenter/wbihelp/v6rxmx/index.jsp?topic=%2Fcom.ibm.wbia_adapters.doc%2Fdoc%2Fswift%2Fswift72.htm

http://www.10588.com/pub_web/swift/books/us1m/doc/ajh.htm

Wednesday, November 14, 2012

Java: Sorting Strings

Just a quick code dump of a string sorter I have been working on.  I think it could probably be optimised a lot.  It is currently about 3x slower than "Arrays.sort" on strings larger than about 12 chars but the point is me trying to figure it out for myself.

Anyway - here it is (updated 17/11/12):

package dan.stringsort;

public enum StringSorter {

    INSTANCE;
    
      public void sortStrings(String[] strings) {
            Node tree = buildTree(strings);
            // now recombine the tree into an array
            this.sortPos = 0;
            exportTree(tree, strings);         
      }

      private int sortPos;
      
      private void exportTree(Node tree, String[] array) {
          for (Node n:tree.children) {
           if (n!=null) {
                for (int i=0;i<n.count;i++) array[sortPos++] = n.value;                                                
                exportTree(n, array);
           }
          }
      }

      private Node buildTree(String[] strings) {        
        Node root = new Node();             
        for (String s : strings) {
                  Node curr = root;
                  int i=0;
                  for (char key:s.toCharArray()) {                   
                      Node t=curr.children[key];
                   if (t == null) {
                            Node n = new Node();
                            curr.children[key]=n;
                            curr = n;
                      } else {
                       curr=t;
                      }
                      if (i++ == s.length()) {
                       if( curr.value==null)curr.value=s;
                          //deal with multiple instances
                       curr.count++;
                      }
                  }
            }
            return root;
      }

      private class Node {
            private Node[] children;
            private int count=0;
            private String  value;
            public Node() {this.children=new Node[256];}
      }
}

Thursday, September 20, 2012

Java - Read and Write files using NIO

Code dump of some example NIO usage:


  
public void writeFileNIO(String path, String fileName, byte[] data) throws IOException {
       writeFileNIOHelper
(path,fileName,data,StandardOpenOption.WRITE);
  
}


  
public void appendFileNIO(String path, String fileName, byte[] data) throws IOException {
       writeFileNIOHelper
(path,fileName,data,StandardOpenOption.APPEND);
  
}


  
private void writeFileNIOHelper(String path,String fileName,byte[] data, StandardOpenOption option) throws IOException {
       Path p
=FileSystems.getDefault().getPath(path, fileName);     
      
if (!Files.exists(p)) Files.createFile(p);
  
      
ByteChannel sbcOut = Files.newByteChannel(p,option);
      
try {
           sbcOut.write
(ByteBuffer.wrap(data));
      
} finally {
           sbcOut.close
();
      
}
   }
  
  
public byte[] readFileNIO(String path, String fileName, int bufferSize) throws IOException {
       Path p
=FileSystems.getDefault().getPath(path, fileName); 

      
ByteChannel sbcIn = Files.newByteChannel(p,StandardOpenOption.READ);          
      
      
ByteBuffer buff = ByteBuffer.allocate(bufferSize);
      
      
byte[]data= new byte[(int)Files.size(p)];
      
int pointer=0;

      
try {
          
int readLen =sbcIn.read(buff);
          
while (readLen>0) {              
              System.arraycopy
(buff.array(), 0, data, pointer, readLen);        
              
buff.rewind();
              
pointer+=readLen;
              
readLen =sbcIn.read(buff);
          
}
       }
finally {
           sbcIn.close
();
      
}
      
return data;
  
}

Saturday, September 15, 2012

Java - UUID Generation and Hex Conversion

This is a quick code dump of a UUID generation function that also has some interesting hex conversion that I had a stab at.  I am trying to get UUID generation down to the fastest possible time.  The obvious bottleneck is the generation of secure random numbers.

I'm working on a idea of having a thread asynchronously caching a list of UUIDs or secure random numbers ready for collection.  It should reduce latency a bit further.

This is a bit quicker than Java's UUID for generating a UUID string, although it isn't doing the exact same as it doesn't follow the format described as type 4 here:

http://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29

Edit:

I've updated it to have 2 modes of operation - Secure/Insecure - basically around the RNG.  The Java Secure one will attempt to use a native generator such as /dev/random to get hardware type entropy.  The "insecure" is just a PRNG and could be predicted but is much faster.

More information on Random Number Generators (RNG) here:

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

Also I have used the enum-singleton pattern as it is pretty!  More information here:

http://electrotek.wordpress.com/2008/08/06/singleton-in-java-the-proper-way/


Anyway here's the code:

package dan.uuid;import java.security.SecureRandom;
import java.util.Random;

/**
* @author Daniel Matthews-Grout
*/


public enum UUIDGeneration {

   SECURE
(true),INSECURE(false);
  
  
private final static char[] HEX_DIGITS = {'0' , '1' , '2' , '3' , '4' , '5' ,'6' , '7' , '8' , '9' , 'a' , 'b' ,'c' , 'd' , 'e' , 'f' };


  
private Random r;
  
private final int UUID_SIZE=32;
  
private final char[] c = new char[UUID_SIZE];
  
private final byte[]  b = new byte[UUID_SIZE/2];

  
private UUIDGeneration(boolean secure) {
      
if (secure) {
          
this.r=new SecureRandom();          
      
} else {
          
this.r=new Random();
      
}
   }
  
  
public static UUIDGeneration getInstance(boolean secure) {
      
if (secure) {
          
return SECURE;
      
} else {
          
return INSECURE;
      
}
   }
  
  
public String getUUID() {            
     r.nextBytes
(b);
    
    
int p=0;
    
for (int i = 0; i < b.length; i++) {
        
int v = b[i] &amp; 0xff;
        
if (v < 16) {
             c[p++]
=c[0];
            
c[p++]=HEX_DIGITS[v];
        
} else {
              c[p++]
=HEX_DIGITS[v/16];
              
c[p++]=HEX_DIGITS[v%16];
        
}
       }  
      
return new String(c);
    
}
  
}

Monday, September 10, 2012

Ctirix Receiver and Ubuntu SSL Error

I was trying to connect to a Citrix session using Ubuntu and the Citrix Linux client and was getting the following error:

You have chosen not to trust VeriSign Class 3 Public Primary Certification Authority - G5 the issuer of the server's  security certificate"

After a bit of faffing about I figured out I needed to download the certificate from here:

http://www.verisign.com/support/roots.html

specifically:

http://www.verisign.com/repository/roots/root-certificates/PCA-3G5.pem

and place it here:

/opt/Citrix/ICAClient/keystore/cacerts

Sunday, August 19, 2012

Genetic Algorithm - Java

Quick brain dump.  I had a passing interest in Genetic Algorithms so I had a go at a starter tutorial (http://www.ai-junkie.com/ga/intro/gat1.html).

I've done a really scratchy implementation (below) and made the fitness-tests multi-threaded for the funnies.

There isn't much call for GA in the workplace, so I doubt I'll ever spend too much time learning about them.  However I was really happy when I finally got it to work.  It really shows the power of evolution.

Anyway, here is the code.  It is probably a lot more complicated than it needs to be, I'm a complete noob at GA and it is completely rough/unoptimised.

The obvious performance improvement would be to make the selection/crossover multi-threaded.

Edit (22/08): I've done some changes to introduce different types of mutation, a different selection,a different scoring mechanism and the ability to accept a threshold (e.g. find closest match).

Code here: http://pastebin.com/NJ7mR3pp