The Beginner’s Guide to Hazelcast Part 5

Standard

This is a continuation of a series of posts I have written about Hazelcast.  I highly suggest you read the other ones: Part 1, Part 2, Part 3 and Part 4.

Things That Makes One Go “Huh?”

This post will have no Hazelcast specific code in it.  Let me repeat that.  This post will have no Hazelcast specific code in it.  That is because the fine folks at Hazelcast produced a product that implements different standards.  This allows for a choice of clients.  One of those standards that Hazelcast implements is memcached.

What about JCache?

JCache (JSR 107) is just for Java.  Memcached protocol clients have been implemented across several languages so one is not nailed down to one language.  Implementing the memcached protocol was a smart move in my opinion because it makes Hazelcast more than a “Java thing.”

Why Use Hazelcast?

Excellent question!  If one can use any memcached server, why use Hazelcast.  Well, to tell you the truth, unless one is sharing a database between several servers, one may not even need caching!  If one does need a caching solution, here is why I would choose Hazelcast:

  1. Automatic, real time backups – I have not read of one Hazelcast datatype that is not backed up at least once.  Just stand up two instances, one off machine from the other, to get the full benefit.
  2. Security – If the servers that need to cache are across different networks, then the firewall rules can be easier with Hazelcast.  Lets say n servers are needing to cache data and n/2 of them are on the 192.168.1.x network and the other n/2 are on the 10.10.1.x network.  By setting one Hazelcast instance on either network, all n machines can be sharing a cache.  The Hazelcast instances can be configured to talk to just the instance on the other side.  That makes the firewall rule writer job easier because there only has to be a rule made for two servers rather than n machines  then the 192.168.1.x machines just talk to their Hazelcast node and the 10.10.1.x machines just talk to their Hazelcast node and let the Hazelcast instances do the rest of the work.

Example

I never like to show just a “ho hum” kind of example so I am going to show how a Java client can share data with a Python client.

Setup

I am using Java 1.7 and Python 3.4.  Unfortunately, neither language has memcached support out of the box so I went looking for already written clients.

Java

I found Spymemcached for Java.  I will be just skimming the surface of its abilities. It can be grabbed from Maven.  Here is the pom.xml file for the project:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 3     <modelVersion>4.0.0</modelVersion>
 4     <groupId>com.darylmathison</groupId>
 5     <artifactId>Memcache</artifactId>
 6     <version>1.0-SNAPSHOT</version>
 7     <packaging>jar</packaging>
 8     <properties>
 9         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
10         <maven.compiler.source>1.7</maven.compiler.source>
11         <maven.compiler.target>1.7</maven.compiler.target>
12     </properties>
13     <build>
14         <plugins>
15             <plugin>
16                 <groupId>org.apache.maven.plugins</groupId>
17                 <artifactId>maven-compiler-plugin</artifactId>
18                 <version>2.3.2</version>
19                 <configuration>
20                     <showDeprecation>true</showDeprecation>
21                 </configuration>
22             </plugin>
23             <plugin>
24                 <groupId>org.codehaus.mojo</groupId>
25                 <artifactId>exec-maven-plugin</artifactId>
26                 <version>1.3.2</version>
27                 <executions>
28                     <execution>
29                         <goals>
30                             <goal>java</goal>
31                         </goals>
32                     </execution>
33                 </executions>
34                 <configuration>
35                     <mainClass>com.darylmathison.memcache.Main</mainClass>
36                 </configuration>
37             </plugin>
38         </plugins>
39     </build>
40     <dependencies>
41         <dependency>
42             <groupId>net.spy</groupId>
43             <artifactId>spymemcached</artifactId>
44             <version>2.11.5</version>
45         </dependency>
46     </dependencies>
47 </project>

Python

Next, I found python3-memcached for Python. It uses the classic setup.py procedure to install.

Server

Not much of a cache if the server is missing. One can download Hazelcast at hazelcast.org/download, extract the contents, cd into the bin directory and run the server.bat or server script according to one’s OS. As setting up servers go, that is the easiest one I have ever done.

Situation

The “expensive” operation that I am trying to make cheaper is Fibonacci numbers. Because Python and Java can both understand unicode, the values are stored as unicode strings. The key is a unicode string of the number of the sequence or the number of rounds it takes to get there.

Code

Java

package com.darylmathison.memcache;

import java.io.IOException;
import java.net.InetSocketAddress;
import net.spy.memcached.MemcachedClient;

