<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-11505453</id><updated>2011-04-23T00:55:41.144+01:00</updated><title type='text'>Shane Bell</title><subtitle type='html'>&lt;a href="http://shanebell.blogspot.com/2005/10/random-thoughts-on-random-things.html"&gt;My thoughts on... well, anything that springs to mind really.&lt;/a&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://shanebell.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-11505453.post-4685983672495579101</id><published>2007-05-30T13:56:00.000+01:00</published><updated>2007-05-30T13:58:41.397+01:00</updated><title type='text'>This blog has moved!</title><content type='html'>This blog has moved to &lt;a href="http://blog.onlysimpler.com"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The new rss feed can be found at &lt;a href="http://blog.onlysimpler.com/rss.xml"&gt;blog.onlysimpler.com/rss.xml&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-4685983672495579101?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/4685983672495579101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/4685983672495579101'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2007/05/this-blog-has-moved.html' title='This blog has moved!'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-116415234292940918</id><published>2006-11-21T23:31:00.000Z</published><updated>2006-11-21T23:39:02.960Z</updated><title type='text'>SchemaSpy</title><content type='html'>If you're working on a project that uses a relational database (I don't think I've ever worked on one that didn't) then you really need to check out &lt;a href="http://schemaspy.sourceforge.net/"&gt;SchemaSpy&lt;/a&gt;. It's a great tool that automatically produces a complete overview of your schema - diagrams and all.&lt;br /&gt;&lt;br /&gt;Here's a &lt;a href="http://schemaspy.sourceforge.net/sample/index.html"&gt;sample&lt;/a&gt; of what it can produce.&lt;br /&gt;&lt;br /&gt;It's very useful for navigating around the tables and seeing relationships between them. It even does some analysis of your schema to identify any potential problems.&lt;br /&gt;&lt;br /&gt;One thing to note is that it takes a static "snapshot" of your schema. The information is not produced in real time, so you'll need to re-run the program now and again to keep it up to date.&lt;br /&gt;&lt;br /&gt;The application itself is a single jar file that you can execute from a command line. You'll also need a JDBC driver so it can talk to your database.&lt;br /&gt;&lt;br /&gt;Finally, in order to produce all the fancy diagrams, you'll need the "dot" executable from &lt;a href="http://www.graphviz.org/"&gt;Graphviz&lt;/a&gt;. Check the docs for more info on that.&lt;br /&gt;&lt;br /&gt;And best of all - it's free (as in beer).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-116415234292940918?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/116415234292940918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/116415234292940918'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/11/schemaspy.html' title='SchemaSpy'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-116162555892706639</id><published>2006-10-23T18:45:00.000+01:00</published><updated>2006-10-23T18:49:34.333+01:00</updated><title type='text'>Subversion - the 30 second guide</title><content type='html'>Setting up a &lt;a href="http://subversion.tigris.org"&gt;Subversion&lt;/a&gt; repository is one of those things that I can never seem to remember how to do. I guess that's because you tend to do it once at the start of a project and it might be 6 months before you need to do it again. And by that time you've forgotten how to do it and need to go search through the docs.&lt;br /&gt;&lt;br /&gt;So here is a very quick guide to setting up a new repository.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;Create a new repository.&lt;br/&gt;&lt;br /&gt;    $ svnadmin create path_to_repository&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;   &lt;br /&gt;  &lt;li&gt;Modify the svnserve.conf and passwd files.&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Create new project directory.&lt;br/&gt;&lt;br /&gt;    $ svn mkdir svn://path/to/repo/myproject&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;li&gt;Create a sub-directory for the trunk (you can create branches and tags later if necessary).&lt;br/&gt;&lt;br /&gt;    $ svn mkdir svn://path/to/repo/myproject/trunk&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;li&gt;Checkout the project and start working.&lt;br/&gt;&lt;br /&gt;    $ svn checkout svn://localhost/repository/project/trunk .&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-116162555892706639?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/116162555892706639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/116162555892706639'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/10/subversion-30-second-guide.html' title='Subversion - the 30 second guide'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-115942955846826398</id><published>2006-09-28T08:45:00.000+01:00</published><updated>2006-09-28T08:53:42.890+01:00</updated><title type='text'>Synchronized Collections in Java</title><content type='html'>This is just a quick word of advice to anyone out there writing threaded code with collections. I recently had to fix an old neglected web application that was having some serious threading issues and came across this little gem.&lt;br /&gt;&lt;br /&gt;Creating a synchronized collection is as easy. All you need to do is...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;List&amp;lt;Long&amp;gt; myList = Collections.synchronizedList(new ArrayList&amp;lt;Long&amp;gt;());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, be careful when iterating over the collection. You still need to manually synchronize code that iterates over it, even though the collection itself is synchronized. Standard operations like adding or removing elements from the collection are thread-safe and will behave as expected in a multi-threaded environment. But iterating is not as simple.&lt;br /&gt;&lt;br /&gt;If you want to iterate over a collection that will potentially be accessed by other threads simultaneously, always synchronize on the list itself. ie:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;List&amp;lt;Long&amp;gt; myList = Collections.synchronizedList(new ArrayList&amp;lt;Long&amp;gt;());&lt;br /&gt;  &lt;br /&gt;// thread safe code&lt;br /&gt;synchronized(myList) {&lt;br /&gt;    for (Long l : myList) {&lt;br /&gt;        // do something with l here&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Failure to synchronize on the collection can cause all kinds of unexpected behaviour. Typically you'll get a ConcurrentModificationException if the collection is modified while you're iterating over it, but there are no guarantees. And that's the problem. An application that falls over and dies is bad, but at least you know it's broken. An application that continues on merrily despite being broken is a very bad thing!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-115942955846826398?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/115942955846826398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/115942955846826398'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/09/synchronized-collections-in-java.html' title='Synchronized Collections in Java'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-115936034911961492</id><published>2006-09-27T13:32:00.000+01:00</published><updated>2006-09-27T13:32:41.593+01:00</updated><title type='text'>Closures In Java</title><content type='html'>There's been &lt;a href="http://gafter.blogspot.com/2006/08/closures-for-java.html"&gt;some talk&lt;/a&gt; recently about adding &lt;a href="http://blogs.sun.com/roller/resources/ahe/closures.pdf"&gt;closures&lt;/a&gt; to the Java language.&lt;br /&gt;&lt;br /&gt;I've spent quite a bit of time writing Ruby code recently, and it's amazing how useful closures and code blocks can be. They're one of those things - once you know how to use them, you start noticing all kinds of places in your code that could be solved using closures. It's like when you learn a definition of a new word and suddenly you start hearing it in conversations everywhere.&lt;br /&gt;&lt;br /&gt;It will be interesting to see how the proposal turns out, but unfortunately we'll have to wait until Java 7 to use them. Considering how many people still haven't made the move to Java 5, this could be a while for some.&lt;br /&gt;&lt;br /&gt;In the meantime, there are a number of hacks that you can use to provide similar functionality to a closure. In fact, &lt;a href="http://jakarta.apache.org/commons/collections/"&gt;Apache Commons Collections&lt;/a&gt; even has some built in classes that provide closure-like functionality.&lt;br /&gt;&lt;br /&gt;But if you need something quick and dirty, this should do the trick.&lt;br /&gt;&lt;br /&gt;First, define a simple interface to represent a closure:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface Closure {&lt;br /&gt;    &lt;br /&gt;    public void execute(Object o);&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The next step is to create a method that calls the execute method of the closure. The following example iterates over a collection and calls the execute method on every object.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public static void execOnEach(Collection&lt;?&gt; collection, Closure closure) {&lt;br /&gt;    for (Object o : collection) {&lt;br /&gt;        closure.execute(o);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally, we write some code that uses the closure interface to execute a block of code on every object in a collection. We do this by creating an anonymous instance of the closure.&lt;br /&gt;&lt;br /&gt;This example uses a collection of StringBuffer objects. The first call to execOnEach() converts each buffer to upper case, while the second call reverses the contents of the buffers.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;        &lt;br /&gt;    Collection&lt;StringBuffer&gt; c = new ArrayList&lt;StringBuffer&gt;();&lt;br /&gt;    c.add(new StringBuffer("abcdefg"));&lt;br /&gt;    c.add(new StringBuffer("hijklmn"));&lt;br /&gt;    System.out.println("c = " + c);&lt;br /&gt;&lt;br /&gt;    // capitalise everything&lt;br /&gt;    execOnEach(c, new Closure() {&lt;br /&gt;        public void execute(Object o) {&lt;br /&gt;            StringBuffer buffer = (StringBuffer) o;&lt;br /&gt;            buffer.replace(0, buffer.length(), buffer.toString().toUpperCase());&lt;br /&gt;        }&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;    System.out.println("c = " + c);&lt;br /&gt;    &lt;br /&gt;    // reverse the strings&lt;br /&gt;    execOnEach(c, new Closure() {&lt;br /&gt;        public void execute(Object o) {&lt;br /&gt;            StringBuffer buffer = (StringBuffer) o;&lt;br /&gt;            buffer.reverse();&lt;br /&gt;        }&lt;br /&gt;    });&lt;br /&gt;    &lt;br /&gt;    System.out.println("c = " + c);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is a pretty trivial example, but you get the idea.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-115936034911961492?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/115936034911961492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/115936034911961492'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/09/closures-in-java.html' title='Closures In Java'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-115650882671462303</id><published>2006-08-25T13:26:00.000+01:00</published><updated>2006-08-25T13:50:13.490+01:00</updated><title type='text'>Exposing Your Privates</title><content type='html'>If you've ever written any serious &lt;a href="http://www.junit.org"&gt;unit tests&lt;/a&gt; for your code then you'll know that testing private methods can be a bit tricky. The only class that has access to a private method is the class that defines it. So how are you supposed to test it from another class that doesn't have visibility of the method?&lt;br /&gt;&lt;br /&gt;One solution would be to NOT declare it as private. This would work, but it's not much of a solution. Methods are made private for good reason and you can't just go around changing their access to suit your testing needs. That's just wrong. &lt;br /&gt;&lt;br /&gt;Purists would say that you should test private methods via the public methods that expose their functionality. Purist say a lot of crap.&lt;br /&gt;&lt;br /&gt;Seriously though, sometimes you need to test a private method, and there just no way around it. Fortunately there's easy solution to the problem. A bit of reflection should do the trick.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/**&lt;br /&gt; * Invokes a private method on a class or object. This method&lt;br /&gt; * can invoke static methods on classes, and instance methods&lt;br /&gt; * on objects.&lt;br /&gt; * &lt;br /&gt; * When invoking an instance method, the instance of the object&lt;br /&gt; * must be passed as the first parameter. For static methods,&lt;br /&gt; * this parameter can be null.&lt;br /&gt; * &lt;br /&gt; * @param object the object to invoke the method on (this is&lt;br /&gt; *        only applicable for instance methods, can be null&lt;br /&gt; *        for static methods).&lt;br /&gt; * @param clazz the class of object.&lt;br /&gt; * @param methodName the name of the method to invoke.&lt;br /&gt; * @param parameters parameters passed to the method.&lt;br /&gt; * @return result from the method or null if method returns void.&lt;br /&gt; */&lt;br /&gt;public static Object invokePrivateMethod(Object object,&lt;br /&gt;                                         Class clazz,&lt;br /&gt;                                         String methodName,&lt;br /&gt;                                         Object... parameters) {&lt;br /&gt;    &lt;br /&gt;    // build an array of parameter types&lt;br /&gt;    Class[] params = new Class[parameters.length];&lt;br /&gt;    for (int i = 0; i &lt; parameters.length; i++) {&lt;br /&gt;        params[i] = parameters[i].getClass();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    Object result = null;&lt;br /&gt;    &lt;br /&gt;    // try to execute the method&lt;br /&gt;    try {&lt;br /&gt;        Method method = clazz.getDeclaredMethod(methodName, params);&lt;br /&gt;        method.setAccessible(true);&lt;br /&gt;        &lt;br /&gt;        // are we invoking a static method or an instance method?&lt;br /&gt;        if (object != null) {&lt;br /&gt;            result = method.invoke(object, parameters);&lt;br /&gt;        } else {&lt;br /&gt;            result = method.invoke(clazz, parameters);&lt;br /&gt;        }&lt;br /&gt;    } catch (Exception e) {&lt;br /&gt;        e.printStackTrace();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The javadoc comment pretty much explains it, but here's a quick example that you shows how to use it. &lt;br /&gt;&lt;br /&gt;Let's assume we have a class called Greeter that looks like this.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Greeter {&lt;br /&gt;    &lt;br /&gt;    // a private instance member&lt;br /&gt;    private String name;&lt;br /&gt;    &lt;br /&gt;    // public constructor&lt;br /&gt;    public Greeter(String name) {&lt;br /&gt;        this.name = name;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // static method that responds with a cheery greeting&lt;br /&gt;    private static String sayHello(String name) {&lt;br /&gt;        return "Hello " + name;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // instance method that responds with a cheery greeting&lt;br /&gt;    private String sayHello() {&lt;br /&gt;        return "Hello " + this.name;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice it has two private methods. One is a static method, the other is an instance method. Using &lt;code&gt;invokePrivateMethod()&lt;/code&gt; that we defined earlier we can invoke these methods as follows.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// invoke a static method&lt;br /&gt;invokePrivateMethod(null, Greeter.class, "sayHello", "Shane");&lt;br /&gt;    &lt;br /&gt;// invoke an instance method&lt;br /&gt;Greeter greeter = new Greeter("Shane");&lt;br /&gt;invokePrivateMethod(greeter, greeter.getClass(), "sayHello");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now you really have no excuse for not writing unit tests ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-115650882671462303?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/115650882671462303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/115650882671462303'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/08/exposing-your-privates.html' title='Exposing Your Privates'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-115640765927480690</id><published>2006-08-24T09:19:00.000+01:00</published><updated>2006-08-24T09:21:36.696+01:00</updated><title type='text'>I'm Back</title><content type='html'>It's been a while, but I'm back.&lt;br /&gt;&lt;br /&gt;No real excuse, other than the fact that I've been out enjoying the summer. But now that that's over you can expect to hear a bit more from me, hopefully regularly.&lt;br /&gt;&lt;br /&gt;I've added a few new books to my &lt;a href="http://shanebell.blogspot.com/2006/03/some-more-books.html"&gt;ultimate reading list&lt;/a&gt;. You'll notice a couple of Ruby books have snuck in there. I'll go into that in a bit more detail in an upcoming post.&lt;br /&gt;&lt;br /&gt;I've also added some more &lt;a href="http://shanebell.blogspot.com/2006/05/random-technical-stuff.html"&gt;random technical things&lt;/a&gt; that I always seem to forget.&lt;br /&gt;&lt;br /&gt;That's it for now, but I've got lots of new things in the pipeline so stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-115640765927480690?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/115640765927480690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/115640765927480690'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/08/im-back.html' title='I&apos;m Back'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-114910914372648546</id><published>2006-05-31T21:30:00.000+01:00</published><updated>2006-08-24T09:19:26.203+01:00</updated><title type='text'>Random Technical Stuff</title><content type='html'>This post is just a collection of random technical stuff that I can never seem to remember. I find myself regularly wasting loads of time researching something that I did just a few months (or even weeks) ago. So I figured I'd put together my own collection of technical bits and pieces here so I can refer back to them as I need them.&lt;br /&gt;&lt;br /&gt;It's also a place for me to collect all my templates for development (things like Ant scripts, Struts config files, etc).&lt;br /&gt;&lt;br /&gt;I'll try and update this list regularly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Java&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;&lt;a href="http://shanebell.f2s.com/downloads/build.xml" aiotitle="Template Ant script"&gt;Template Ant script&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;a href="http://shanebell.f2s.com/downloads/log4j.properties"&gt;Template log4j properties file&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;More to come...&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Oracle&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;To create an Oracle synonym...&lt;br /&gt;    &lt;span style="font-family:Courier;font-size:85%;"&gt;&lt;br /&gt;      &lt;span style="FONT-WEIGHT: bold"&gt;create synonym &amp;lt;name&amp;gt; for &amp;lt;schema&amp;gt;.&amp;lt;object&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;/span&gt;&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;To select the next value in an Oracle sequence...&lt;br /&gt;    &lt;span style="font-family:Courier;font-size:85%;"&gt;&lt;br /&gt;      &lt;span style="FONT-WEIGHT: bold"&gt;select &amp;lt;sequence_name&amp;gt;.nextval from dual&lt;/span&gt;&lt;br /&gt;    &lt;/span&gt;&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;To find out the standard TNS details for a global database name run the NAMESCTL command and execute the following query at the prompt...&lt;br /&gt;    &lt;span style="font-family:Courier;font-size:85%;"&gt;&lt;br /&gt;      &lt;span style="FONT-WEIGHT: bold"&gt;query &amp;lt;global_db_name&amp;gt; A.SMD&lt;/span&gt;&lt;br /&gt;    &lt;/span&gt;&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;To add a constraint to a table...&lt;br /&gt;    &lt;span style="font-family:Courier;font-size:85%;"&gt;&lt;br /&gt;      &lt;span style="FONT-WEIGHT: bold"&gt;alter table &amp;lt;schema_name&amp;gt;&lt;schema_name&gt;.&amp;lt;table_name&amp;gt;&lt;table_name&gt; add (constraint &lt;key_name&gt;&amp;lt;key_name&amp;gt; primary key (&amp;lt;columns&amp;gt;&lt;columns&gt;))&lt;/columns&gt;&lt;/key_name&gt;&lt;/table_name&gt;&lt;/schema_name&gt;&lt;br /&gt;      &lt;/span&gt;&lt;br /&gt;    &lt;/span&gt;&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;To run a sql script from sqlplus (and pass the parameter 123)...&lt;br /&gt;    &lt;span style="font-family:Courier;font-size:85%;"&gt;&lt;br /&gt;      &lt;span style="FONT-WEIGHT: bold"&gt;SQLPLUS  &amp;lt;username&amp;gt;/&amp;lt;password&amp;gt;@&amp;lt;dbname&amp;gt; @script.sql 123&lt;/span&gt;&lt;br /&gt;    &lt;/span&gt;&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;SSH&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;More to come...&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-114910914372648546?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114910914372648546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114910914372648546'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/05/random-technical-stuff.html' title='Random Technical Stuff'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-114294038513075247</id><published>2006-03-21T11:15:00.000Z</published><updated>2006-03-21T11:28:31.663Z</updated><title type='text'>Oracle SQL Developer</title><content type='html'>Oracle have just released a new visual SQL that is well worth a look. I'm big fan of &lt;a href="http://www.toadsoft.com/"&gt;Toad&lt;/a&gt;, but you have to pay for it because the free version stops working after 30 days. Oracle's new tool is free, and everybody likes free stuff.&lt;br /&gt;&lt;br /&gt;It does a pretty good job of all the standard stuff you ever need to do when working with a database and it has some nice visual tools and wizards. It's one big downfall is that it only works on version 9.2.0.1 and up of their database, so if you're running an older version you'll have to use something else. But overall it's a pretty solid tool.&lt;br /&gt;&lt;br /&gt;Take a look at &lt;a href="http://www.oracle.com/technology/products/database/sql_developer/index.html"&gt;Oracle SQL Developer&lt;/a&gt; for yourself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-114294038513075247?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114294038513075247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114294038513075247'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/03/oracle-sql-developer.html' title='Oracle SQL Developer'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-114250138183951798</id><published>2006-03-16T09:25:00.000Z</published><updated>2006-11-21T23:17:53.186Z</updated><title type='text'>Some more books</title><content type='html'>Below is the my personal "ultimate reading list". All of them sit on my bookshelf either electronically or physically and are well worth the read.&lt;br /&gt;&lt;br /&gt;These books are mainly concerned with software development at a conceptual level. However, there are a few hardcore technical books in there too. Basically these books got me where I am today, hopefully you'll find them useful too.&lt;br /&gt;&lt;br /&gt;I'll add to this as I think of more, but this is a good start.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1590594614?ie=UTF8&amp;tag=shanebellsblo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1590594614"&gt;&lt;img border="0" src="http://images.amazon.com/images/P/1590594614.01._AA_SCMZZZZZZZ_V59224315_.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;o=1&amp;a=1590594614" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;a href="http://www.amazon.com/gp/product/1590596242?ie=UTF8&amp;tag=shanebellsblo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1590596242"&gt;&lt;img border="0" src="http://images.amazon.com/images/P/1590596242.01._AA_SCMZZZZZZZ_.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;o=1&amp;a=1590596242" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;path=ASIN/1590596234&amp;tag=shanebellsblo-20&amp;camp=1789&amp;creative=9325"&gt;&lt;img border="0" src="http://images.amazon.com/images/P/1590596234.01._AA_SCMZZZZZZZ_V55599791_.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;o=1&amp;a=1590596234" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;path=ASIN/1932394613&amp;tag=shanebellsblo-20&amp;camp=1789&amp;creative=9325"&gt;&lt;img border="0" src="http://images.amazon.com/images/P/1932394613.01._AA_SCMZZZZZZZ_V61467277_.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;o=1&amp;a=1932394613" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;path=ASIN/1590596161&amp;tag=shanebellsblo-20&amp;camp=1789&amp;creative=9325"&gt;&lt;img border="0" src="http://images.amazon.com/images/P/1590596161.01._AA_SCMZZZZZZZ_V54773546_.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;o=1&amp;a=1590596161" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;path=ASIN/097669400X&amp;tag=shanebellsblo-20&amp;camp=1789&amp;creative=9325"&gt;&lt;img border="0" src="http://images.amazon.com/images/P/097669400X.01._AA_SCMZZZZZZZ_.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;o=1&amp;a=097669400X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;path=ASIN/0974514055&amp;tag=shanebellsblo-20&amp;camp=1789&amp;creative=9325"&gt;&lt;img border="0" src="http://images.amazon.com/images/P/0974514055.01._AA_SCMZZZZZZZ_.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;o=1&amp;a=0974514055" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;path=ASIN/0131463055&amp;amp;tag=shanebellsblo-20&amp;camp=1789&amp;amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0131463055.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0131463055" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0321117425&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0321117425.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0321117425" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0596006624&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0596006624.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0596006624" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/020161622X&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/020161622X.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=020161622X" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0201485672&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0201485672.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0201485672" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0130449164&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0130449164.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0130449164" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0321193687&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0321193687.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0321193687" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0321267974&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0321267974.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0321267974" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0321127420&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0321127420.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0321127420" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/1590593898&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/1590593898.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=1590593898" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/1590595009&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/1590595009.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=1590595009" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0201633612&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0201633612.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0201633612" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0066620724&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0066620724.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0066620724" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0596006519&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0596006519.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0596006519" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0596001088&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0596001088.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0596001088" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0596006764&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0596006764.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0596006764" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/193239415X&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/193239415X.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=193239415X" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0596100949&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0596100949.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0596100949" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/1565924266&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/1565924266.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=1565924266" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0130313580&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0130313580.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0130313580" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0321278658&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0321278658.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0321278658" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0201835959&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0201835959.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0201835959" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0932633439&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0932633439.01._AA_SCMZZZZZZZ_.gif" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0932633439" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/1590596013&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/1590596013.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=1590596013" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0201310058&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0201310058.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0201310058" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/032133678X&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/032133678X.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=032133678X" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0735619670&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0735619670.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0735619670" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0471417114&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0471417114.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0471417114" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0131103628&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0131103628.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0131103628" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/013143635X&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/013143635X.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=013143635X" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0887308554&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0887308554.01._AA_SCMZZZZZZZ_.gif" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0887308554" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0029356717&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0029356717.01._AA_SCMZZZZZZZ_.gif" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0029356717" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0131422464&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0131422464.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0131422464" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0316778494&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0316778494.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0316778494" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0471117099&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0471117099.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0471117099" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0596007604&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0596007604.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0596007604" width="1" border="0" /&gt; &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;amp;path=ASIN/0596007833&amp;tag=shanebellsblo-20&amp;amp;camp=1789&amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/0596007833.01._AA_SCMZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: 0px; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;amp;a=0596007833" width="1" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;And here are a few links to some free online books...&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://ximbiot.com/cvs/manual/"&gt;Version Management with CVS&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://java.sun.com/docs/books/jls/"&gt;Java Language Specification&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.gigamonkeys.com/book/"&gt;Practical Common Lisp&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.fourmilab.ch/hackdiet/www/hackdiet.html"&gt;The Hacker's Diet&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://mindview.net/Books/DownloadSites"&gt;Bruce Eckel's Books&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/"&gt;Designing Enterprise Applications with the J2EE Platform&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://research.sun.com/techrep/1994/smli_tr-94-29.pdf"&gt;A Note on Distributed Computing (PDF)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://svnbook.red-bean.com/"&gt;Version Control with Subversion&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-114250138183951798?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114250138183951798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114250138183951798'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/03/some-more-books.html' title='Some more books'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-114191308606377237</id><published>2006-03-09T14:03:00.000Z</published><updated>2006-03-09T14:18:57.793Z</updated><title type='text'>Monkeys and Fire Hoses</title><content type='html'>A wise university lecturer once told me this story...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;If you take 3 hungry monkeys and put them in a cage with some bananas in the corner they will undoubtedly head straight for the bananas to eat them. However, if you stand outside the cage with a fire hose and spray all the monkeys each time any of them try to eat the bananas, they will eventually learn to stay away. &lt;/span&gt;&lt;span style="font-style: italic;"&gt;The key to this rather unfriendly experiment is that you must give all the monkeys a good hosing each time any of them try to eat the bananas.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Now and again one of the monkeys might decide to try his luck again with the bananas, but the other monkeys will beat him back, knowing that if he tries to eat the bananas they will get wet. Eventually the monkeys will learn the rules and stay away from the bananas. At this point you can get rid of the fire hose, the monkeys have learned their lesson.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Next, you replace one of the original monkeys with a new monkey who doesn't know the rules. He will head straight for the bananas in the corner, only to be beaten up by the 2 banana fearing monkeys. Remember, they don't want him to go near the bananas for fear of getting hosed.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Eventually the new monkey will learn the rules of the cage and wont go near the bananas, if he does the others will beat him up. In fact, he will even learn to join in on the beatings every time another monkey goes near the bananas. He's not sure why, but those are the rules of the cage.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Remember, this new monkey has never been sprayed with the fire hose, he has learned the rules from the other 2 monkeys.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;If you continue this process until all of the original monkeys have been replaced, you will end up with a cage full of monkeys all of which are too scared to go near the bananas in the corner. But none of them know why.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Too many people behave like this. They follow along in life never stopping to think and challenge the ideas presented to them. They do things because "that's they way they've always done them" or because "that's what everyone else is doing".&lt;br /&gt;&lt;br /&gt;Well, we just saw what happens when you do that... you miss out on the bananas.&lt;br /&gt;&lt;br /&gt;Think for yourself and question the norm once in a while.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-114191308606377237?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114191308606377237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114191308606377237'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/03/monkeys-and-fire-hoses_09.html' title='Monkeys and Fire Hoses'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-114181458576553600</id><published>2006-03-08T10:38:00.000Z</published><updated>2006-03-09T13:50:11.086Z</updated><title type='text'>Book of the Month</title><content type='html'>I thought it might be fun to post the details of books that I'm currently reading. A "book of the month" sort of thing.&lt;br /&gt;&lt;br /&gt;I tend to read more than one book at a time, especially thanks to my good friends over at &lt;a href="http://safari.oreilly.com"&gt;Safari Bookshelf&lt;/a&gt;. But I also read books in dead tree form to keep me entertained on the way to work.&lt;br /&gt;&lt;br /&gt;So here are two books I'm currently reading...&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Joshua Bloch, the guy who wrote &lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;path=ASIN/0201310058&amp;amp;tag=shanebellsblo-20&amp;camp=1789&amp;amp;creative=9325"&gt;the book that every Java developer should own&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=0201310058" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt; has a new book. Java Puzzlers is an excellent collection of quirks about the Java language. Arranged as a collection of puzzles that Josh has collected over the years, you are sure to learn a lot from this one.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;path=ASIN/032133678X&amp;amp;tag=shanebellsblo-20&amp;camp=1789&amp;amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/032133678X.01._AA_SCTZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=032133678X" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;If you're interested in starting your own software company, then this book will really get you thinking. &lt;a href="http://mymicroisv.com/"&gt;Bob Walsh&lt;/a&gt; has his own successful ISV and has some great ideas on how to get started. And the foreword is written by &lt;a href="http://www.joelonsoftware.com"&gt;someone&lt;/a&gt; with a pretty successful startup of his own.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/exec/obidos/redirect?link_code=as2&amp;path=ASIN/1590596013&amp;amp;tag=shanebellsblo-20&amp;camp=1789&amp;amp;creative=9325"&gt;&lt;img src="http://images.amazon.com/images/P/1590596013.01._AA_SCTZZZZZZZ_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=shanebellsblo-20&amp;l=as2&amp;amp;o=1&amp;a=1590596013" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-114181458576553600?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114181458576553600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114181458576553600'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/03/book-of-month.html' title='Book of the Month'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-114009336294647169</id><published>2006-03-07T15:14:00.000Z</published><updated>2006-03-07T15:13:09.693Z</updated><title type='text'>Attachment Check</title><content type='html'>How many times have you done this...&lt;br /&gt;&lt;br /&gt;1. Compose email&lt;br /&gt;2. Click 'Send'&lt;br /&gt;3. Swear profusely&lt;br /&gt;4. Add the attachment and resend it&lt;br /&gt;&lt;br /&gt;I never learn. I've accepted that I'm destined to do this for the rest of life. But never fear, I have the answer. Well, assuming you use Outlook at least.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://shanebell.f2s.com/downloads/AttachmentCheck.txt"&gt;This snippet&lt;/a&gt; of VBA code should do the trick nicely.&lt;br /&gt;&lt;br /&gt;I can't take credit for the code, thank &lt;a href="http://www.danevans.co.uk/vba/"&gt;Dan Evans&lt;/a&gt; for it. I just tweaked a few things and cleaned it up a little. Detailed instructions on how to install it into Outlook are posted on Dan's site.&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-114009336294647169?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114009336294647169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/114009336294647169'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/03/attachment-check.html' title='Attachment Check'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113870894345560015</id><published>2006-01-31T11:13:00.000Z</published><updated>2006-01-31T12:03:44.760Z</updated><title type='text'>Incremental Find in Eclipse</title><content type='html'>Those of you who use &lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox&lt;/a&gt; will be familar with it's fantastic incremental find feature. Just hit / and start typing your search term and Firefox will search for it as you type.&lt;br /&gt;&lt;br /&gt;It's one of those features that after a while you just can't live without. On the rare occasions that I'm forced to use IE, I'm always disappointed when I have to revert to the old Ctrl-f find.&lt;br /&gt;&lt;br /&gt;So you can imagine my joy when I discovered that &lt;a href="http://www.eclipse.org"&gt;Eclipse&lt;/a&gt; has this same feature. It's been there all along, I just never knew.&lt;br /&gt;&lt;br /&gt;While you're editing a file, just hit Ctrl-j to enter the incremental find mode (you should see "Incremental Find" in the status bar if all is well). Then just type the text you're looking for and Eclipse will jump to the first instance of that text. Ctrl-k will find the next match, and Esc will get you out of incremental find mode.&lt;br /&gt;&lt;br /&gt;Add that one to your bag of tricks and you'll save yourself 20 minutes a day :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113870894345560015?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113870894345560015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113870894345560015'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/01/incremental-find-in-eclipse.html' title='Incremental Find in Eclipse'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113699066592479673</id><published>2006-01-11T14:38:00.000Z</published><updated>2006-01-11T14:46:58.936Z</updated><title type='text'>RSS</title><content type='html'>The other day I made a passing comment about RSS to a group of colleagues only to be confronted with a series of blank looks saying "what's RSS?". I almost fell over!&lt;br /&gt;&lt;br /&gt;I was amazed that a group of technology professionals didn't know what RSS was. And even worse is that they're missing out on such a useful tool.&lt;br /&gt;&lt;br /&gt;For those who don't know (shame on you), &lt;a href="http://www.xml.com/pub/a/2002/12/18/dive-into-xml.html"&gt;RSS&lt;/a&gt; is basically a simple XML content feed that allows you to "subscribe" to information of interest to you. RSS, or it's cousin &lt;a href="http://help.blogger.com/bin/answer.py?answer=697"&gt;ATOM&lt;/a&gt;, is mostly used for news and blogs to save you the trouble of going to each of your favourite sites each day to see if there's anything new.&lt;br /&gt;&lt;br /&gt;For example, this blog has an ATOM feed &lt;a href="http://shanebell.blogspot.com/atom.xml"&gt;here&lt;/a&gt; that you can subscribe to. By using an RSS reader (there's loads of them out there) or a website that does the job for you like &lt;a href="http://www.bloglines.com/"&gt;Bloglines &lt;/a&gt;you'll be notified of anything new automatically. It saves you a ton of time and means you're always the first to know what's going on.&lt;br /&gt;&lt;br /&gt;I have a number of feeds that I read to keep me up to date on what's going on in the world of Java and technology in general. Here are a few of my favourites...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a aiotarget="false" aiotitle="The Server Side" href="http://www.theserverside.com/rss/theserverside-atom.xml"&gt;The Server Side&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a aiotarget="false" aiotitle="Signals vs Noise" href="http://feeds.feedburner.com/37signals/beMH"&gt;Signals vs Noise&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a aiotitle="Jonathan Schwartz" href="http://blogs.sun.com/roller/rss/jonathan"&gt;Jonathan Schwartz&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a aiotitle="James Gosling" href="http://blogs.sun.com/roller/rss/jag"&gt;James Gosling&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.joelonsoftware.com/rss.xml"&gt;Joel On Software&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oreillynet.com/pub/feed/7?format=rss2"&gt;OnJava.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://joegrossberg.com/paulgraham.rss"&gt;Paul Graham&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://feeds.feedburner.com/javaposse"&gt;The Java Posse&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://martinfowler.com/bliki/bliki.rss"&gt;Martin Fowler&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.pbs.org/cringely/pulpit/rss2.xml"&gt;I, Cringely&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://weblogs.java.net/blog/batate/index.rdf"&gt;Bruce Tate&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;My tool of choice for RSS feeds is &lt;a href="http://www.mozilla.com/thunderbird/"&gt;Mozilla Thunderbird&lt;/a&gt;. Mainly because I already use it for my personal email, but also because it works really well and gives you a great email-esque feel to your feeds which I think makes a lot of sense for most feeds.&lt;br /&gt;&lt;br /&gt;So don't be one of the uninformed, go and subscribe to some feeds and be one of the people who know what's going on in the world.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113699066592479673?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113699066592479673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113699066592479673'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/01/rss.html' title='RSS'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113596230524953017</id><published>2006-01-05T22:22:00.000Z</published><updated>2006-01-05T22:22:32.950Z</updated><title type='text'>Maven 2.0</title><content type='html'>When I first heard people talking about &lt;a href="http://maven.apache.org"&gt;Maven&lt;/a&gt; I thought to myself "Why do we need another build tool? Ant does a fine job thank you very much". But then curiosity got the better of me and I went and had a play with Maven anyway. But at that point in time the project was still in its infancy and the documentation was a little sparse. So after fumbling around for a while I decided that Maven demanded more time and effort to learn that I cared to spend and I gave up, convinced that I was better off with &lt;a href="http://ant.apache.org"&gt;Ant&lt;/a&gt; anway.&lt;br /&gt;&lt;br /&gt;But then a couple of months ago, Maven 2.0 was released and I decided it was time to give it another go. And I must say that things are a whole lot better now. However, I don't think I'll be saying goodbye to Ant just yet.&lt;br /&gt;&lt;br /&gt;The underlying concepts behind Maven are its strongest feature. Maven encourages you to do things in certain ways - to follow best practises. And by doing so it makes the world a better place for everyone. Most developers have a standard Ant script they carry around with them from project to project that does most of the things they need. When a new project starts, they dig it out, tweak a few things here and there and they're up and building. But the thing is, everyone's script does essentially the same thing. They all compile, test, package, deploy etc. It took Maven to realise this and decide that if everyone structured their projects in much the same way then we could do away with all this boilerplate and just start building. And that's exactly what it does. So long as you adhere to the Maven standards, it will happily build your project for you with very little config. It's "configuration by exception" which has become the norm these days with most tools, Hibernate and EJB 3.0 are two popular examples that come to mind.&lt;br /&gt;&lt;br /&gt;However, there's quite a difference between getting a simple example working and using Maven in a real project. It took quite a bit of effort to get a side project of mine up and running with Maven. It's a real shift of mindset moving from Ant to Maven. There were moments when the documentation let me down and I had to spend a little longer than I would have liked to figure things out, but in general things were pretty good. I'm pretty happy with my experience so far and will definitely continue to use it.&lt;br /&gt;&lt;br /&gt;The tool support for Maven 2.0 is moving pretty quickly. There are already &lt;a href="http://m2eclipse.codehaus.org/"&gt;plugins&lt;/a&gt; available, and development is &lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=38346"&gt;progressing rapidly&lt;/a&gt; on others.&lt;br /&gt;&lt;br /&gt;The one thing I do love about Maven is it's site building capabilities. Have you noticed that the home pages of all the Apache projects look remarkably similar these days? Well that's because most of them use Maven to build the site. It's simple and easy to use and produces a really slick looking site. In fact, even if you don't use Maven to build your project, it's worth using it just for the site building tools!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113596230524953017?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113596230524953017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113596230524953017'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2006/01/maven-20.html' title='Maven 2.0'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113581425668249169</id><published>2005-12-29T00:57:00.000Z</published><updated>2005-12-28T23:57:36.683Z</updated><title type='text'>Delicious</title><content type='html'>If you haven't already discovered &lt;a href="http://del.icio.us/"&gt;Delicious&lt;/a&gt; then you're missing out! I've been using it for a while now but have only recently reached the point where it's become a standard part of my day.&lt;br /&gt;&lt;br /&gt;Basically Delicious manages your bookmarks for you and allows you to tag your links so you can easily find them later. But it also links you to a whole community of bookmarkers allowing you to share your bookmarks with others and have them share theirs with you. For example, here's my list of &lt;a href="http://del.icio.us/shane_a_bell"&gt;bookmarks&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The UI is very slick and easy to use.  And there are &lt;a href="http://del.icio.us/help/firefox/extension"&gt;extensions&lt;/a&gt; and &lt;a href="http://del.icio.us/help/buttons"&gt;browser buttons&lt;/a&gt; that make managing your bookmarks a breeze.&lt;br /&gt;&lt;br /&gt;Go and check it out it's very cool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113581425668249169?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113581425668249169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113581425668249169'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/12/delicious_29.html' title='Delicious'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113581320468822143</id><published>2005-12-28T22:55:00.000Z</published><updated>2005-12-28T23:44:37.096Z</updated><title type='text'>JavaServer Faces</title><content type='html'>Over the last couple of weeks I've been busy writing a small &lt;a href="http://www.jcp.org/en/jsr/detail?id=168"&gt;portlet&lt;/a&gt; application for a client. As luck would have it, I had some spare time on my hands to try out some new technology so I decided to give &lt;a href="http://java.sun.com/j2ee/javaserverfaces/"&gt;JavaServer Faces&lt;/a&gt; a whirl. And so far I'm very impressed!&lt;br /&gt;&lt;br /&gt;JSF is Sun's attempt to include a web development framework into the Java EE spec to fill what until now has been a gaping hole. Until JSF came along, if you wanted to write a web application in Java the first step was choosing a framework. Fortunately there are plenty of options like &lt;a href="http://struts.apache.org/"&gt;Struts&lt;/a&gt; or &lt;a href="http://jakarta.apache.org/tapestry/"&gt;Tapestry&lt;/a&gt; that do the job very well. However, they aren't standard, and these days it seems like there's a new framework being released every week! So Sun decided it would be a good idea to fill the void and include a standardised web framework as part of the spec. The great thing about this is that it becomes part of the stack and each vendor can provide their own implementation of the API.&lt;br /&gt;&lt;br /&gt;So, what's so great about JSF I hear you ask. Well, for starters it's simple. Frameworks like Struts have a pretty steep learning curve with all those actions and forms and horribly complicated mapping files. But JSF keeps things pretty simple. Instead, you write backing beans that handle forms and listen for events. The JSF event driven programming model is simple and intuitive and eliminates much of the boilerplate code that other frameworks force you to deal with. And yes, you can test your beans with ease. Yay!&lt;br /&gt;&lt;br /&gt;The other great feature of JSF is the set of reusable UI components that it provides. Want a table that iterates through a collection of objects? No worries. Want a form with lots of great validation and event driven actions? No problem. And the best thing is that you get a wonderfully rich UI without having to write all the fiddly Javascript that goes with it. JSF generates all that for you (don't worry, you can still call custom Javascript if you like). So all this means that you can get on with your job of writing an application rather than fighting with stupid UI problems and dealing with the tedium of forms and validation.&lt;br /&gt;&lt;br /&gt;All in all, my little project went very well. The learning curve of JSF was small and the outcome was pretty good if I do say so myself. As I said at the start of this article, I used JSF to write a fairly simple portlet application for a client. JSF slotted in with the portlet framework nicely and didn't cause me too much grief at all. The process was essentially the same as writing a standard web application (and so it should be). I'll definitely be using JSF again for future web applications. In fact I'm already using it on another project.&lt;br /&gt;&lt;br /&gt;If you're looking for a book to get started on JSF I can recommend &lt;a href="http://www.horstmann.com/corejsf/"&gt;this one&lt;/a&gt;. I must admit that didn't sit down and read the whole thing cover to cover (mainly because I used &lt;a href="http://safari.oreilly.com/"&gt;Safari&lt;/a&gt; to read it), but I found it to be a great reference with plenty of examples and sample code to get you up and going quickly.&lt;br /&gt;&lt;br /&gt;So go and give JSF a try, I think you'll like it.&lt;br /&gt;&lt;br /&gt;Oh yeah, one more thing. Apache have an open source version of JSF called &lt;a href="http://myfaces.apache.org/"&gt;MyFaces &lt;/a&gt;that seems pretty rock solid to me. In fact, &lt;a href="http://www.jboss.com/"&gt;JBoss&lt;/a&gt; are bundling the MyFaces libraries with the latest version of their application server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113581320468822143?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113581320468822143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113581320468822143'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/12/javaserver-faces.html' title='JavaServer Faces'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113406617851202641</id><published>2005-12-08T18:05:00.000Z</published><updated>2005-12-08T18:24:23.823Z</updated><title type='text'>PMD</title><content type='html'>I've recently discovered &lt;a href="http://pmd.sourceforge.net/"&gt;PMD&lt;/a&gt;, an open source static code analysis tool for Java, and so far I'm very impressed! Basically, PMD trawls through your Java code looking for potential problems and violations of common best practises (like unused local variables, or an empty catch block) and reports on them. There's a great plugin for Eclipse (and most other popular IDEs) and from what I've seen so far, it seems like a pretty solid product.&lt;br /&gt;&lt;br /&gt;There is a huge number of rules that it can check for you, and it's easy to customise to your liking if there are particular rules you don't necessarily agree with.&lt;br /&gt;&lt;br /&gt;Well worth checking out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113406617851202641?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113406617851202641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113406617851202641'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/12/pmd.html' title='PMD'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113260871854245166</id><published>2005-11-28T18:28:00.000Z</published><updated>2005-11-28T18:26:38.776Z</updated><title type='text'>EJB 3.0 - Part 1</title><content type='html'>The sound of the letters E-J-B make many developers cringe. These three little letters bring back painful memories of home interfaces, deployment descriptors, java.rmi.RemoteException and of course, most painful or all... entity beans.&lt;br /&gt;&lt;br /&gt;But there's good news on the horizon. The final release of the EJB 3 spec is just around the corner and thankfully much of the pain is now a thing of the past. I'm not saying it's perfect, but it's a huge improvement over the current disaster of EJB 2.1. Ok, perhaps "disaster" is a little harsh, but I think you'd have a hard time finding a developer who likes to program EJBs in their current state.&lt;br /&gt;&lt;br /&gt;So what's new in the 3.0 release. Well a quite a lot actually. Here is a list of the more interesting changes...&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;&lt;span style="font-style: italic;"&gt;Everything's a POJO.&lt;/span&gt; At last, no more "extends EJBHome" or "implements SessionBean". The new spec allows any plain old java object to be enterprise beans. This is a welcome change for those of us who like to unit test our EJBs and don't like the messy test frameworks that the current spec forces us to use.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Annotations are the new deployment descriptor.&lt;/span&gt; One of the more controversial new features in Java 5.0 is annotations. Love them or hate them they're here to stay. And the new EJB spec has embraced them with open arms and made them an integral part of the framework. Now you can do away with those ugly xml deployment descriptors and use annotations instead. However, if you want to continue to use deployment descriptors then that's fine too. In fact, you can even use a combination of the two.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Configuration by exception.&lt;/span&gt; Another welcome change. No longer do you need to configure every last option of every piece of your application. Sensible defaults are available for most things and you need only define what you want to change.&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt; &lt;/span&gt;&lt;/li&gt;   &lt;li&gt;&lt;span style="font-style: italic;"&gt;Dependency Injection.&lt;/span&gt; EJB has jumped on the dependency injection bandwagon and now provides some basic injection functionality. You can have JNDI resources and other beans injected for you at runtime, saving you the trouble of looking them up or creating them yourself.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;No more home interface.&lt;/span&gt; I don't think anyone will miss them.&lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;span style="font-style: italic;"&gt;Simplified Persistence.&lt;/span&gt; Those nasty entity beans aren't so nasty anymore. For starters they can be POJOs now, and you can map them using simple annotations. Entity beans are much nicer in general really. But don't get too excited, Hibernate is still better.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;AOP support (sort of). &lt;/span&gt;With the introduction of interceptors, EJB now lets you do some very basic aspect oriented programming. It's not fantastic, but it works and it's better than not having it all. Basically you can specify that a method on an interceptor class be called whenever a business method is called on your EJB. However, it is somewhat restricive in the way it works. It would be useful for generic stuff like logging or audit information, but it would be a little clumsy for anything too complex.&lt;br /&gt;&lt;/li&gt;   &lt;li&gt;&lt;span style="font-style: italic;"&gt;Callbacks.&lt;/span&gt; You can now define methods on your EJBs that will be notified of lifecycle events. By simply annotating a method as a callback method it will be notified of various events (there are several, depending on the type of bean).&lt;br /&gt;&lt;/li&gt;   &lt;li&gt;&lt;span style="font-style: italic;"&gt;Fewer checked exceptions.&lt;/span&gt; The question of checked vs unchecked exceptions can quickly become a heated debate. But I think it's a great idea. It removes those unecessary try/catch blocks and throws clauses and makes code so much cleaner. There's not much you can do with a checked exception at that level anyway. But if you feel you need to catch them then you still can.&lt;br /&gt;&lt;/li&gt;   &lt;li&gt;&lt;span style="font-style: italic;"&gt;Interoperability.&lt;/span&gt; The good news is that your old EJBs have not been rendered useless. You can still use them in conjuction with the EJB 3.0 framework. So if you have old legacy EJBs that you just can't live without, never fear, you don't have to re-write them just yet.&lt;br /&gt;&lt;/li&gt;  &lt;/ul&gt;As you can see, there's lots of new stuff. Over the next few weeks I'll discuss all of these new features in all their gory detail. In the next article I'll discuss the changes that have been made to our good friend - the session bean.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113260871854245166?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113260871854245166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113260871854245166'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/11/ejb-30-part-1_28.html' title='EJB 3.0 - Part 1'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113260859950917849</id><published>2005-11-21T21:29:00.000Z</published><updated>2005-11-21T21:34:28.076Z</updated><title type='text'>EJB 3.0</title><content type='html'>EJB 3.0 has been gaining momentum recently. &lt;a href="http://www.jboss.com/"&gt;JBoss&lt;/a&gt; have a working &lt;a href="http://www.jboss.org/products/ejb3"&gt;EJB 3&lt;/a&gt; plugin for &lt;a href="http://www.jboss.com/products/jbossas"&gt;JBoss Application Server&lt;/a&gt; and recently published this &lt;a href="http://jboss.org/jbossBlog/blog/bburke/?permalink=EJB_3_0_in_production_User_testimonial.txt"&gt;customer testimonial&lt;/a&gt; about it working in a production environment. &lt;a href="http://www.oracle.com/technology/ejb3/index.html"&gt;Oracle&lt;/a&gt; have an early release available too.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.jcp.org/en/jsr/detail?id=220"&gt;spec&lt;/a&gt; hasn't been finalised just yet, but it's getting close and shouldn't be far away. So to prepare you for the release date, I'll be writing a series of articles on the new spec over the coming weeks explaining how the face of EJB has changed.&lt;br /&gt;&lt;br /&gt;Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113260859950917849?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113260859950917849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113260859950917849'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/11/ejb-30_21.html' title='EJB 3.0'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113240723809353475</id><published>2005-11-19T13:13:00.000Z</published><updated>2005-11-20T21:20:26.043Z</updated><title type='text'>You Get What You Pay For</title><content type='html'>Something I've been thinking about recently is the difference in the way most companies buy software, and the way they buy services.&lt;br /&gt;&lt;br /&gt;When it comes to buying software, most companies think about what it is they need and carefully compare the features of each potential product. Most will consider other factors such as the product's market share, support costs and the general reputation of the product. And then, once they've narrowed down the candidates, price is typically the deciding factor.&lt;br /&gt;&lt;br /&gt;In contrast, when a company makes a decision on who they employ to provide a services they typically consider one thing... price.&lt;br /&gt;&lt;br /&gt;It's not just companies that think this way, consumers make decisions like this every day. When looking for a new MP3 player or a TV, people shop around and compare features before deciding on the product that suits them best. And we'll happily pay a little more for a superior product. But when looking for an accountant or someone to build an extension on the house we tend to ignore all other factors and cut straight to the case... how much will it cost?&lt;br /&gt;&lt;br /&gt;Thinking this way is crazy! It assumes that all services are provided with the same level of quality and produce the same result in the end. And this couldn't be more wrong! Choose the cheapest accountant you can find and you could end up in jail for tax avoidance. Or choose the wrong builder and that new extension to the living room might not make it through the next storm.&lt;br /&gt;&lt;br /&gt;When companies recruit staff they interview all the candidates and and choose the most skilled and experienced candidate for the job. They don't just ask each candidate how much they want to be paid and then choose the cheapest. And yet when choosing a service provider this is exactly what they do. They ask a handful of providers to submit a proposal and then choose the cheapest option. And sadly this often ends up being a company in India who charge $80 a day for a developer.&lt;br /&gt;&lt;br /&gt;The problem with this approach is that not all service providers are created equal. Some provide an excellent service and produce quality results. Others take all your money and deliver very little. But as a service provider how do you make this clear to potential customers and differentiate yourself from the crowd.&lt;br /&gt;&lt;br /&gt;To be honest, I haven't quite figured that one out just yet. But when I do, I'll be sure to let you know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113240723809353475?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113240723809353475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113240723809353475'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/11/you-get-what-you-pay-for.html' title='You Get What You Pay For'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113188770180478262</id><published>2005-11-13T12:41:00.000Z</published><updated>2005-11-20T21:20:40.116Z</updated><title type='text'>Seam</title><content type='html'>&lt;a href="http://www.jboss.com"&gt;JBoss&lt;/a&gt; have some excellent technology available, and one of their latest offerings that is well worth a look is a framework called &lt;a href="http://www.jboss.com/products/seam"&gt;Seam&lt;/a&gt;. Gavin King (the guy behind Hibernate) has played an integral role in its conception and recently published this &lt;a href="http://blog.hibernate.org/cgi-bin/blosxom.cgi/2005/09/21#components"&gt;blog entry&lt;/a&gt; about it.&lt;br /&gt;&lt;br /&gt;Basically, Seam is an application framework that stitches together (hence the name) the pieces you need to build web applications. It is based around JSF and EJB 3.0, although you can also use Hibernate for persistence, or plug in the standalone EJB3 container from JBoss.&lt;br /&gt;&lt;br /&gt;It's well worth investigating if you're looking for a framework to build your next web application. The only problem you may face is the fact that it needs Java 5.0 to run, so you're a bit limited in your choice of application servers. And if you want to use EJB 3.0 then you're even more limited. But there's nothing proprietary in there that locks you into JBoss, the framework is based around standard Java EE technology.&lt;br /&gt;&lt;br /&gt;Just don't hold your breath waiting for the &lt;a href="http://www-306.ibm.com/software/info1/websphere/index.jsp?tab=products/appserv"&gt;big boys&lt;/a&gt; to release a Java 5.0, EJB3 compliant app server any time soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113188770180478262?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113188770180478262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113188770180478262'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/11/seam.html' title='Seam'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113138677529060900</id><published>2005-11-07T18:01:00.000Z</published><updated>2005-11-07T18:11:06.216Z</updated><title type='text'>Public Speaking 101</title><content type='html'>I've been to a few presentations over the last week and I'm still amazed at how bad some people are at it! Here are my top 10 tips for better presentations. Nothing groundbreaking, just common sense. It's not rocket surgery as they say.&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Be prepared. Those boy scouts are smart kids you know. Take some advice from them and prepare before your presentation. Make sure you have everything you need. Does the room have a projector? And does your laptop work with the projector? Do you have a backup of your slides? Do you have another backup of the backup? And is it in a format that someone else's laptop can read if Murphy turns up and your machine suddenly stops working? Do you have a hard copy so that if technology stops working that day at least you can hand out photocopies.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Tell us what you are there to talk about. Don't just launch into it, give some background first and if necessary, give a brief overview of the subject to get everyone up to speed. And provide some context as to how your subject fits into the real world.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Keep it simple. Try to explain things in a way that everyone will understand. Obviously this depends on your audience, the more technical they are, the more technical you can be. But try to consider the lowest common denominator and explain things in a way that everyone will understand.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Keep it short. Long presentations are boring. People lose interest very quickly, so try to keep your presentation to a sensible length. Again, this depends on the audience, but after 45 mins most people's minds will begin to wander and start thinking about what's on TV tonight.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Know your subject. Don't give a presentation on something you don't know a lot about. People are there to learn and they will expect that you know what you're on about. And if you don't, people will be able to tell very quickly. After the second question you answer with "Um, I'm not sure about that one", your audience will start leaving the room pretending they're late for a meeting.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Practise. No matter how experienced you are, practise your presentation a few times to get to know it. If all you do is read out each line of your PowerPoint presentation as you go your audience will very quickly lose patience with you and start throwing things.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Give people access to your presentation. Nobody likes frantically taking notes while trying to listen to what you have to say. Let people know that they can get a copy of your presentation when you are done so they can go back over it later at their leisure. That way they can focus on listening rather than trying to write everything down.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Summarise your presentation. When writing an essay there's a saying that says - "tell us what your about to tell us, then tell us, then tell us what you told us". The same thing applies to giving a speech. People have short memories and if you want to get your point across you need to make sure you reiterate it a few times so it sinks in.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Leave time for questions. People will want to ask questions and discuss your ideas. Make sure you give them time to do so. Running overtime indicates that you can't keep to time and that you don't really care about what your audience has to say.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Make it interesting. So many people give incredibly boring presentations that leaves the audience fighting to stay awake. Don't be one of those people. I've sat through too many boring presentations recently to face another one.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113138677529060900?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113138677529060900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113138677529060900'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/11/public-speaking-101.html' title='Public Speaking 101'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113031451446189048</id><published>2005-10-26T09:15:00.000+01:00</published><updated>2005-10-26T09:15:14.470+01:00</updated><title type='text'>The Java Posse</title><content type='html'>Just a quick one to tell you all about a great podcast that is well worth a listen.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://javaposse.com"&gt;Java Posse&lt;/a&gt; consists of &lt;a href="http://blogs.sun.com/roller/page/tor"&gt;Tor Norbye&lt;/a&gt; from Sun Microsystems, Carl Quinn from Google, and &lt;a href="http://www.voiceoftheresistance.com/"&gt;Dick Wall&lt;/a&gt; from NewEnergy Associates. All very knowledgeable guys in the Java world.&lt;br /&gt;&lt;br /&gt;The original Java podcast, The JavaCast, was very successful but lasted for only a few episodes. It died after a conflict of priorities between the founders Dick Wall and &lt;a href="http://www.brandonwerner.com"&gt;Brandon Werner&lt;/a&gt;. Fortunately Dick had the dedication to keep it alive so he joined forces with Tor and Carl and the Java Posse was born. &lt;br /&gt;&lt;br /&gt;Most episodes go for about 30 minutes (about a commute's worth of listening) and cover a wide range of topics relating to Java. They also interview prominent industry figures. Most recently they spoke with Joshua Bloch - author of Effective Java, and a major contributor to the JDK. They also have an interview lined up with &lt;a href="http://blogs.sun.com/jonathan"&gt;Jonathan Schwartz&lt;/a&gt; in the coming weeks!&lt;br /&gt;&lt;br /&gt;You can subscribe through iTunes or download the episodes direct from the website.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113031451446189048?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113031451446189048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113031451446189048'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/10/java-posse_26.html' title='The Java Posse'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-113026877410201319</id><published>2005-10-25T20:32:00.000+01:00</published><updated>2005-10-26T09:19:58.893+01:00</updated><title type='text'>Size matters</title><content type='html'>The old saying goes "it doesn't matter how big it is, it's how you use it that counts". In the software world, this couldn’t be more applicable.&lt;br /&gt;&lt;br /&gt;The big software companies like IBM and Microsoft have so many people hacking away at their products that they just can't seem to produce any decent software any more. Microsoft has been working on Longhorn, or &lt;a href="http://www.microsoft.com/windowsvista/default.mspx"&gt;Vista&lt;/a&gt; as it's now known, for years, and they're still a long way from delivering anything. Meanwhile, IBM products have become so complex and bloated, you need a super computer to run them on.&lt;br /&gt;&lt;br /&gt;I recently wasted an afternoon (and about 3GB of disk space) attempting to install IBM's &lt;a href="http://www-306.ibm.com/software/genservers/portal"&gt;WebSphere Portal&lt;/a&gt;. The install consists of countless CDs, and installs about 11 other products while it's at it. Why does it need to be so complicated? &lt;a href="http://www.jboss.org/products/jbossportal"&gt;JBoss Portal&lt;/a&gt; is a 9MB binary download that you install on top of &lt;a href="http://www.jboss.org/products/jbossas"&gt;JBoss Application Server&lt;/a&gt; (a mere 47 MB download) and can be installed and configured in under 15 minutes.&lt;br /&gt;&lt;br /&gt;Why? IBM is a huge software company with years of experience in writing software. JBoss is an open source product developed by a handful of developers. Sure, JBoss products can be a bit rough around the edges and don't come with all the bells and whistles, but they work! They just work! JBoss is probably the most configurable and scalable Java EE application server in the market today. And they're the only vendor who releases products in a timely manner. It will be years before we see EJB 3 in WebSphere.&lt;br /&gt;&lt;br /&gt;So why can't companies the size of IBM build better products? It's because they're so big. Size has a huge impact on productivity. With more people you have more meetings, and more disagreements, and more politics. If you can get a small team of highly skilled and motivated people together you can achieve amazing things.&lt;br /&gt;&lt;br /&gt;A fine example of this is a company called &lt;a href="http://www.37signals.com"&gt;37 Signals&lt;/a&gt;. They produce a number of online services including the very successful &lt;a href="http://www.basecamphq.com"&gt;BaseCamp&lt;/a&gt; and &lt;a href="http://www.backpackit.com"&gt;BackPack&lt;/a&gt;. At the time of writing this article, they employ a total of 7 people! But with those 7 people they build excellent products and often share &lt;a href="http://www.javaworld.com/javaworld/jw-10-2005/jw-1017-ajax.html"&gt;press&lt;/a&gt;  with the likes of Google for their innovative and amazingly simple applications. They're just a bunch of very intelligent and dedicated individuals who are passionate about building excellent products. And because they're small they can.&lt;br /&gt;&lt;br /&gt;Physics says that a body in motion tends to stay in motion, but the same is true for software companies. Big vendors are so big and bulky that it takes them forever to react to the demands of the market. Meanwhile the little guy can decide to change today and have a beta release out by next week. Why? Because they can make quick decisions and implement them without having to run the idea past legal, marketing, the architecture group, etc...&lt;br /&gt;&lt;br /&gt;Size matters. Stay lean and you can be quick on your feet and build software that works. You'll be able to make regular releases and fix bugs quickly. And most importantly, you can react quickly to the needs of your users and build a product that people actually want.&lt;br /&gt;&lt;br /&gt;So don't be worried if the software company next door is bigger than yours... it's what you do with it that counts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-113026877410201319?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113026877410201319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/113026877410201319'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/10/size-matters.html' title='Size matters'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-112896931602530837</id><published>2005-10-10T19:31:00.000+01:00</published><updated>2005-10-10T23:43:50.806+01:00</updated><title type='text'>Don't be lazy</title><content type='html'>If there's one thing that drives me mad, it's lazy developers. Unfortunately, most developers are lazy. I think one of the key attributes of an excellent developer is the fact they take the time to do things right instead of just hacking away at a problem until it seems to work.&lt;br /&gt;&lt;br /&gt;Sometimes it seems that you just don't have time to do it right. When the deadline is fast approaching and your boss is breathing down your neck it's tempting to just get the damn thing working and out the door. "I'll clean it up later" you say. Yeah right, as if that's gonna happen. The problem with writing sloppy code is that it never gets cleaned up. People just keep adding to the pile making it progressively worse as time goes by. And by the time someone finally decides to make the effort to clean things up, they realise it's probably quicker and easier to just start over.&lt;br /&gt;&lt;br /&gt;So what started off as a lazy bit of code has turned into a sloppy production application that is a nightmare to maintain and support. If only someone had taken the time to do it right the first time you wouldn't be in this mess. And here's the thing. Taking the time to do it right from the start is negligble. Taking the time to do it at the end is substantial.&lt;br /&gt;&lt;br /&gt;But how do you avoid this situation that we all too often find ourselves in? Here is a list of things you can do to improve the way you write applications and stop yourself from getting into the mess in the first place.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Write a spec&lt;/b&gt;&lt;br /&gt;Do you actually know what it is you're building? If you don't have a destination in mind, how do you know when you get there? Don't start coding without some kind of basic specification. It doesn't need to be long or fancy. It just needs to tell you what it is your building. Even if it's only a paragraph or two. If it clearly defines what you're setting out to do then that's fine.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Agree on the design&lt;/b&gt;&lt;br /&gt;Didn't we just go though this? No, a design is different from a spec. A spec says &lt;i&gt;what&lt;/i&gt; you're going to build. A design says &lt;i&gt;how&lt;/i&gt; you're going to build it. Again, it doesn't need to be a fancy document with UML diagrams all over the place. It just needs to provide a high level overview of how you're going to write your code. It can be a single diagram, or a page of text or even a working framework. Whatever it is, just make sure that everone understands it and adheres to it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Use Source control&lt;/b&gt;&lt;br /&gt;Do you have source control? If the answer is no, then stop everything immediately. You cannot build applications without source control. Period. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Write unit tests&lt;/b&gt;&lt;br /&gt;Write unit tests first. Why? Because it makes you think. And that's something that many developers neglect to do before they start writing. Not only will it force you to think, but you have the added benefit that once you've written your unit test, it's always there to test your code for you.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Use a build script&lt;/b&gt;&lt;br /&gt;You should be able to build and deploy your application in one step. And one step &lt;i&gt;doesn't&lt;/i&gt; mean following an 8 page document explaining the step by step process to follow. One step means clicking a button or executing a script. A good build process will check out the latest copy of your code from source control, compile everything from scratch, run all your unit tests, build a distributable file (eg: an .ear file) and deploy the application to the appropriate environment. Getting all this up and running can be tricky, but make the effort, it's worth it. Not only will it make your life easier but it will make you much more productive.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Don't be lazy&lt;/b&gt;&lt;br /&gt;This is the most important of all, don't be a lazy programmer. Take the time to do things right...&lt;br /&gt;&lt;br /&gt;Write comments. Code is only written once, but you come back to read it time and time again. And when you do, it's helpful if there's a comment or two to explain what's going on. You're not going to remember what a program does in 6 months time when a bug crops up, so save yourself the time and effort and write comments now.&lt;br /&gt;&lt;br /&gt;Don't hard code things that belong in properties files or in a database. It might be quicker for now, but what happens when that same program has to run in a development, test and production environment with different settings for each environment.&lt;br /&gt;&lt;br /&gt;Write code that people can read. Compilers will optimize your code for you. There's no need to try and and be clever, especially when it makes your code difficult to read. And take a bit of pride in what you write. Don't leave auto generated comments lying around all over the place that say things like &lt;code&gt;"To change this generated comment edit the template variable..."&lt;/code&gt;. And don't leave print statements all over the place saying &lt;code&gt;"##### Got to here - 17"&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Refactor when needed. If you find yourself calling a method over and over again, perhaps it belongs in a utility class or in a super class that you can extend. Take the time to fix it. Don't just keep on avoiding the problem, hoping it will go away. My rule of thumb is that if I find myself calling or writing the same section of code twice, I seriously consider refactoring it. 3 times, and I definitely refactor it.&lt;br /&gt;&lt;br /&gt;I could go on and on, but I think you get the idea. The most important aspect of all this is that it's not hard and it doesn't take much extra time or effort. In fact, you'll soon realise that it saves you time in the long run. But the benefits you'll gain from making these changes are huge. You'll be more productive, you'll be happier, and most importantly - you'll bulid a better end product.&lt;br /&gt;&lt;br /&gt;So next time you fire up the editor to start coding, take a few minutes to think about what you're doing and find the best way to go about it. Don't just start hacking away, do it right the first time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-112896931602530837?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/112896931602530837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/112896931602530837'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/10/dont-be-lazy.html' title='Don&apos;t be lazy'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-112870263126523202</id><published>2005-10-07T17:20:00.000+01:00</published><updated>2005-11-20T21:20:01.876Z</updated><title type='text'>Lorem ipsum dolor sit amet</title><content type='html'>I realised today at work that very few people have seen &lt;a href="http://en.wikipedia.org/wiki/Lorem_ipsum"&gt;Lorem Ipsum&lt;/a&gt; before so I figured I'd share it with you. &lt;br /&gt;&lt;br /&gt;"Lorem Ipsum" is a grouping of nonsense words used a lot by publishing and graphic design folk when presenting mock-ups of their designs. For example, if you're designing a new web site (as I was doing today) but the content for a particular page is not quite ready yet, then you can fill the blanks with something like this...&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The theory is that it resembles real text, but doesn't distract you with real words which you might be tempted to read when you're actually supposed to be looking at the design. In practise this often doesn't quite work. If someone hasn't seen Lorem Ipsum  used before then chances are they'll start reading the text trying to decipher some hidden meaning, thus completely distracting them from the design.&lt;br /&gt;&lt;br /&gt;Alas, it can still be useful. It's better than filling in blanks with some dribble like this...&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Text goes here...blah, blah, blah. Blah, blah, blah.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;There are some great &lt;a href="http://www.lipsum.com/"&gt;web pages&lt;/a&gt; that will generate pages of Lorem Ipsum text for you next time you need some.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-112870263126523202?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/112870263126523202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/112870263126523202'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/10/lorem-ipsum-dolor-sit-amet.html' title='Lorem ipsum dolor sit amet'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-11505453.post-112845425250728280</id><published>2005-10-04T20:22:00.000+01:00</published><updated>2005-10-04T20:30:52.506+01:00</updated><title type='text'>Random thoughts on random things...</title><content type='html'>I have decided to start putting down my ideas on this blog for a number of reasons.&lt;br /&gt;&lt;br /&gt;First, it's a good way to get me writing, something I want to improve and do more regularly. Also, it gives me a way to keep track of the random thoughts that float around my head from day to day. I read all kinds of weird and wonderful articles and books, so I figure if I write down my thoughts then I will digest them a little better.&lt;br /&gt;&lt;br /&gt;Ultimately, I want to start writing articles for industry publications and websites and hopefully one day write a book or two. But baby steps first.&lt;br /&gt;&lt;br /&gt;So what can you expect to read about here. Well, I'm a Java developer with ambitions to start my own business. So I'll be writing on anything that's even remotely related to that.&lt;br /&gt;&lt;br /&gt;Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11505453-112845425250728280?l=shanebell.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/112845425250728280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11505453/posts/default/112845425250728280'/><link rel='alternate' type='text/html' href='http://shanebell.blogspot.com/2005/10/random-thoughts-on-random-things.html' title='Random thoughts on random things...'/><author><name>Shane Bell</name><uri>http://www.blogger.com/profile/04268722286257779634</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://howe.textdrive.com/~shane_a_bell/blog/shane.jpg'/></author></entry></feed>
