Archive

Archive for July, 2010

Eclipse + Android + SVN = fail

July 28, 2010 14 comments

If you are developing a project in SVN (I’m sorry for your predicament) and using Eclipse, please heed my advice.  Otherwise you could unintentionally delete your source directory during a routine cleanup.

Now, how could you possibly do that? you might wonder.  Are you incompetent?  Well, maybe, but not in this case.  The situation was this: I was about to make a commit of some changes to the code and did a svn status before committing to ensure that everything was as I wanted it to be.  I noticed that there were dozens of files in the bin directory that either had question marks next to them (.class files) or showed up with exclamation points next to them (indicating that SVN thought they’d gone missing).  Given that the binary class files do not belong in version control, I went ahead and did a svn rm -rf bin (recursively delete all the files under bin).  I went ahead and finished the commit.  Later I went to make another commit and I got an error telling me that the src folder didn’t exist in the svn repository.  Horrified, I my unix history and then the svn commit log:

529  svn rm –force bin/
530  svn ci -m “Bin should not be under version control.”

Revision 249
Author:     ndunn
Date:   Mon Jul 26 14:52:14 2010 UTC (62 minutes, 34 seconds ago)
Log Message:

Bin should not be under version control.

trunk/projname/src/     deleted

Um.  What?  I’m pretty sure bin != src.  Well.  You’d think that.  But if you’re using Eclipse and haven’t dived in four menus deep, you’d be wrong.

You see, for some reason Eclipse copies all the files from the src folder into the bin folder when you build the project.  Why it does that, I’m not sure.  I’d love to know why.  Regardless of the reason, all of the files in the src are copied.  Including… the hidden .svn folders.  These folders are how subversion keeps track of the changes to your files.  The problem is, since the .svn folders were copied, and bin was deleted, it was exactly the same to svn as if I had deleted src.  Which is why my src folder disappeared.

How do you work around this?  Well, I mentioned earlier that by default eclipse copies all of the files from src to bin.  You can add filters so that certain files/extensions are ignored, if you know where to look.  In Eclipse, go to Preferences -> Java -> Building -> Output Folder and make sure that *.svn is on the line for filtered resources.  It will prompt you to rebuild your project.  Once it does so, you will not have this potential mistake looming over your head.

Finally, here’s the svn command you need to revert a folder if you accidentally delete it and check the deletion into source control.  Let’s assume you deleted the folder in revision n.  Then you want to fetch the status of that folder at n – 1

n = 249

svn  copy -r248 -m "Restore deleted trunk/src"  svn+ssh://username@company/path/to/trunk/src@248  svn+ssh://username@company/path/to/trunk/src

Thanks to the android developers group for helping me figure out what was going on; see here for details.

I have submitted a bug / feature enhancement request to the Eclipse developers so that the default behavior is a bit more sane.  You can find that bug report here. The commenters mention that installing the svn plugin for Eclipse fixes the problem, but I don’t think I or anyone else should have to install something just to have sensible behavior.

The StackOverflow post giving a shorter synopsis of the problem can be found here.

Conclusion:

Lots of Android developers use Eclipse to develop their projects due to the plugin support available.  I’d wager a fair number of them use SVN as well for their source control.  They should be very wary about the default behavior of Eclipse, and ensure that they filter to remove .svn files from being copied over to their src folder.  Take it from me – it’s not a good feeling seeing a commit message with your name on it deleting the src folder.  Or you could use git and not have to worry about any of these problems…

Categories: Android, eclipse, Java, svn

How to make git use TextMate as the default commit editor

July 21, 2010 2 comments
git config --global core.editor "mate -w"

Now when you do a git commit without specifying a commit message, TextMate will pop-up and allow you to enter a commit message in it. When you save the file and close the window, the commit will go through as normal. (If you have another text editor you prefer instead, just change the “mate -w” line to the preferred one)

For those curious what the -w argument is about, it tells the shell to wait for the mate process to terminate (the file to be saved and closed). Read this for more information about how to associate TextMate with various other shell scripts and programs.

Categories: textmate, Uncategorized, unix Tags: , ,

Nerdy on so many levels

July 21, 2010 1 comment

1337 StackOverflow Reputation

For those not hip to stupid Internet lingo: http://lmgtfy.com/?q=1337

