Development Team Best Practices


I wanted to put together some thoughts on high level best practices for your dev shop.  These practices will skew towards larger dev shops inside of big corporations but can also be applied to 1-2 man teams.  These thoughts are inspired by a combination of The Pragmatic Programmer and The Joel Test.  I read both of these sources early in my career and they have continuously provided inspiration on what kinds of practices highly effective dev team should follow.  Futhermore I’ve found it surprising how many shops I’ve worked with that break these practices.  Following these practices will increase your dev team’s effectiveness, making for happy developers and manager.  Breaking these practices will result in a slower development velocity and frustrated developers and managers.

  • Streamline your local build process.  

Do you think your build process is pretty fast?  It could be faster.  If it takes more than a few seconds to redeploy your code you lose your train of thought – and there is a cost to putting that train back on the rails.  As someone who has spent a lot of time doing Enterprise Java development, it often amazes me what developers will put up with in their build processes.   Here are a couple of tips to decrease build time:

    • Your environment probably supports some sort of hot swap method where you don’t need to do a full build after every change.  Java’s JVM Hot Swap feature allows this for some cases.  I’ve also heard very good things about JRebel.
    • If you have a medium to large sized application, you probably don’t need to rebuild the whole thing all of the time.  Make sure you’re not rebuilding more components than necessary.  Here are some kinds of things I’ve seen automatically included in a full build that could be excluded from a “fast” version of your build: code generated from wsdl/xsd, database migrations, unit test suite execution, minification/obsfucation of js/css.  In Java, the war/ear step will package all of your files into a war/ear.  When you deploy that war/ear to your application server it will unpackage all of the files.  You can eliminate a step by just copying your war/ear directory directly into your application server.
  • Use a debugger.  

Do you test your application by inserting new log statements and redeploying?  Stop it!  One of the best ways to cut down on redeploy time is to not have to redeploy.  Every single commercially used language supports debugging.  Here are a few links to get you started using a debugger with your language

  • Automate your QA builds and minimize QA downtime

Your QA build process should be quick and painless.  I would shoot for a combination of automated QA builds (2 or more times per day) and one-click, on-demand deployments.  The outage to a QA environment needs to be small – 5 minutes or less – to keep the deployments painless enough to not disrupt the workflow of the QA staff.

Doing frequent, automatic QA builds does a couple of great things for your IT organization- it sets a precedent that your team has the ability to quickly turn around fixes.  It also minimizes the impact of bugs in your QA process;  After all, if your team finds a bug, it’s not a huge deal since the bug might be resolved in a few hours.

Contrast this approach with an organization I recently worked with that only did two QA builds per week because their build process took so painfully long to complete.  Every bug became a news headline.  The management team would often choose not to fix bugs because of the huge turnaround time and the risk of additional lost time in case a bug fix was not successful.

  • Treat database schema updates like source control

 SQL is code, and your database structure is the product of that code.  In the same way that every developer working on a project needs to be able to run the software on their local system, those developers also need to be able to run their own copies of the database.  Database changes should be part of your normal build process, and like your code, your database schema needs a version so you know which changes have been applied.  This helps keep your development, test, and production environments all in a sane state.

It’s easy to fall into the trap where a database is very difficult to create so you end up running one development database for all of your developers to share.  The problem comes when you need to support multiple work streams at the same time – this means you need to simultaneously run multiple versions of the schema at the same time.  You can work around this problem by adding more schemas and more hardware, but the overhead involved may make it really difficult for developers to do the kind of risk taking and rapid iteration required to reach a high velocity.

I recommend using flyway or liquibase to manage database changes for most technology stacks.  Rails has built in support with Active Record Migrations.

 That’s all for now.  Please send feedback in the comments if this post has helped provide value for your team, or even if it seems too rudimentary.  I’d be happy to do a deeper dive on any one of these topics if there is interest.

Full Text Search for the enterprise with Oracle Text

You work in software and your stack includes an Oracle database.  One day the business approaches you and says ‘I want a search page for our product/order/customer data.  Make it work like Google’.  You think to yourself, “If I could make a search page work like Google I would work at Google”!!!  Fear not, developer.  This problem has been solved many times in the past.  In this blog post I’m going to show you how to approach this problem, and show you a shortcut in case your environment’s stack includes an Oracle database.

Approaching Full Text Search