/**
 *
 * @author Daryl
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            MemcachedClient client = new MemcachedClient(new InetSocketAddress("localhost", 5701));
            for(int i = 2; i < 20; i++) {
                System.out.println("value of round " + i + " is " + fibonacci(i, client));
            }
            client.shutdown();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
    
    private static long fibonacci(int rounds, MemcachedClient client) {
        String cached = (String)client.get(String.valueOf(rounds));
        if(cached != null) {
            System.out.print("cached ");
            return Long.parseLong(cached);
        }
        
        long[] lastTwo = new long[] {1, 1};
        
        for(int i = 0; i < rounds; i++) {
            long last = lastTwo[1];
            lastTwo[1] = lastTwo[0] + lastTwo[1];
            lastTwo[0] = last;
        }
        
        client.set(String.valueOf(rounds), 360, String.valueOf(lastTwo[1]));
        return lastTwo[1];
     }
}

Python

Here is the Python client. As a pythonian, I tried to be as pythonic as possible.

import memcache

client = memcache.Client(['localhost:5701'])

def fibonacci(round):
    f = [1, 1, 1]
    
    for i in range(round):
        f[-1] = sum(f[:2])
        f[0], f[1] = f[1], f[2]
        
    return f[2]

def retrievefib(round):
    fib = client.get(str(round))
    if not fib:
        fib = fibonacci(round)
        client.set(str(round), str(fib))
    else:
        print("cached")
        
    return fib

def main():
    store = [ x for x in range(20) if x % 2 == 0]
    for i in store:
        retrievefib(i)
    
    for i in range(20):
        print(retrievefib(i))

if __name__ == "__main__":
    main()

Conclusion

Well, here is an example of Hazelcast as being the powerhouse behind the scenes. This is a place where I think it shines the most. One doesn’t have to create whole new crafty, distributed applications to take advantage of Hazelcast. All one has to do is use known practices and let Hazelcast do the hard work. The source for this post can be found here for the Java code and here for the Python code.

References

http://en.wikipedia.org/wiki/Fibonacci_number
https://code.google.com/p/spymemcached/
https://pypi.python.org/pypi/python3-memcached/1.51

How to Use Callable and FutureTask

Standard

Introduction

Since Java 1.5 there has been a new set of objects under java.util.concurrent.  This package has a number of different classes including thread queues.  I could have used those when I was programming with Java 1.2!  When I started looking at the new toys I became hesitant.  What is this Callable thing and what is the Future?  It turns out that there is nothing wrong with a Future and Callable.  In fact, they are what I have been hoping, looking for in my Java career.

Differences Between Callable and Runnable

Callable is what Runnable hoped to become.  Callable’s only method is “T call().”  What makes it so neat is that it returns something.  This is a step above having to create a getter for the answer to a task.  While this is cool, there needs to be a way to get at the returned value.

The Future is here

Future has a way to get the value out when the Callable is done.  The function is get() or get(long timeout, TimeUnit unit).  This is the equivalent of calling thread.join(); runnable.getValue() at the same time.

Example

I created a class called CounterCallable.  All it does is add numbers from the variable start to variable end.

CounterCallable

package org.mathison.futurecallable;

import java.util.concurrent.Callable;

/**
 *
 * @author Daryl
 */
public class CounterCallable implements Callable {

    private long start;
    private long end;

    public CounterCallable(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    public SumTimeAnswer call() throws Exception {
        long sum = 0;
        long startTime = System.currentTimeMillis();
        for(long i = start; i <= end; i++){
            sum += i;
        }
        long endTime = System.currentTimeMillis();

        return new SumTimeAnswer(sum, endTime - startTime);
    }
}

SumTimeAnswer

Class SumTimeAnswer is really a simple getter class that holds the sum and the amount of time it took to do the operation.

package org.mathison.futurecallable;

/**
 *
 * @author Daryl
 */
public class SumTimeAnswer {
    private long timeToFinish;
    private long sum;

    public SumTimeAnswer(long sum, long timeToFinish) {
        this.sum = sum;
        this.timeToFinish = timeToFinish;
    }

    public long getTimeToFinish() {
        return timeToFinish;
    }

    public long getSum() {
        return sum;
    }
}

App

App is just a main class pulling everything together

package org.mathison.futurecallable;

import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

/**
 * Hello world!
 *
 */
public class App 
{
    public static final long BEGIN = 0;
    public static final long END = 100000;
    public static void main( String[] args )
    {
        FutureTask task = new FutureTask(new CounterCallable(BEGIN, END));
        FutureTask firstHalf = new FutureTask(new CounterCallable(BEGIN, END/2));
        FutureTask secondHalf = new FutureTask(new CounterCallable(END/2 + 1, END));
        
        ExecutorService pool = Executors.newSingleThreadExecutor();
        pool.submit(task);
        pool.submit(firstHalf);
        pool.submit(secondHalf);
        
        try {
            SumTimeAnswer taskAnswer = task.get();
            System.out.println("just one thread Time: " + taskAnswer.getTimeToFinish()
                + " Total: " + taskAnswer.getSum());
            
            
            SumTimeAnswer taskFirstAnswer = firstHalf.get();
            SumTimeAnswer taskSecondAnswer = secondHalf.get();
            long totalTime = taskFirstAnswer.getTimeToFinish() + taskSecondAnswer.getTimeToFinish();
            long totalSum = taskFirstAnswer.getSum() + taskSecondAnswer.getSum();
            System.out.println("Two thread time: " + totalTime + " Total: " + totalSum);
        } catch(CancellationException | InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        pool.shutdown();
    }
}

Conclusion

In this post, classes Callable and FutureTask were used to demonstrate how to use the java.util.concurrent package.

BufferedReader of The EOF Kind

Standard

Introduction

I have been adding automated tests in projects that I have written at work.  One of these projects outputs CEF formatted messages to syslog.  The test required that /var/log/messages be read and compare the CEF message with the known good message.  I ran into a problem while reading the file.

What Problem?

Even a novice Java developer knows that reading a text file is no big deal, just chain the right streams together and the contents will be easily extracted.  I wanted to read the file line by line so I chained java.io.FileReader inside a java.io.BufferedReader.  Everything should work, right?  Indeed each line was dutifully read and was displaying on my log except the last line, the exact line that I was trying to compare.  I found the root of the cause in the javadocs themselves.  Here is the excerpt from the BufferedReader’s javadoc:

Reads a line of text. A line is considered to be terminated by any one of a line feed (‘\n’), a carriage return (‘\r’), or a carriage return followed immediately by a linefeed.
That sounds reasonable, at the end of a line, a line is returned.  This works 99.9% of the time but what if the line ends with an end of file(EOF)?  I will tell you what happens, a null is returned!  Remember that java.io.BufferedReader considers that a line ends in a line feed, carriage return or a carriage return followed by a line feed, not a EOF.  Syslog ends its logs with a EOF not a line terminator at the end of the last line.  This means java.io.BufferedReader as the javadoc states will not show the last line but return a null because there are no more end of line indicators before the end of the file.  This is a major problem for my test because I have to check the last line in most cases to validate output.  I am going to say this is an oversight for the makers of the Java libraries.

What To Do, What To Do

I obviously needed to modify the definition of what the end of a line was by java.io.BufferedReader.  My first thought was to extend BufferedReader so I started the checklist.  The class is not final but the buffer underneath was not visible.  This is a problem because the only way to get to the buffer is going through the java.io.Reader interface.  So my initial thought was to override the readLine method and use the read() method to get the contents one by one to parse each line.  That seemed a waste to make repeated method calls just to access a buffer.  It would be better to just read the buffer directly and increment a counter.  This meant that I would have to basically recreate BufferedReader.  “This should be no problem.  I am an experienced developer.  This will be easy!” I thought to myself.

A lesson Learned

Four days and 26 automated tests later, the beast was done.  While it is more efficient to to use a counter on an array instead of  repeated method calls, it did not make good time management sense.  Remember this was for an automated test, not code destined to be delivered to the customer.  A second or two extra per test run does not matter in the long run.  Getting it done in a quarter of the time so tests can be run does matter.  In my mind, the sooner a test is written, the more time can be saved and time is money.

The Solution

In theory, the concept is simple, the buffer is filled from the inner reader.  If the buffer is full, it is cleared and another set of data is read from the inner reader.  This repeats until the inner reader returns -1.  The main methods are skip(long n), read(char[] data, int offset, int length), readLine() and fillBuffer().

Skip(long n)