Categories: Uncategorized Tags:

How to: Interact with remote Unix Systems

July 16, 2010 Leave a comment

If you’re a software developer or sysadmin, chances are that you will not always be working with a local machine.  That is where remote access comes in.  I’ve had to pick up how to do this through trial and error; hopefully this post will pull together information from all the disparate sources and will help newbies like myself learn a little more quickly.

This post will go through all the tools you will need to interact with remote Unix based systems while using Windows or Mac OSX.   Why am I focusing on interacting with Unix based systems?  Many of the computers you will want to access remotely will be running a variant of Linux (servers come to mind).  Besides, I guarantee you will be a more productive programmer / computer operator if you learn Unix command line tools.  I will be covering Unix command line tools in much greater depth in a later post.

Beginner

If all you need is to grab files off of a remote Unix computer or dump some files to said machine, you can use a client application to help.  If you’re on Windows, you will want a copy of WinSCP.   This is a GUI version of the command line tool secure copy (scp), and allows you to drag and drop files between your local machine and the remote computer.  For users uncomfortable with command line tools, this is the easiest way to add and grab files to remote machines.  WinSCP has some bizarre UI choices (the selection of file nodes is unlike anywhere else in the Windows OS) but it can be useful. For MacOSX you can use Fugu; it does much the same thing.

Intermediate

When copying and pasting files is not enough, you will need to roll your sleeves up and learn a few more tools. First, you need to get used to the idea of giving up your GUI windowing environment and interacting with a keyboard


The terminal.  Learn to love it

First, you will need to learn how to navigate a Unix directory tree, as you will not have the nice GUI environment you are used to.

Here is that same Directory viewed in the Terminal with the tree command:

Nick@Macintosh-2 ~/Desktop/TestDir$ tree .
.
|--  SubFolder1
|   |-- SubSubFolder1
|   `-- test.txt
|--  SubFolder2
`-- test.txt

3  directories, 2 files

I’m not going to duplicate all the information that’s already on the Internet about using the command line.  Here’s a few commands you’ll absolutely need to know.

Command
Description
cd change directory
ls list files in directory
cp copy files
mv move files
mkdir make directories

Once you are comfortable moving around your own directory structure using the command line, you’re ready to interact with a remote machine.

SSH

SSH stands for Secure Shell and is the primary way you will interact with remote computers.  When you have a connection to the computer via SSH, it is just as if you were a local user signed on and using the terminal.  Thus it is crucial that you understand how to use command line tools and navigate a UNIX based operating system.

See the man page for the full syntax, but the basic way to use ssh is as follows:

ssh  username@remotemachine

where remotemachine is either the name of the machine, if it’s on your local network and is mapped to an IP Address, or the IP address.  You must have an account on that machine, and permission to log in.  You will be prompted for a password if necessary.  There are plenty of guides online for how to use SSH, here’s a good intro guide.

Type ‘logout’ when you are finished.

Advanced

You can now log on to the remote machine and interact with it as if it were a local machine.  But what if you need to run scripts that take a long time to complete?  As it stands now, if your connection is terminated (either by purposely logging out or the connection being interrupted), whatever you are running will exit.  This happened to me when I was working from home; I started a batch job that would take around 6 hours to finish and after about 3 hours my Internet connection hiccuped, I lost the connection, and the whole run had to be restarted later.
How do you get around this problem?  Enter screenScreen is a Unix command line tool that allows you to do two things really well: open multiple terminal windows in one window and cycle between them, as well as persist your sessions after you logout.  If all it did were the latter, it would still be worth using as it allows you to start jobs and not be tied to the connection; as long as the remote machine stays on, your job will keep working.  The former capability is extremely useful as well; prior to this I would find myself opening multiple putty or cygwin windows, each of which would have an ssh connection to the remote machine, and each of which would necessitate me typing the password again.  In some cases I had 8 windows open at once, since I had to start 8 long-running jobs simultaneously.  Now I only have to create one window, ssh into the remote machine, start (or resume) a screen session, create all the windows I need, start whatever work I need to do, detach the session, and now my work continues in the background.

If you’re on a Linux box, you’ve probably already got screen installed.  If you’re on Windows running Cygwin, there’s a patch to add screen support.  If you’re on Mac, you can use MacPorts (one of my essential pieces of Mac software) to install screen:

