Here is a list of things I do on every project these days and I highly recommend that you do the same. The result is that: (1) It is very easy for new developers to come up to speed on a project like this to quickly; (2) The installation process for the users of the project is very simple and simple will aid adoption of your product.
- Version Control: This should go without saying that you need to have some sort of version control system. Today the version control system of choice is Subversion. You will need a server to host the repository. For open source projects I use code.google.com and for commercial I use Hosted-Projects. Hosted-Projects are just few dollars per month and you get a piece of mind of backups. Don’t forget to check in everything you need into the repository, this includes all of the dependent libraries.
- Command Line Build Script: Most of my time I live in Eclipse and it does all of the compilation, unit-test running and code-coverage (EclEmma) for me. Nevertheless you need a command line script for building in the continuous build (usually an Ant Script). Your script should:
- Continuous Build: I have been on too many projects where the head of the repository does not compile resulting in endless loss of productivity. Always have a rule that whatever is in repository at least compiles (Tests pass is ideal). Use a continuous integration server such as CruiseControl or Hudson. I prefer Hudson because the setup is a no-brainer and it is very powerful and feature rich with lots of nice graphs for your upper-management (BTW Hudson follows the suggestions in here, which is one of the reasons it so great.). You want your continues build to publish the JARs, JavaDoc, Tests Report and Coverage Report which the build script generated. This way there never is doubt as to what is the state of the code-base. If your boss wants to try the latest code he can download it from the continues build.
- Automatic Push to Staging: Set up the continuous build so that if the build is successful (tests pass) automatically push the code to staging server. I usually set up a Tomcat server and simply update its WEB-INF directory with the latest code. Tomcat automatically notices new files and refreshes. This gives people an area where to play with the product. You can have your QA use the server or set up a separate one. I usually have a lot of automated tests so I give the URL directly to customer and tell them this is the “ALPHA” server. This is very useful when you are working on a feature, the customer gets to be part of the feature building and can give you input all along as opposed to on the end when it is hard to change anything.
- Tests and coverage: Even if you are new to automated tests and unit-testing, I still recommend that you do everything else on this list. But the automated tests bring the whole process to the next level. The benefits you get from automated testing are immense and people have written books on it, so we will not go into it here. If you are new to testing make a “Hello World” tests just so that you get all of the scripts and coverage working with it. This puts all of the infrastructure in place so that once your developers get into writing tests they will have a place to put them. It is very important to run the tests with the continuous build, otherwise your tests will bit-rot.
- Default Embedded Web Server: If you are building a web app I recommend Jetty as your web container. The cool thing about Jetty is that you can simply new-it-up in your main method. With Tomcat you have to package up a WAR file and drop the WAR file into the Tomcat directory and wait for Tomcat to “install it”. This makes development as well as deployment complicated. With Jetty you start your application through a main method (just like a normal desktop app) and your main method starts Jetty. Your developers have easier time developing/debugging and your customer has easier time deploying. I usually go a step further and make sure that the JAR file produced is also a WAR file. So if you insist and want to deploy with Tomcat you can. Make it easy for everyone!
- Default Embedded Database: Nothing puts me off from tyring an application than a complicated database installation instructions. As a result I use an embeddable database such as HSQLDB. In development and in tests I let the system instantiate an in-memory database, on staging I instantiate a disk-backed version. But in both cases there is nothing for the customer/developer to do; it is part of the main method! I provide a command line option to use external DB such as Oracle in heavy-production.
- Automatic Schema Installation: When the application starts the first thing it does is checks if the schema is installed. If not it automatically install the schema. I usually use Hibernate for persistence which does all of this for me. Hibernate even upgrades the schema to newer versions if needed so I never have to worry about the schema in the DB.
- GUICE Dependency Injection: If you want a maintainable, testable and easy to understand code-base, you need to use dependency injection (DI) as a design pattern. This should be a no-brainer, but sadly the industry needs to catch up, so be ahead of the industry. If you use DI, then you need an automated DI framework to make your life easier. I use GUICE and I think it is the most advanced DI out there, but there is also PicoContainer and Spring. If you will use DI it will pay huge dividends throughout the project lifetime, especially as the project matures and becomes more complicated.
- Easy Installation/Run: Focus on making it easy for the customer to try your product. I like to shock my customers by handing them a JAR file and say “double-click” which starts the JVM, the web-server, the DB, installs the schema, and launches a web-browser which points to the localhost. Or server your application through Java Web Start which does the same one-click process in a web-page. Make it so that there is no need for an installation manual.
- Place main class into the JAR MANIFAST so that double clicking will launch your application
- Place all of your JAR dependencies into the main JAR file. Use JarJar or One-Jar-Classloader.
- No argument launch should bring the application up in “reasonable state”: in-memory-database; install schema; launch web-container; install a default admin user; etc…
What is the end result? You will have happy and productive developers, and happy customers. Make it easy for your customers to switch to your product.