    @Override
    public long skip(long n) throws IOException {
        long numSkipped = 0;
        long leftToSkip = n;
        int lenRead = 0;
        while(leftToSkip > 0 && lenRead != -1) {
            if((offset + leftToSkip)  endIndex) {
                lenRead = fillBuffer();
                if(lenRead != -1) {
                    int amountBuffered = endIndex - offset;
                    long amountToSkip = (amountBuffered < leftToSkip)? 
                            amountBuffered:leftToSkip;
                    offset += amountToSkip;
                    numSkipped += amountToSkip;
                    leftToSkip -= amountToSkip;
                }
            }
        }

        return numSkipped;
    }

Read(char[] data, int offset, int length)

    @Override
    public int read(char[] cbuf, int off, int length) throws IOException {
        int totalRead = 0;
        boolean noReads = true;
        int targetOffset = off;
        int newTargetOffset = off + length;
        int readLen = 0;
        int lenToCopy = 0;
        int leftToCopy = length;
        
        while(targetOffset < newTargetOffset && readLen != -1) {
            if((offset + leftToCopy) < endIndex) {
                readLen = fillBuffer();
                if(readLen != -1) {
                    int amountBuffered = endIndex - offset;
                    lenToCopy = (amountBuffered < leftToCopy)? amountBuffered:leftToCopy;
                    System.arraycopy(buffer, offset, cbuf, targetOffset, lenToCopy);
                    noReads = false;
                    offset += lenToCopy;
                    targetOffset += lenToCopy;
                    leftToCopy -= lenToCopy;
                    totalRead += lenToCopy;
                }
            }
        }
        
        if(noReads) {
            totalRead = -1;
        }

        return totalRead;
    }

ReadLine()

    public String readLine() throws IOException {
        StringBuilder line = new StringBuilder();
        boolean foundCR = false;
        boolean foundLinefeed = false;
        boolean foundBoth = false;
        int readLen = 0;
        final char LINEFEED = '\n';
        final char CR = '\r';
        
        if(offset == endIndex) {
            readLen = fillBuffer();
        }
        
        while(!(foundCR || foundLinefeed || foundBoth) && readLen != -1) {
            if(buffer[offset] == CR) {
                foundCR = true;
                offset++;
                if(offset == endIndex) {
                    readLen = fillBuffer();
                    if(readLen != -1) {
                        if(buffer[offset] == LINEFEED) {
                            foundBoth = true;
                            offset ++;
                        } 
                    }
                } else if(buffer[offset] == LINEFEED) {
                    foundBoth = true;
                    offset++;
                } 
            } else if(buffer[offset] == LINEFEED) {
                foundLinefeed = true;
                offset ++;
            } else {
                line.append(buffer[offset]);
                offset++;
            }
            
            if(offset == endIndex) {
                readLen = fillBuffer();
            }
        }
        
        if(line.length() == 0) {
            return null;
        }
        
        return line.toString();
    }

FillBuffer()

