Category: Java


If the code is so simple, then it will be simple to test it.

And at some point, it’s likely the feature will be enhanced. If there is an existing test then it should be simple to enhance it. If there isn’t an existing test then things can quickly get messy.

The more complex the code, the harder it is to introduce tests.

This is the TDD approach: get something simple working, then enhance it in a simple way, and repeat until you have what you want. Lots of small, simple (and testable) steps.

OK, not all code needs a test. (Auto-generated accessors, simple wrapper methods, etc). But still, be mindful of the myth!

Firstly, domain classes and DAOs are two separate issues. With Hibernate, for example, you can use POJOs or maps, and you can have multiple DAOs or one generic one. So why do i prefer POJOs…

1. They are type safe

Your IDE will flag a problem as soon as you type it.

2. Code is more concise and readable

Readability is key. Developers read 10x more code more than they write.

// The POJO
Article article = new Article(1234);
article.setHeadline(“Cheryl Cole Arrested”);
smallImage = article.getImageOfWidth(250);
mainImage = article.getMainImage();

// The Map
Map<String, ? super Object> article = new HashMap<String, Object>();
article.put(ArticleKeys.ID, Integer.valueOf(1234));
article.put(ArticleKeys.HEADLINE, “Cheryl Cole Arrested”);
image = ArticleHelper.getImageOfWidth(article, 250);
mainImage = (Image) article.get(ArticleKeys.MAIN_IMAGE);

3. Code is more concise and readable in JSP

${myPojo.author.name}
${myPojo.pubDate}

<%@taglib prefix=”met” uri=”…” %>
${myMap['author']['name']}
${met:pubDate(myMap)}

<!– For draft articles there won’t be a published date so we want to fallback to modified date –>

4. They can encapsulate domain logic

This keeps code where it belongs. And stops it sprawling where it shouldn’t. Some basic examples

  • Validation rules, for example. JSR-303 provides annotations which can be used with Spring and Hibernate.
  • POJOs can have proper toString methods – useful for debugging and logging. In contrast, maps will splurge all their entries, in a random order, including the whole article body text. (BTW, that will probably kill your log files and potentially your app).

5. They abstract from the relational schema

Consider an article with images.

  • Maybe images are stored as separate rows in an IMAGES table
  • Maybe the images are stored in the article body text
  • Maybe images are stored in the ARTICLES table in a column of type “array”

6. They are easier to debug

It’s hard to find a specific Map entry in a debugger.

7. IDE support

Code completion. Find references. Refactorings. Javadoc tooltips.

8. POJOs are easier to profile

What’s eating up all you memory and killing your app? Using POJOs, a profiler will tell you how many Article objects there are, how many Category objects, etc.

Using maps, a profiler will tell you… guess what? You’ve got a lot of map entries. Not much help.

9. They are more expressive

Class models are more expressive than relational models. Classes can extend other classes. They can implement interfaces. Objects reference other objects. Java has annotations and javadoc. This all helps express the domain model. And the domain model is the heart of the application.

Database tables just have foreign keys.

10. They perform better

There are no lookups. You don’t need to worry about the number of entries, or the capacity, or the load factor, or the performance characteristics of your chosen implementation.

Also, consider that JDK maps don’t know about primary keys. This means…

  • Slow hashCode methods = poor performance with collections
  • Slow (and semantically incorrect) equals methods

11. They are the de facto standard

12. They have a versioning strategy

This applies to serialized data (e.g. caching to disk) and hot-swap code changes.

13. They can use primitives

Simple. Efficient.

Finally…

A few false arguments for using Maps…

  1. You end up with lots of domain classes. The same is true of maps, you still end up with a class per entity (for key constants and helper methods).
  2. POJOs result in more code. No, the code example above shows that even if the POJO itself is more verbose, the code using it (services, controllers and views) is more concise.
  3. Writing and testing POJOs is too much effort. Your IDE can generate the boilerplate code. There are libraries to auto-test accessors and Object methods.

So you want an executable jar. It’s got lots of dependent jars. What’s a geek to do?

There is the uberjar plugin for maven. But it doesn’t seem to be supported any more, it’s not in maven central, and some people report classloader issues (it works some classloader magic).

There is the Shade plugin for maven. But it unpacks (slowly) all jars into one, and has to resolve “overlapping” resources (e.g. “spring.handler” files).

But don’t despair! There is a third way! Jar files can be given a classpath via the manifest file and Maven can generate it for you…

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <classpathPrefix>lib/</classpathPrefix>
              <mainClass>foo.bar.Baz</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>

Maven can also copy dependencies to a suitable location…

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.2</version>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}/lib</outputDirectory>
            </configuration>
          </execution>

Then to run it just…

java -jar myapp.jar

To deploy it requires copying more than one file, but that’s not necessarily a bad thing. In fact, 8/10 jar files prefer it. Jar. File. Fact.

I recently got an Maven error something like ”Missing indirectly referenced artifact javax.transaction:jta:jar:1.0.1B:compile”. I fixed it by adding an extra repository in my pom.xml

</build>
<repositories>
<repository>
<!– For jta jar –>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<dependencies>
...

Javapolis 2007 Technology Highlights

Tech highlights from Javapolis 2007:

    • now supported by many vendors
    • slick demo of a Jackrabbit-based commercial product from day.com
    • JCR 2.0 is in the pipeline
  • Glassfish open source application server
    • is now the reference implementation of the Servlet API
    • v3 (currently in beta) is more modular. The demo had a fast startup time.
  • Resin (commercial servlet container) claims to serve static content faster than Apache
  • FindBugs will find a lot of potential Java bugs for you!
    • provides a combination of modern scripting features and tight Java integration. For example, Groovy classes can implement Java interfaces.
    • v1.5 offers signficant performance gains
  • JRuby on Rails = Rails + support for calling Java code
  • JavaRebel is a commercial product that enables auto-reloading of classes without restarting the server
Follow

Get every new post delivered to your Inbox.