The problem you’re solving has a name and that name is Full Text Search.  The problem is that your Relational database, while presumably well normalized, is not good at searching for single words across huge data sets.  You need a different kind of database which is optimized for full text search.  A Search database will physically store the data differently so that it can quickly look up your search terms and return some metadata associated with those terms.  In your RDMBS, records are identified by keys.  In your Search index, they keys are the search terms.

There are several well known full text search solutions.  The bare minimum list you should probably know about is Solr/LuceneSphinx, and ElasticSearch.  These are all great full text search solutions, but they all require a lot of overhead to operate.  New servers, new software to install, new syntaxes to learn, admin consoles, and new interfaces or libraries to build into your front end application.

Oracle Stack Solution: Oracle Text

One drawback of each of the aforementioned search solutions is that you will likely want to run it on a dedicated machine (or VM).  If you work in an Oracle shop it likely means that you work in an enterprise where provisioning hardware (even virtual hardware) can be annoyingly difficult and time-consuming process.   I this environment, Oracle Text jumps out as a really nice solution.  Oracle Text is a full text search solution that is built in to all modern version of Oracle’s database.  This means that you don’t have to request a new machine, and request for new software to be installed on that machine in each of your QA and Production environments (or request for root access to do it yourself).  With Oracle Text you just run some DDL to create the index and start using it!*  The only hardware issue you should consider is the amount of disk in use on your Oracle database.

Here’s a simple example of how to take advantage of an Oracle Text search index.  Let’s assume that I have a database with products and reviews (a product has many reviews) and I want to be able to return search results for both at once.

The most straight-forward way to start is to gather all of the data you want to index into a single VARCHAR2 column named SEARCH_TEXT on our PRODUCT table.  If you need to index more than 4000 characters, use a CLOB.

alter table PRODUCTS add SEARCH_TEXT varchar2(4000);

Now we need to populate that column with the search data we want to index from the PRODUCTS and REVIEWS tables  We are going to fetch the data into the search text column as a big space delimited string.  The below query is called a correlated update, and is specific to Oracle.   You can accomplish the same thing with a procedure but I find this more concise.

 select ||' '|| P.description ||' '||R.title ||' '||R.review_text
 where P.ID = R.PRODUCT_ID
 ) where = P.ID;

Next we create Oracle Text index on that column.  The important part is the ctxsys.context at the end of this statement.  Context is one of the three types of text indexes that oracle offers, but the best one for blocks of structured text.

 indextype is ctxsys.context;

It is worth noting that you can configure the index to use a separate tablespace so that you can control where on the disk your index lives.  See the docs for more info.

Next we we run a command to ‘sync‘ the index.  This actually indexes the data for the first time.  Run it again after you’ve inserted or updated data to update the index.  In fact, you should  plan on running this command periodically as part of a dbms_scheduler or whatever your enterprise’s favorite scheduler is.


Now we can run a full text search query and see some results.  A statement like this will return all product records which have the word ‘paper’ in the title, description, or reviews. yay!  It’s pretty awesome that we can run searches on this index in our existing RDBMS and apply whatever filters, sorts, and joins we want without having to call out to another system.

select * from PRODUCTS where contains(SEARCH_TEXT, 'paper') > 0;

Finally, we create a job to periodically ‘optimize‘ the index.  According to the docs your index gets fragmented and slower over time and this will fix it up.  I’ve had luck with running this nightly but YMMV.

ctx_ddl.optimize_index(PRODUCT_REVIEW_SEARCH_IDX, 'FULL');

After you’ve got your index up and running you can get some useful info and stats out of it with the CTX_REPORTS package.  Among other things it will tell you how fragmented your index is, and what words are the most frequently indexed.

I’ve really just scratched the surface to show you how to get a text index up and running fast.  Oracle has a ton of options to tune the index, and search features like fuzzy searching, stemming, and wildcards.

*Ok, maybe you should still consult a DBA first if you have access to one.



Reducing JBoss’s Memory Footprint

I am working on a project to convert a handful of J2EE applications from an Oracle OC4J application (no longer supported) server to JBoss 5.1.0.  Among the many challenges in the conversion is the fact that JBoss’s default profile has a significantly larger memory footprint than OC4J.  In the past I have just accepted that Jboss uses over 400MB of heap space before you even deploy anything. This time however we were hoping to reuse the same hardware from the old application server with the new application server.  When the test system started paging and eventually using up all of the physical memory available, we were forced to choose between ordering more memory and trying to tune jboss to reduce the memory footprint.

We ended up having a lot of success reducing the footprint through tuning.  Bottom line: we reduced the memory footprint by 120MB, and the startup time from 53s to 24s