    private int fillBuffer() throws IOException {
        int length;
        int lenRead = 0;
        long newOffset = offset + buffer.length;
        if(newOffset >= endIndex) {
            moveLeftoverToBeginning();
            endIndex = endIndex - offset;
            offset = 0;
            
            length = bufferSize - endIndex;
            lenRead = in.read(buffer, endIndex, length);
            if (lenRead != -1) {
               endIndex += lenRead;
            } else {
                //endIndex = offset;
            }
        } else if(newOffset < endIndex) {
            lenRead = 0;
        }
        return lenRead;
    }

Conclusion

In this blog entry, a custom BufferedReader is discussed. The reader includes EOF as a line terminator. This is to facilitate verifying the output of a CEF formatted syslog message. The link to see the rest of this BufferedReader and its tests, download the Maven project via git at https://github.com/darylmathison/buffered-reader-example.

Three Ways to Solve a Problem

Standard

Introduction

I wanted to show the differences of three different languages.  I made a palindrome detector with Java, Groovy and Python.  Technically the Python I used is CPython so it is not Java but JPython runs in the JVM so I am counting it as a Java related language.  Groovy is Java related because as of Java 1.6 and later, Groovy natively runs on the JVM.  Since this is a Java blog, Java had to be one of the languages used.  I will point out differences and similarities when all of the solutions are posted.  This will not be a explaination of each language.  There are many excellent resources out there.  For example, one place I find myself at a lot is http://www.python.org.  Another site I found myself for this post is http://groovy.codehaus.org/.

Solutions (code)

Requirements

The solution must analyze a string and see if it is a palindrome.  A palindrome is a word or phrase, that spelled the same forwards and backwards.  For example, 123321 is a palindrome.  Two strings will be used to test the solution, “123321” and “1234321.”  This covers the case of a palindrome with an odd number of characters and a even number of characters,  The solution returns the equivalent of a true when a palindrome is detected and the equivalent of false when one is not detected.

Java

public class Palindrome {

private static boolean isPalindrome(String testString) {

String firsthalf;

StringBuilder secondhalf;

int firstHalfIndex;

int secondHalfIndex;

int length = testString.length();

if(length % 2 == 0) {

firstHalfIndex = (int)(length/2);

firsthalf = testString.substring(0, firstHalfIndex);

secondhalf = new StringBuilder(testString.substring(firstHalfIndex));

} else if ( length % 2 == 1) {

firstHalfIndex = (int)(length/2);

secondHalfIndex = firstHalfIndex + 1;

firsthalf = testString.substring(0, firstHalfIndex);

secondhalf = new StringBuilder(testString.substring(secondHalfIndex));

} else {

firsthalf = “”;

secondhalf = new StringBuilder();

}

return firsthalf.equals(secondhalf.reverse().toString());

}

public static void main(String[] argv) {

System.out.println(isPalindrome(“123321”));

System.out.println(isPalindrome(“1234321”));

}

}

Groovy

def isPalindrome(testString){

def firsthalf

def secondhalf

def firstHalfIndex

def secondHalfIndex

if (testString.length() % 2 == 0) {

firstHalfIndex = testString.length()/2

firsthalf = testString[0..<firstHalfIndex]

secondhalf = testString[firstHalfIndex..<testString.length()]

} else if(testString.length() % 2 == 1) {

firstHalfIndex = testString.length()/2

firsthalf = testString[0..<firstHalfIndex]

secondHalfIndex = firstHalfIndex + 1

secondhalf = testString[secondHalfIndex..<testString.length()]

}

firsthalf == secondhalf.reverse()

}

println isPalindrome(“123321”)
println isPalindrome(“1234321”)

Python

def isPalindrome(test_string):

length = len(test_string)

first_half = None

second_half = None

if length % 2 == 0:

first_half_index = int(length/2)

first_half = test_string[:first_half_index]

second_half = test_string[first_half_index:]

elif length % 2 == 1:

first_half_index = int(length/2)

second_half_index = first_half_index + 1

first_half = test_string[:first_half_index]

second_half = test_string[second_half_index:]

return first_half == second_half[::-1]

def main():

print(isPalindrome(“123321”))

print(isPalindrome(“1234321”))

if __name__ == “__main__”:

main()

Thoughts

Similarities

What I found was the same was how easily it was to implement the same solution in three different languages.  Each one did it in their own idiom but it was done.  Each had the ability to figure out the length of the string, split the string by an index and reverse the string.  I am a sucker for slices so Groovy and Python were more fun for me.

Differences

I wasn’t aware of this before I started hitting the blogosphere but one of the complaints of Java is that it is too wordy.  Doing this exercise really exposed me to the wordiness of Java.  Groovy did the same work without having to use a StringBuilder to do a string reverse.  The only reason I did a main on the Python solution is because that is a way to be able to use a file as a library and be a standalone script (It is a Python “idiom” I once read.).  The concept of slices really made the code look neat and tidy for me.  Did I mention I am a sucker for slices? The Groovy reverse extension to Strings was really nice.  Being able to reverse the string with a slice was really cool in Python.

Conclusion

In this post, I compared three languages implementing the same solution.  While the problem was simple, each language succeeded in its own way.

When a String is Null but Not Null

Standard

Introduction

A junior programmer on my team at work had an interesting bug.  Its symptoms I have seen more than once.  This post is what to look for and how to prevent it in the future.  I also explore different solutions to the problem.

Symptoms

The code in question looked well made.:

if(trouble != null && !trouble.isEmpty()) {
    System.out.println("fine here: " + trouble);
} else {
    System.out.println("not so fine here: " + trouble);
}

The code would hit the “fine here” block but would print the value of “null.”  The variable was set by reading a file.

Investigation

The developer and I looked at the print out and ran the test several times but the same result came up.  I looked where the variable was being set.  It should have set the value to null if there was nothing there, yet the print out stated the value was null.  I had an idea and we decided to test it.  He changed the code:

if(trouble != null && !trouble.isEmpty() && !trouble.equals("null")) {
    System.out.println("fine here");
} else {
    System.out.println("not so fine here");
}

The tests went to the “not so fine here” every time.  It appears the value was set to the string “null” not to the value null.

What to Learn

To tell the truth, I have seen this before.  It took me about a day when my code started doing the same thing to figure it out.  What I learned from this is that parameter checking is still a good thing.  I found that the valid string check could be used in several places in my code.  To prevent the copy and paste anti-pattern, I abstracted the validation into a method.

private static boolean isValidString(String test) {
    boolean isValid = (test != null && !test.isEmpty() && !test.equals("null"));
    return isValid;
}

The next step to prevent a longer and longer and validation line is to abstract it to a validation object.  This allows for a dirty word list.

public class StringValidator {
    private List dirtyWords;

    public static final int ARRAY_SIZE = 20;
    public StringValidator() {
        dirtyWords = new ArrayList(ARRAY_SIZE);
    }

    public boolean isValid(String test) {
        boolean isValid = false;
        isValid = (test != null) && !test.isEmpty();
        if(isValid) {
            for(String word: dirtyWords) {
                if(word.equals(test)) {
                    isValid = false;
                    break;
                }
            }
        }
        return isValid;
    }

    public void addDirtyWord(String word) {
        if(!isValidString(word)){
            throw new IllegalArgumentException(word + " is not a good dirty word");
        }

        dirtyWords.add(word);
    }