port  install screen
There are many excellent tutorials on screen; you should check them out for more in-depth looks at the options.  Check out the man page as well.  Here is the bare minimum of what you need to know how to do:
Before screen is launched (in standard terminal)
Command
Description
screen
Launches the screen program; you might see information popup describing the program
screen -S name
Creates a new screen session instance named ‘name’
screen -r
If there’s only one saved screen session, resume it; else displays the list of screen sessions available
screen -r text
Resume the screen session whose name includes ‘text’; if it’s ambiguous it will tell you so and you need to be more specific

While screen is running

Command
Description
Ctrl-a ? Display all the keyboard commands
Ctrl-a “
List all the current windows in the screen session
Ctrl-a A
Rename the current window
Ctrl-a k Kill the current window (pops up a Dialog question)
Ctrl-a d Disconnect from the screen session; you can resume it later with screen -r
Ctrl-a c Create a new window
Ctrl-a p Go to previous window
Ctrl-a n Go to next window
Ctrl-a S Split the window
Ctrl-a Q Quit splitting the windows (go back to one)
Ctrl-a Tab Jump between split windows
Ctrl-a a Invoke a literal ctrl-a (jump to first character of input)

If you’re a Unix guru who’s used to navigating through text with Ctrl-a to jump to the start of a line, this last command is very useful (and I just found it while researching this post; it was driving me nuts previously).  On Windows the Ctrl-a a shortcut is not necessary; you can hit Home to jump to the front of the line.  On a Mac, however, the Home key pages up.

Conclusion

Being able to interact with machines that are not right in front of you is a crucial skill to have in the IT business.  It can also be useful if you’re in school and need to retrieve a file that you saved on a machine somewhere and that you don’t feel like walking across campus to access locally.  There are all sorts of uses for the tools I’ve introduced here; hopefully this piques your interest and causes you to read more about them.

Categories: unix Tags: , , ,

Android: Principle of least surprise violation in GPS emulation

July 16, 2010 1 comment

Some of the most viewed posts on this blog have been about Android development, namely some workarounds for bizarre bugs that Google *still* has not fixed, months later.  I haven’t touched Android in a few months, but recently have started to dive back in.  Here’s yet another instance where an Android related piece of software performs completely counter-intuitively.

When developing an Android application, I often use the emulator rather than an actual hardware device.  In order to test GPS related functionality, you can either send simulated GPS events through the Dalvik Debug Monitor Service (DDMS) via Eclipse or through the Android terminal via telnet.  I’ll detail surprising bugs/defects in both ways.

DDMS

The DDMS Eclipse view is available after installing the ADT plugin, and it’s absolutely crucial in order to see logging messages produced from your application (“LogCat”).    It also allows you to send GPS coordinates, as the following screenshot shows.

Unfortunately there is a bug in this software that drove me up the wall, and I never would have figured it out myself.  I was running into the problem where the first GPS coordinate sent would be received by the emulator, but all subsequent ones would not.  It turns out the problem has to do with locales and decimals being treated as commas, or vice versa.  See the following Google bug report for more details.  The bug has been open over a year; fortunately it looks like it’s slated to be fixed in the next SDK release.

Telnet

If you telnet into your emulator instance, you have access to the Android console environment.

telnet localhost 5554

Android Console: type ‘help’ for a list of commands
OK

One of the commands you can send is fix, which send a latitude longitude pair to the emulator.  Well, that’s what I assumed it did.  After wondering why all my locations were were coming out incorrectly, I read the documentation a little more carefully.

fix <longitude> <latitude> [<altitude>] Send a simple GPS fix to the emulator instance. Specify longitude and latitude in decimal degrees. Specify altitude in meters.

There is a VERY strong convention to specify latitude before longitude.  (“latitude and longitude” returns 4,240,000 results as opposed to 542,000 for “longitude and latitude”)  Having this command take arguments in the opposite order is very surprising and counter-intuitive.   I notice that the DDMS screen has it longitude, latitude as well, but even within the Android APIs, you specify the latitude first!

I realize I should have read the documentation first, but it still is a flaw that the software behaves in unexpected manners (it violates the Principle of Least Surprise/Astonishment), and inconsistent with how API calls in the rest of the OS work.  If someone has an explanation for why it’s written this way, I’d love to hear it.