Here were the steps taken

Heap Size (MB) Used (MB) Reduction in Used (MB)
Starting Heap 419 314
commented out debug level MBeans annotation in deployers.xml 322 247 67
removed ejb3 services 317 238 9
removed messaging folder & props 310 238 0
removed seam & admin-console 256 205 33
Removed xnio-deployer and xnio-provider 256 203 2
removed ROOT.war 256 203 0
removed management 256 199 4
removed jbossws.sar 256 193 6


The instructions for each step can be found :

Notes on my environment and testing process:

  • Windows XP, JDK 1.6.0_22,
  • JBoss 5.1.0.GA.  Xmx=512M , Xmx=256 (this is why heap didn’t drop below 256)
  • I used jvisualvm to watch the heap and “used” memory values
  • For the “Used” memory, I took the maximum observed value while JBoss was starting.  If you understand that a time vs. memory usage graph follows a sawtooth pattern as objects are instantiated and garbage collected, then I took the value from the tip of the highest tooth.

No Fluff Just Stuff 2011, Madison, WI

I attended the No Fluff Just Stuff conference in Madison, WI this weekend. It was a great chance to learn the newest Java trends and share struggles in programming with people much like myself, even if most of them were cheeseheads. Here are some of my reflections on the state of Java tech post-conference:

-Java 7 is underwhelming, mostly because it will not have closures. It will however introduce enhancements to speed up Groovy, JRuby, and Scala

-If I read between the lines what features are in HTML and any of them are supported by Chrome, then I think that HTML5+Chrome could easily turn into a gaming platform!

-There is no question that Groovy is the “next big thing” for Java. Get on board.

-A java developer could easily add Hadoop to his resume (and dollars to his pocket), by learning Hadoop with Cascading. Hadoop-worthy scale data sets are available for free from amazon:

Grails is really cool. I wish there was a hosting platform available that was anything close to Heroku for Rails. I think it is unlikely that we will hear any good Startup stories with Grails for that reason.

Setting the Default Version of Java in Windows

You’re a java programmer on a Windows development environment.  You fire up the command prompt and run “java -version”.  It’s some JRE and its not even the version you want!  Eclipse is throwing a fit.  There’s no good way to figure out what path the “java.exe” you are executing lives in.

The most surefire way to solve this problem is take the java bin path (ex: C:\program files\Java\jdk1.6.0_07\bin)  you want and prepend it to your System level PATH environment variable, as highlighted below.  This will ensure that you are executing the java.exe from the expected java installation every time.

JPA Annotation Cheatsheet

Whenever I need need help configuring JPA annotations I turn to google, and I always find it difficult to find a good cheatsheet.

Well here is my favorite JPA annotation cheatsheet.  Even though it says Oracle and Toplink it applies to any Spring/JPA/Hibernate technology stack:

Oh yeah, and here’s my tip on using cascades: Never use CascadeType.ALL!  Use MERGE, PERSIST, and maybe REMOVE if you want to cascade your deletes.  CascadeType.ALL will result in poor performance and unintended consequences.

Configuring Jetty, Maven, and Eclipse together with Hot Swap

For over a year I’ve been developing a Java webapp in Hibernate with maven and Jetty.  Recently I’ve figure out how to make them all play nice with each other.  For too long I had to restart my application server, which takes upwards of 45 seconds, for any code changes to make it to my development server.  This tutorial will show you how to setup Jetty in embedded mode, and using Eclipse, attach a debugger to enable True Hot Swap of code onto your Jetty server.

Environment Information:

JDK 1.5+
Eclipse 3.4.0
maven 2.0.10
m2eclipse 0.9.7 (maven plugin for eclipse)
Jetty 6.1.10

Continue reading “Configuring Jetty, Maven, and Eclipse together with Hot Swap”

Java Project Versioning with perforce plus ant

I recently developed a useful ANT task to automatically increment a version number on your Java project when using perforce as your source control application. This task is intended to be run as part of an automated build (via cruisecontrol). It checks out and checks it back in after incrementing.

  1. The task will look for the following files in the same directory as your build.xml. You should be able to figure out what parameters belong in each file by looking at the task. files:,,
  2. In the lines where I print the full version number I have broken it up into two lines for display purposes. In practice you will want to keep it on one line.

  p4.path is ${p4.path}
  Creating Label: ${new.version.major}.${new.version.minor}. ${new.version.iteration}.${}"