    private boolean isValidString(String test) {
        return ((test != null) && !test.isEmpty());
    }
}

which leads to this parameter checking code:

if(validator.isValid(trouble)) {
    System.out.println("fine here");
} else {
    System.out.println("not so fine here");
}

Conclusion

Sometimes we need to think a little outside the box to figure out a problem.  Don’t feel bad to get a second set of eyes on a problem; it maybe the best thing that happened.  I explored the solution ending up creating a validator allowing for the inclusion of a dirty word list without a long and confusing test. The source code for this can be found at https://github.com/darylmathison/null-but-not-null-example.

The JAXB Well Known Secret

Standard

Introduction

I rediscovered a library that Java offers to the masses. When I first read the specification, I was confused and thought I needed all these special tools to implement. I found recently that all was needed was some annotations and a POJO.

JAXB

JAXB stands for Java Architecture for XML Binding. This architecture allows a developer to turn the data from a class to be turned into a XML representation. This is called marshalling. The architecture also allows a developer to reverse the process turning a XML representation to be turned into a class. This is called unmarshalling. There are tools that can create Java classes from XML Schema files. The tool is called xjc. There is another tool that creates a xsd files by using schemagen.

Marshalling

Marshalling and unmarshalling happens several places in Java. The first I was exposed to this was RMI. Objects are sent over  being used as parameters for remote method calls, hence the name Remote Method Invocation (RMI). Another place it happens is writing objects to a stream. The streams that implement this are ObjectOutputStream and ObjectInputStream. Another place that it happens are ORM classes. Another way of course is writing a XML representation of an instance. Classes that want to be marshalled need to implement Serializable and all of its member attributes need to implement Serializable too with the exception of classes going through JAXB. Serializable is a marker interface. It has no methods to implement but it shows that a class can be serialized or marshalled. An object that has been marshalled has had its data put into some persistent fashion. Unmarshalled objects have had their data read from a persistent state and joined with a class. This makes classpaths very important. For a fun fact, a valid entry in a classpath is http://ip:port/path/to/jar. I imagine some organizations make use of this by centralizing their jar files and the latest version is just a download away.

Example

I used maven and spring to do this example. The reason was not to make it more complicated but to make the code cleaner to read and focus more on using the technology that I am showing. The dependencies in the pom.xml file are below:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0>

  <groupId>org.mathison>
  <artifactId>JAXBProject>
  <version>1.0-SNAPSHOT>
  <packaging>jar>

  <name>JAXBProject>
  <url>http://maven.apache.org>

  <properties>
    <project.build.sourceEncoding>UTF-8>
  >

  <dependencies>
    <dependency>
      <groupId>junit>
      <artifactId>junit>
      <version>4.11>
      <scope>test>
    >
    <dependency>
      <groupId>com.sun.xml.bind>
      <artifactId>jaxb-impl>
      <version>2.2.8-b01>
    >
    <dependency>
      <groupId>org.springframework>
      <artifactId>spring-core>
      <version>3.2.3.RELEASE>
    >
    <dependency>
      <groupId>org.springframework>
      <artifactId>spring-context>
      <version>3.2.3.RELEASE>
    >
    <dependency>
      <groupId>org.springframework>
      <artifactId>spring-beans>
      <version>3.2.3.RELEASE>
    >
  >
>

The wonderful thing about JAXB is that it uses POJOs. Contact.java is the central POJO class in the collection of three.

package org.mathison.jaxb.beans;

import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author Daryl Mathison
 */
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Contact {
    private String lastName;
    private String firstName;
    private String middleName;
    private String jobTitle;
    
    @XmlElementWrapper(name = "addresses")
    @XmlElement(name = "address")
    private List<Address> addresses;
    
    @XmlElementWrapper(name = "phone-numbers")
    @XmlElement(name = "phone-number")
    private List<PhoneNumber> numbers;

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getMiddleName() {
        return middleName;
    }

    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }

    public String getJobTitle() {
        return jobTitle;
    }

    public void setJobTitle(String jobTitle) {
        this.jobTitle = jobTitle;
    }

    public List<Address> getAddresses() {
        return addresses;
    }

    public void setAddresses(List<Address> addresses) {
        this.addresses = addresses;
    }

    public List<PhoneNumber> getNumbers() {
        return numbers;
    }

    public void setNumbers(List<PhoneNumber> numbers) {
        this.numbers = numbers;
    }

    @Override
    public String toString() {
        return "Contact{" + "lastName=" + lastName + ", firstName=" + firstName + ", middleName=" + middleName + ", jobTitle=" + jobTitle + ", addresses=" + addresses + ", numbers=" + numbers + '}';
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 23 * hash + (this.lastName != null ? this.lastName.hashCode() : 0);
        hash = 23 * hash + (this.firstName != null ? this.firstName.hashCode() : 0);
        hash = 23 * hash + (this.middleName != null ? this.middleName.hashCode() : 0);
        hash = 23 * hash + (this.jobTitle != null ? this.jobTitle.hashCode() : 0);
        hash = 23 * hash + (this.addresses != null ? this.addresses.hashCode() : 0);
        hash = 23 * hash + (this.numbers != null ? this.numbers.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Contact other = (Contact) obj;
        if ((this.lastName == null) ? (other.lastName != null) : !this.lastName.equals(other.lastName)) {
            return false;
        }
        if ((this.firstName == null) ? (other.firstName != null) : !this.firstName.equals(other.firstName)) {
            return false;
        }
        if ((this.middleName == null) ? (other.middleName != null) : !this.middleName.equals(other.middleName)) {
            return false;
        }
        if ((this.jobTitle == null) ? (other.jobTitle != null) : !this.jobTitle.equals(other.jobTitle)) {
            return false;
        }
        
        if(!listEquals(this.addresses, other.addresses)) {
            return false;
        }
        
        if(!listEquals(this.numbers, other.numbers)) {
            return false;
        }
        return true;
    }
    
    private boolean listEquals(List first, List second) {
        for(Object o: first) {
            if(!second.contains(o)) {
                return false;
            }
        }
        return true;
    }
}

The main part to look at is the annotations. @XmlRootElement defines that this is the start of a class. @XmlAccessorType(XmlAccessType.FIELD) tells the architecture that the fields will be used to define the elements in the xml. The annotations can be put on the getters as well. If the annotation is not used, JAXB gets confused as to which to use. For instances where a list is present, @XmlElementWrapper is used to tell JAXB what the outer tag will be. For example, there are a list of addresses. The wrapper takes a parameter named “name” and it is filled with “addresses.” When the XML is rendered, there will be the tag “addresses” wrapped around the collection of addresses. The @XmlElement annotation is used when one wants to change the tag of a property. To come back to our address list, the annotation has redefined the addresses list to “address.” This will cause each address object to have a tag of “address” instead of “addresses” which is already taken up. The same pattern is used for numbers. The rest of the properties will be have tags that match the name of them. For example, lastName will be turned into the tag “lastName.” The other two POJOs, PhoneNumber.java and Address.java have public enum classes. Here is PhoneNumber.java:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.mathison.jaxb.beans;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
 *
 * @author Daryl Mathison
 */
@XmlRootElement
public class PhoneNumber {
    @XmlType(name="phone-type")
    public enum Type {
        HOME,
        WORK,
        HOME_FAX,
        WORK_FAX;
    }
    