Edit: Later I learned that KML has the same convention, longitude followed by latitude. This corresponds with the x,y ordering conventional in math, so it’s perhaps not so surprising after all. This ordering problem is fairly minor in the grand scheme of things, and reflects more on my own inexperience with geospatial APIs than any fault of Android itself.

An introduction to Scala

July 15, 2010 1 comment

Functional programming plus Object Oriented Programming = Scala

An Introduction to Scala

Overview

  • Introduction
  • Why is it gaining popularity, and why should you care?
  • History
  • Functional programming
  • Syntax
  • Data structures
  • Benefits
  • Drawbacks
  • Conclusion

Introduction

  • Scala = scalable language.
    • From scripts all the way up to enterprise
  • Runs on JVM
  • Combines functional and object-oriented paradigms

Scala was designed to be both object-oriented and functional. It is a pure object-oriented language in the sense that every value is an object. Objects are defined by classes, which can be composed using mixin composition. Scala is also a functional language in the sense that every function is a value. Functions can be nested, and they can operate on data using pattern matching. Language creator Martin Odersky

Why?

  • Productive like a scripting language, but with type safety and speed
  • You can express yourself in fewer lines of code than equivalent Java.
  • Well suited to multithreaded environments
    • Actors and message passing

Less boilerplate

// Scala
case class Person(firstName: String, lastName: String)

// Java
public class Person implements Serializable {
    private final String firstName;
    private final String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Person withFirstName(String firstName) {
        return new Person(firstName, lastName);
    }

    public Person withLastName(String lastName) {
        return new Person(firstName, lastName);
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Person person = (Person) o;
        if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) {
            return false;
        }
        if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) {
            return false;
        }
        return true;
    }

    public int hashCode() {
        int result = firstName != null ? firstName.hashCode() : 0;
        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
        return result;
    }

    public String toString() {
        return "Person(" + firstName + "," + lastName + ")";
    }
}

Samples where Scala code is significantly shorter than Java

History

  • Martin Odersky created it
    • Functional programming and compiler background (wrote current javac reference compiler)
    • Worked on adding generics to Java
  • Design began in 2001, released in 2003
  • Version 2.80 Final released July 14, 2008

Functional programming

  • Avoid state and mutable data
  • Every variable is a constant
  • Lends itself to parallelization; avoid locking and deadlocks
  • First-class functions – functions can serve as arguments and results of functions
  • Recursion is primary tool for iteration
  • Heavy use of pattern matching
  • Lazy evaluation – infinite sequences

Who’s using Scala

  • Twitter uses for performance critical code; replaces Ruby in that regard
  • FourSquare uses Scala and Lift web framework
  • Xerox uses Scala and Lift
  • Etherpad uses Scala in its real time document collaboration software (acquired by Google for Google Docs; Scala code is now opensourced)

Syntax:

Hello world in Scala:

object HelloWorld extends Application {
  Console.println("Hello World")
}

No semicolons needed

Variables declared with val and var

val x = 0 // immutable
var y = 0 // mutable
x = 1 // compiler error
y = 1 // fine

Type declarations occur after the variable

int x = 0; // Java
val x: Int = 0 // Scala

Generic type arguments occur within square brackets rather than angle brackets

List<Integer> intList = ...; // java
val intList: List[Int] =  ..// scala

Array indexing is done through use of parentheses rather than square brackets

// Java
int[] x = {1,2,3,4};
x[0] // 1

// Scala
val x: Array[Int] = Array(1,2,3,4)
x(0) // 1

Method definitions

scala> def square(x:Int) = { x * x }
square: (Int)Int

scala> square(5)
res38: Int = 25

No such thing as a ‘void’ method, every method returns a value. void = “Unit” in Scala

scala> def printIt(x:Any) = { println(x) }
printIt: (Any)Unit

Type inferencing – note that I haven’t been declaring what types my methods take

// Compiler infers that the return type must be int
scala> def square(x:Int) = { x * x }
square: (Int)Int

// I can explicitly indicate what it returns if I prefer
scala> def squareExplicit(x:Int):Int = { x * x }
squareExplicit: (Int)Int

No need to explicitly return values

scala> def square(x:Int) = { x * x }
square: (Int)Int

scala> def squareExplicit(x:Int):Int = { return x * x }
squareExplicit: (Int)Int

// The result of last expression is returned.

Conditionals as values

// BAD.  Java style, mutable value
var x = 0
if (someCondition) {
    x = something
}
else {
    x = somethingElse
}

// GOOD: Scala style, immutable
val x = 
    if (someCondition) {
        something
    }
    else {
        somethingElse
    }

// or if short enough
val x = if(something) something else (somethingElse)

All operations are method calls

Scala doesn’t technically have operator overloading, because it doesn’t actually have operators in the traditional sense. Instead, characters such as +, -, *, and / can be used in method names. Thus, when you typed 1 + 2 into the Scala interpreter in Step 1 you were actually invoking a method named + on the Int object 1, passing in 2 as a parameter. As illustrated in Figure 3.1, you could alternatively have written 1 + 2 using traditional method invocation syntax (1).+(2).
“Programming in Scala, p. 39”

What good does that do me?

If your domain objects make sense to add, multiply, divide, etc., you can treat them in a much more natural way.

// BigInt is a wrapper around Java's BigInteger, providing arithmetic methods
scala> BigInt("103058235287305927350") + BigInt("288888203959230529352")
res16: BigInt = 391946439246536456702

// In Java you're stuck calling .add, .multiply, etc
scala> new java.math.BigInteger("103058235287305927350").add(new java.math.BigInteger("288888203959230529352"))
res21: java.math.BigInteger = 391946439246536456702

Data structures

Lists

More powerful than Java lists. Expose a whole raft of Functional Programming paradigms, such as map, reduce, filter, folds, etc.

// Note the syntax; you do not call "new".  This is because there is
// an apply ("()") method defined in the List object.
scala> val a = List("hello","how","are","you")
a: List[java.lang.String] = List(hello, how, are, you)

// Explicit
val nums:List[Int] = List(1,2,3,4)

scala> a.size
res40: Int = 4

scala> a.mkString(" ")
res41: String = hello how are you

scala> a.map(x => x.toUpperCase())
res42: List[java.lang.String] = List(HELLO, HOW, ARE, YOU)

scala> a.map(x => x.length())     
res43: List[Int] = List(5, 3, 3, 3)

scala> a.filter(x => x.startsWith("h"))
res44: List[java.lang.String] = List(hello, how)

scala> a.forall(x => x.length() > 0)
res46: Boolean = true

// Singly linked list
scala> a.head
res67: java.lang.String = hello

scala> a.tail
res68: List[java.lang.String] = List(how, are, you)

// add to head
scala> 1 :: List(2)      
res70: List[Int] = List(1, 2)

// reverse
scala> a.reverse  
res72: List[java.lang.String] = List(you, are, how, hello)

Tuples

Tuples are a good data structure to pack up multiple variables to return from a function, without the need to define a helper class to do so. Slightly syntax to create them, as well as to access the elements contained therein.

// Explicitly create the tuple; never really a need to do this
scala> val a:Tuple2[Int,Int] = (5,6)
a: (Int, Int) = (5,6)

// The parentheses indicate it's a tuple
scala> val b = (5,6)
b: (Int, Int) = (5,6)

// Yes, I know it's a strange syntax.  And it's 1-based rather than 0-based.  This is because Haskell has 1-based tuple ordering and Odersky wanted to stay true to that.
scala> a._1
res48: Int = 5

scala> a._2
res49: Int = 6

// You can have an arbitrary number of elements, of any type you want
val listTuple = (List(1,2,3), "hello", new java.awt.Color(255,0,0))
scala> val listTuple = (List(1,2,3), "hello", new java.awt.Color(255,0,0))
listTuple: (List[Int], java.lang.String, java.awt.Color) = (List(1, 2, 3),hello,java.awt.Color[r=255,g=0,b=0])

Maps

Scala provides immutable maps as well as a syntax for creating map literals.

scala> val theMap = Map("hello"->5,"world"->5)
theMap: scala.collection.immutable.Map[java.lang.String,Int] = Map(hello -> 5, world -> 5)

scala> theMap("hello")
res50: Int = 5

scala> theMap.getOrElse("world",2)
res51: Int = 5

scala> theMap.getOrElse("worldly",2)
res52: Int = 2