    private Type type;
    private String number;

    public Type getType() {
        return type;
    }

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

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    @Override
    public String toString() {
        return "PhoneNumber{" + "type=" + type + ", number=" + number + '}';
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 37 * hash + (this.type != null ? this.type.hashCode() : 0);
        hash = 37 * hash + (this.number != null ? this.number.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final PhoneNumber other = (PhoneNumber) obj;
        if (this.type != other.type) {
            return false;
        }
        if ((this.number == null) ? (other.number != null) : !this.number.equals(other.number)) {
            return false;
        }
        return true;
    }
    
}

The annotation of note is @XmlType. This tells JAXB that a class of limited number of values. It takes a name parameter. The last POJO also uses @XmlType to define its public enum class. It can be found at Address.java.

Putting It All Together

With all of this annotation and class definition, it is time to pull it all together into one main class. Here is App.java, the main class:

package org.mathison.jaxb.app;

import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.mathison.jaxb.beans.Contact;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext cxt = new GenericXmlApplicationContext("jaxb.xml");
        Contact contact = cxt.getBean("contact", Contact.class);
        StringWriter writer = new StringWriter();
        try {
            JAXBContext context = JAXBContext.newInstance(Contact.class);

            //create xml from an instance from Contact
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            m.marshal(contact, writer);
            String xml = writer.getBuffer().toString();
            System.out.println(xml);
            
            //Take xml to Contact
            StringReader reader = new StringReader(xml);
            Unmarshaller u = context.createUnmarshaller();
            Contact fromXml = (Contact)u.unmarshal(reader);
            
            System.out.println("Are the instances equivalent: " + contact.equals(fromXml));
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

First, the instance of contact is retrieved from the ApplicationContext. Second, an instance of JAXBContext is created with the Contact class as the root class. The context will analyze the class structure and create a context that can marshall or unmarshall the Contact, Address and PhoneNumber classes. In the next section, a marshaller is created from the JAXBContext. The property, Marshaller.JAXB_FORMATTED_OUTPUT is set to true. This creates a XML output that is formatted. If the property was not set, the XML would come out as one line of text. The the marshaller is called to marshall contact and be written to a StringWriter. Then the XML is printed to System.out. The output should look like the following:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contact>
    <lastName>Mathison>
    <firstName>Daryl>
    <middleName>Bob>
    <jobTitle>Developer>
    <addresses>
        <address>
            <addressLine>123 Willow View>
            <city>Cibolo>
            <state>TX>
            <type>HOME>
            <zipCode>78228>
        >
        <address>
            <addressLine>411 Grieg>
            <city>San Antonio>
            <state>TX>
            <type>WORK>
            <zipCode>78228>
        >
    >
    <phone-numbers>
        <phone-number>
            <number>210-123-4567>
            <type>WORK>
        >
        <phone-number>
            <number>210-345-1111>
            <type>HOME>
        >
    >
>

In the next section, the xml is unmarshalled back into an instance of Contact with its data. An Unmarshaller is created by the JAXBContext. Next, the unmarshaller is passed a StringReader with the just created XML as its contents. The Unmarshaller returns an Object that gets cast to a Contact. The original instance of Contact is tested against the new Contact instance to see if they are equivalent. The output should show:

Are the instances equivalent: true.

Summary

In this example, an instance of Contact was turned into XML and the resulting XML was turned back to a Contact instance with the help of JAXB. JAXB is an architecture that maps the state of an object into XML and maps XML back into an object.  The source code can be found here.

References

http://www.techrepublic.com/blog/programming-and-development/jaxb-20-offers-improved-xml-binding-in-java/498

http://www.vogella.com/articles/JAXB/article.html

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

Solving a Puzzle with Spring

Standard

Introduction

Spring

Spring uses the Inversion of Control (IoC) pattern. There are many ways to do IoC. From what I can tell (please comment if I am entirely wrong) is that instead of creating the objects yourself, you have someone else do it for you. For example, EJB lookups with EJB 2.1 (You can still do this in EJB 3.1), the server gives you an instance of the object you want. Spring creates the objects for you through a BeanFactory or an ApplicationContext. The other pattern that gets thrown around in reference to Spring is Dependency Injection (DI). Many times IoC and DI can be interchangeable. The main thrust of DI is that to make objects as decoupled as possible. This happens by injecting the objects to an object rather than the object creating them. Spring uses a configuration file so it can know what beans it can inject. If a bean has a property with setters, the property can be set in the configuration. Here is an example of a property being set.

Randy

One can also populate a java collection like a java.util.List or java.util.Map. These are beyond the scope of this article. For now, one should know that a spring bean’s property can be set.

Puzzle

There are many puzzle books out there but the one I have is Dr. Ecco’s Cyberpuzzles by Dennis E. Shasha. I am up to puzzle number 2. The puzzles are given as stories with the puzzle changing throughout the story. There are many points in the story where the reader is challenged to solve the puzzle before going on. What is interesting from a software development perspective is that the requirements while changing are well defined. This makes it ideal for writing programs that can do the boring work for you while thinking about the solution.

The puzzle we are going to solve deals with Monopoles. In the story the person with the Jordan Tyler is talking to Dr. Ecco and his niece Liane. Jordan explains that they are going to ship monopoles into space for a mission. The company that makes the monopoles makes 52 kinds. Monopoles have interesting properties. They bind three kind at a time. Once bound, they are forever bound. If the conditions to bond do not exist, the monopoles neither attract nor repel each other. The formula for what monopoles will bind is x + y = z. For example, monopoles 1,2 and 3 will bond together as will 5, 3 and 8. For the purposes of the mission, bonded monopoles are worthless. They have discovered that a barrier of tungsten will block the attraction of monopoles that would normally bond together. The company launching the monopoles into space doesn’t want to fill their ship with a rare metal. The challenge is what is the smallest number of containers that can hold all 52 monopoles types without any of them bonding together.

Example

Model

Monopole types are going to be modeled as integers. I could create a monopole class and define a function that returns the type number but that would be an int. Monopoles will be held in Chambers. Chambers will know if a monopole can be added or not and will not allow a monopole that will bind to other monopoles to be added. Chambers will be inside Ships. Ships will know if a monopole can be held by querying its chambers. A ship can have chambers added if there is not enough to hold all 52 types.

Interfaces

In the interest of keeping dependencies low, I decided to make a couple of interfaces, one for Ship and one for Chamber.

Ship.java:
package ship;

import java.util.List;

import chamber.Chamber;

public interface Ship {

public void addMonopole(int monopole);

public boolean canAddMonopole(int monopole);

public void addChamber(Chamber chamber);

public List getChambers();

public int getNumChambers();

public void reset();

public String toString();

}
Noticed that I have addChamber() with a parameter of Chamber. This is so the dependency can be injected by the ApplicationContext. Normally, I would have the Ship create the Chamber internally. The reset method is to clear the chambers of their monopoles in preparation for another try.

Chamber’s interface is next:
package chamber;

import java.util.List;

public interface Chamber {

public void addMonopole(int monopole);

public boolean canAddMonopole(int monopole);

public int numMonopoles();

public List getMonopoles();

public void clear();

public boolean isEmpty();

public String toString();

}
This is a pretty simple interface. Basically, it is a list with a simpler interface. The canAddMonopole method is what prevents monopoles that would bond outside the chamber.

Chamber Implementation

Chambers do two things, hold monopoles and prevent monopoles from bonding. My solution to the problem is found below.

LinkedListChamber.java:
package chamber;

import java.util.Collections;

import java.util.HashSet;

import java.util.LinkedList;

import java.util.List;

import java.util.Set;

public class LinkedListChamber implements Chamber {

private List monopoles;

private Set monopoleTypeCache;

public LinkedListChamber() {

monopoles = new LinkedList();

monopoleTypeCache = new HashSet();

}

@Override

public void addMonopole(int monopole) {

if(monopole < 1 || monopole > 52) {

throw new IllegalArgumentException(“the range for monopole is 1 to 52”);

}

if(canAddMonopole(monopole)) {

addToCache(monopole);

monopoles.add(monopole);

}

}

@Override

public boolean canAddMonopole(int monopole) {

return !monopoleTypeCache.contains(new Integer(monopole));

}

@Override

public int numMonopoles() {

return monopoles.size();

}

@Override

public List getMonopoles() {

return Collections.unmodifiableList(monopoles);

}

@Override

public void clear() {

monopoles.clear();

monopoleTypeCache.clear();

}

@Override

public boolean isEmpty() {

return monopoles.isEmpty();

}

@Override

public String toString() {

return “LinkedListChamberImpl{” + “monopoles=” + monopoles + “}”;

}

private void addToCache(int monopole) {

List temp = new LinkedList();

for(int m: monopoles){

temp.add(m + monopole);

}

monopoleTypeCache.addAll(temp);

}

}
As one can see, there are two data structures keeping track of the monopoles. The first one is a java.util.List. This holds the monopoles. The other structure is a java.util.Set that holds the possible monopoles that would bond to two other monopoles held in the chamber if added. Entries are added before the monopole is entered.

Ship Implementation

A ship places the monopoles into chambers. The way that it does this affects how many chambers are needed to hold all 52 monopoles. I created three ways the chambers are filled. All but one method was common among them so I extracted an abstract class and extended it three times. Here is the AbstractShip class.

AbstractShip.java:
package ship;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import chamber.Chamber;

abstract class AbstractShip implements Ship {

protected List chambers = new ArrayList();

public void addChamber(Chamber chamber) {

if (chamber == null) {

throw new NullPointerException(“chamber is null”);

}

chambers.add(chamber);

}

@Override

public abstract void addMonopole(int monopole);

@Override

public boolean canAddMonopole(int monopole) {

boolean canAdd = false;

for (Chamber c : chambers) {

if (c.canAddMonopole(monopole)) {

canAdd = true;

break;

}

}

return canAdd;

}

@Override

public List getChambers() {

return Collections.unmodifiableList(chambers);

}

@Override

public int getNumChambers() {

return chambers.size();

}

@Override

public void reset() {

for (Chamber c : chambers) {

c.clear();

}

}

@Override

public String toString() {

return “Ship{” + “chambers=” + chambers + ‘}’;

}

}
As one can see, the abstract class just implements everything but one method, addMonopole(). Here is my first attempt at placing all of the monopoles, FirstChamberShip.

FirstChamberShip.java:
package ship;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import chamber.Chamber;

public class FirstChamberShip extends AbstractShip {

@Override

public void addMonopole(int monopole) {

if(canAddMonopole(monopole)) {

for(Chamber c: chambers) {

if(c.canAddMonopole(monopole)){

c.addMonopole(monopole);

break;

}

}

}

}

}
This ship just places the monopole in the first chamber that can hold the monopole. I did two more types of ships to see how low I could get the chamber count. The lowest I could get it to was four. The other two ship classes can be found at http://darylmathisonblog.googlecode.com/svn/trunk/Monopole/src/ship/MaxChamberShip.java and http://darylmathisonblog.googlecode.com/svn/trunk/Monopole/src/ship/MinChamberShip.java.

Factories

Whenever I use interfaces, I normally want to use a factory to hide the implementation. This involves making a singleton and defining a method that returns the instance of the class you want. Then if I want to have a more dynamic factory, I need to define a property that tells the factory what class to create. If this sounds like a pain, it is a pain. What would happen if one could create a factory in a line of xml? What if one could define a factory that could instantiate several different classes all by just setting a property in an XML file? Both of those factories are possible in Spring.

DI depends on factories. The dependency is injected in from an outside source. Spring implementing DI creates objects via its BeanFactory or its ApplicationContext. The basic line of code that uses a spring injection is like this:
chamber = cxt.getBean(“chamber”, Chamber.class);
The object is created by Spring, not by using new. By default, all beans are singletons. Imagine that, every time the above line is called the same object is returned. This can be used everywhere a singleton is needed. The line in the configuration file that creates the bean is:

There it is, a factory that creates a singleton. As long as one uses the same id or name, the same instance is returned. This would be a problem for adding chambers to a ship. There in effect would be only one chamber! The Spring framework has an attribute in the bean tag named “scope.” There are several types of scopes, the majority of them are used for web applications. The ones that I am interested in are singleton (default) and prototype. The prototype scope creates a different instance every time one injects the bean. This is ideal for adding new chambers into a ship. The configuration line is this:

The only change is adding the scope and setting it to prototype. This way does not depend on anything that is specific to Spring. This trick can be used in other IoC frameworks. There is a Spring factory interface. It is named org.springframework.beans.factory.FactoryBean. Requires the three methods to be implemented:
public <? > getObject() throws Exception;

public Class<?> getObjectType();

public boolean isSingleton();
There is another interface that I used and that is org.springframework.beans.factory.InitializingBean. This defines the method that is called after a property is set. The method is:
public void afterPropertiesSet() throws Exception;
To configure Spring to use a FactoryBean one uses the factory class at the class attribute. An example is below:

This line configures Spring to call the factory when the ApplicationContext is called to inject firstChamberShip. One can add properties to the factory to make it create different beans. As one can tell from the above example line, I used a factory bean to create the different types of ships. I created an enum class to choose which one is created. Here is the class:
package ship;

public enum ShipType {

FIRSTCOME,

LARGEST,

SMALLEST;

}
I created the property shipType and set in the configuration file. Here is the full factory bean class that I made to create the different ships.
package ship;

import org.springframework.beans.factory.FactoryBean;

import org.springframework.beans.factory.InitializingBean;

public class ShipFactory implements FactoryBean, InitializingBean{

private Ship ship;

private ShipType shipType = ShipType.FIRSTCOME;

@Override

public Ship getObject() throws Exception {

return ship;

}

@Override

public Class<?> getObjectType() {

return Ship.class;

}

@Override

public boolean isSingleton() {

return true;

}

@Override

public void afterPropertiesSet() throws Exception {

if(shipType == ShipType.FIRSTCOME){

ship = new FirstChamberShip();

} else if(shipType == ShipType.LARGEST){

ship = new MaxChamberShip();

} else if(shipType == ShipType.SMALLEST) {

ship = new MinChamberShip();

}

}

public void setShipType(ShipType shipType) {

this.shipType = shipType;

}

}
Notice that when after the properties are set, the member attribute ship is set. The FirstChamberShip is the default ship type for the factory.

Here is the full configuration file that defines the different beans used in the program.

LARGEST

SMALLEST

This is a simple configuration file. All it does is define four beans, one with a prototype scope and three using a FactoryBean.

Putting It All Together

This would not be a fair if I did not show how it all fits together in one place. To show how it all works, here is the main class, monopole.Monopole:
package monopole;

import chamber.Chamber;

import ship.Ship;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.GenericXmlApplicationContext;

public class Monopole {

public static void main(String[] args) {

ApplicationContext cxt =

new GenericXmlApplicationContext(“classpath:swing/monopole.xml”);

Ship maxShip = cxt.getBean(“maxChamberShip”, Ship.class);

Ship firstShip = cxt.getBean(“firstChamberShip”, Ship.class);

Ship minShip = cxt.getBean(“minChamberShip”, Ship.class);

run(firstShip, cxt);

run(maxShip, cxt);

run(minShip, cxt);

}

public static void run(Ship ship, ApplicationContext cxt) {

int numOfMono = 0;

Chamber chamber = cxt.getBean(“chamber”, Chamber.class);

ship.addChamber(chamber);

while (numOfMono < 52 && ship.getNumChambers() < 52){

for(int i = 1; i <= 52; i++) {

if (ship.canAddMonopole(i)){

numOfMono++;

ship.addMonopole(i);

} else {

numOfMono = 0;

chamber = cxt.getBean(“chamber”, Chamber.class);

ship.addChamber(chamber);

ship.reset();

break;

}

}

}

System.out.println(“largest num ” + numOfMono + ” with “

+ ship.getNumChambers() + ” chambers”);

System.out.println(ship);

}

}
The ships are defined then run is called to put them through their paces. Ships are given one chamber at first and seen if they can load all of the monopoles. If they cannot load all of the monopoles, they print out how many they could and how many chambers. If the number of chambers is greater than 52 then the number of chambers and what is in the chambers are printed out.

The source code project can be found at https://github.com/darylmathison/monopole-example. I used Netbeans 7.3 to develop the source code.

Conclusion

A puzzle was used to feature the different factory styles that can be done in the Spring Framework. One style is the standard bean definition. It can be customized to create different instances or a singleton. The other way is to create a FactoryBean. When using a FactoryBean, the class attribute of the bean definition is the FactoryBean. A property can be added to have different beans coming out of the same FactoryBean. Using both of these styles, I was able to test three different solutions to the monopole puzzle. I was able to only use four chambers to store all 52 monopoles.

References

  • Ho, Clarence and Harrop, Rob. Pro Spring 3. New York:Springer Science+Business Media, 2012. Print
  • Shasha, Dennis E. Doctor Ecco’s Cyberpuzzles. New York:W.W. Norton & Company, Inc. 2002. Print