scala> theMap.keySet  
res54: scala.collection.Set[java.lang.String] = Set(hello, world)

scala> theMap.values
res55: Iterator[Int] = non-empty iterator

scala> theMap.values.toList
res56: List[Int] = List(5, 5)

// Mutable map:
var mutableMap = Map[Int, String]()
mutableMap += (1 -> "1")
mutableMap += (2 -> "2")

Arrays

Internally map to Java arrays. Idiomatic Scala code tends to prefer Lists to Arrays, but they are necessary for interacting with a lot of Java code. Create in same way as lists.

scala> val array = Array(1,2,3)
array: Array[Int] = Array(1, 2, 3)

Benefits

  • Static type checking but with improved type inference

    // Java
    private Map wordCount = new HashMap();
    // Scala:
    var wordCount:Map[String, Int] = Map()

  • Much faster than Python/Ruby and other interpreted languages, but just as expressive

  • Duck typing support
  • Conciseness
    • Functions as first class objects; no need for anonymous classes and extraneous interfaces Unified types
  • Traits are a cross between interfaces and abstract classes, allowing you to provide default implementations. Allows for ‘mix-in’ composition, as well. Solves problems with multiple inheritance, while giving flexibility. Avoid repeating yourself.
  • Console REPL environment allows you to quickly iterate and test
  • Of theoretical interest
    • Combines functional and object-oriented in statically-typed environment

Drawbacks/Complaints

  • Immaturity of tool chain
  • Binary/source incompatibility from rapid change of language
  • Type system is very complex
  • Functional programming can be hard to wrap head around for people familiar with OOP
  • Syntax can be so concise as to be cryptic

    For instance, the following example comes from StackOverflow post.

    def scanLeft[a,b](xs:Iterable[a])(s:b)(f : (b,a) => b) =
    xs.foldLeft(List(s))( (acc,x) => f(acc(0), x) :: acc).reverse
    

    And then use it like this:

    scala> scanLeft(List(1,2,3))(0)(_+_)
    res1: List[Int] = List(0, 1, 3, 6)
    

Conclusion

Scala is a very intriguing language due to its combination of object orientation with functional programming concepts. The programmer is not forced to choose between the expressiveness of objects and immutability; he can switch between the two paradigms as the situation warrants.

While binary/source incompatibility is a very real problem for enterprise adoption, it is an issue that the creators are working on.

Scala provides a great framework in which to explore functional programming methods, especially through the use of the interactive console environment.

Resources

Images:

XStream introduction and Java Collections serialization problem workaround

July 13, 2010 3 comments

XStream is an open-source Java library for converting objects to and from XML.  I’ll introduce how to use the library, show a problem I ran into that was a bit difficult to track down, as well as a workaround.

Library example

Imagine we are modeling a library in XML.  This will be much simplified for the purposes of illustration.  A sample XML library document might look like the following:

<library>
  <books>
    <book>
      <title>The Talent Code: Greatness Isn't Born. It's Grown. Here's How.</title>
      <author>Daniel Coyle</author>
    </book>
  </books>
</library>

Let’s write some Java classes to represent this hierarchy.

public class Library {
    public List<Book> books;

    public Library(List<Book> books) {
        this.books = books;
    }

    @Override
    public String toString() {
        StringBuilder b = new StringBuilder();
        b.append("Library with " + books.size() + " books:\n");
        for (Book book : books) {
            b.append(book.toString());
            // Skip a line
            b.append("\n");
        }
        return b.toString();
    }

    public static class Book {
        private String title;
        private String author;

        public Book(String title, String author) {
            this.title = title;
            this.author = author;
        }

        @Override
        public String toString() {
            return "\"" + title + "\" by " + author;
        }
    }

    public static void main(String[] args) {
        List<Book> books = new ArrayList<Book>();
        books.add(new Book("The Talent Code: Greatness Isn't Born. It's Grown. Here's How", "Daniel Coyle"));

        Library lib = new Library(books);
        // Handles conversion of our objects into XML
        XStream stream = new XStream(new DomDriver());

        String xml = stream.toXML(lib);
        // fromXML returns a general Object; need to cast it into a Library
        Library lib2 = (Library) stream.fromXML(xml);

        System.out.println(xml);
        System.out.println(lib);
        System.out.println(lib2);
        System.out.println("Libraries equal: " + lib.toString().equals(lib2.toString()));
    }
}

This is not production worthy by any means; in general comparing the string representations of objects to test for equality is a very bad idea.  But writing a foolproof equals method is very difficult and irrelevant to the point of this post.  Here is the output produced by running the program:

<Library>
  <books>
    <Library_-Book>
      <title>The Talent Code: Greatness Isn&apos;t Born. It&apos;s Grown. Here&apos;s How</title>
      <author>Daniel Coyle</author>
    </Library_-Book>
  </books>
</Library>
Library with 1 books:
"The Talent Code: Greatness Isn't Born. It's Grown. Here's How" by Daniel Coyle

Library with 1 books:
"The Talent Code: Greatness Isn't Born. It's Grown. Here's How" by Daniel Coyle
Libraries equal: true

This is somewhat close to what we want, but not exactly.  (Note that the &apos; stuff in the middle of the title is not a mistake; I was imprecise by including apostrophes in the original XML example.  See here for an explanation of why apostrophes are treated specially in XML). Let’s start by aliasing some of the tag names.  The relevant change is as follows:

XStream stream = new XStream(new  DomDriver());
stream.alias("library", Library.class);
stream.alias("book",  Book.class);

Output:

<library>
  <books>
    <book>
      <title>The Talent Code: Greatness Isn&apos;t Born. It&apos;s Grown. Here&apos;s How</title>
      <author>Daniel Coyle</author>
    </book>
  </books>
</library>

Initial success

OK, looks like things are working!  But the way of constructing the list is not how I normally create lists.  Let’s make sure the serialization works for alternative means of List construction.

Book talentCode =  new Book("The Talent Code: Greatness Isn't Born. It's Grown. Here's  How", "Daniel Coyle");
Library lib = new  Library(Arrays.asList(talentCode));

For you who haven’t seen the use of Arrays.asList, it’s a method to convert an array (or varargs) into a List.  It’s important for compatibility between array based and collection based frameworks.  The corresponding method in the opposite direction, from Collections to arrays is the Collections.toArray.  For the truly nerdy, here’s an interesting discussion of possible implications of calling toArray in a multithreaded environment.
Anyways, here’s the output.

<library>
  <books class="java.util.Arrays$ArrayList">
    <a class="book-array">
      <book>
        <title>The Talent Code: Greatness Isn&apos;t Born. It&apos;s Grown. Here&apos;s How</title>
        <author>Daniel Coyle</author>
      </book>
    </a>
  </books>
</library>
Library with 1 books:
"The Talent Code: Greatness Isn't Born. It's Grown. Here's How" by Daniel Coyle

Library with 1 books:
"The Talent Code: Greatness Isn't Born. It's Grown. Here's How" by Daniel Coyle

Libraries equal: true

Hmmm.  The XML serialization/deserialization still works but it’s sure not pretty.  What’s going on here?  Why did it print “books” earlier but now it throws in all that ugly stuff about “java.util.Arrays$ArrayList”?

The answer is that XStream has a powerful set of converters that handle mapping Java constructs to and from XML.  The relevant converter is the CollectionConverter.  Here is the JavaDoc description, and the solution to the mystery:

Converts most common Collections (Lists and Sets) to XML, specifying a nested element for each item.

Supports java.util.ArrayList, java.util.HashSet, java.util.LinkedList, java.util.Vector and java.util.LinkedHashSet.

The problem is that creating a List via the Arrays.toList method does not create an instance of any of these classes.  Instead, it returns an instance of an inner class named ArrayList (not to be confused with the java.util.ArrayList).  Read the source of the java.util.Arrays class if you are interested in the implementation details.

What’s the workaround?  Don’t blindly accept the list of books that is passed into the constructor.  Instead, make a defensive copy.

public List<Book> books = new  ArrayList<Book>();

public Library(List<Book>  books) {
      this.books.addAll(books);
 }

Sure enough, this fixes the problem, as the actual class of the list of books is now one that the converter supports.  Alternatively we could change the implementation of CollectionConverter to support the Arrays$ArrayList class, but it’s probably not worth it.

Conclusion

I introduced the XStream library for Java which handles the conversion of objects to and from XML.  I presented a very simple Java example of a Library and its collection of books, as well as a problem that arises from the way XStream converts collections into XML.