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.
23 responses so far ↓
Misko,
Ok bro, this is an awesome start! I will start communicating with you through your blog. For the Guerrilla Marketing book however, we will need to break this down for simpletons!! You are simply too advanced as is this content. I will have my co-author work on this for me.
Great, quick job though. We’re on our way! By the way, for iPhone development, do you have a Mac by any chance?
Sincerely,
Shawn
Yes, I have a Mac it is #11 on the list.
Hey, I wonder if you could sell a “project kickstart” which has a default project layout and setup like you are talking about.
you dont have to do WAR in tomcat and it can be started with exe and that is faster then main method.
and i would put ipod on #12, it give you nothing, but its cool.
Nice setup.. I pretty much follow this to the T, except for using Spring instead of Guice (no annotation dependencies) and Derby instead of HSQLDB. It suprises me how many shops out there don’t do half of this stuff…
Interesting post, We’ll apply some of those we weren’t using… Thanks!
There are three things we do differently
1) Do not checking dependnecies into the repository, use maven to manage dependecies
2) Use maven as our build tool instead of ant. Maven performs all those substeps mentioned quite easily
9) Use our custom DI framework
The Disco Blog » Blog Archive » The weekly bag– July 18 // Jul 18, 2008 at 2:12 pm
[...] Top 10 Things I do on Every Project- #9 is using Google’s Guice! Oh wait, he works for Google. [...]
FYI, HSQLDB link is botched. Great article.
Blog bookmarks 07/19/2008 « My Diigo bookmarks // Jul 18, 2008 at 9:35 pm
[...] Miško Hevery [...]
With Grails you pretty much get all of this for free by typing “grails create-app your_app_name”.
Use Continuum for Continuous Integration ->
http://today.java.net/pub/a/today/2006/05/30/continuous-integration-with-continuum.html
Get integrated with SVN, Maven and generate automated mails on every build/release.
Use Maven instead of Ant
http://maven.apache.org/
Find the better way to integrate the maven with eclipse -> http://m2eclipse.codehaus.org/
Use TestNG for unit testing -> http://www.javaworld.com/javaworld/jw-04-2005/jw-0404-testng.html
And do the ST/IT with Spring -> http://www.infoq.com/articles/testing-in-spring
Consider Toplink instead of Hibernate-> http://www.oracle.com/technology/products/ias/toplink/index.html
Vere useful checklist! I do use Spring in my project. But I have never used automated tests for my web app. I have to experiment more on this testing area. anyway, nice article!
fgantt » Blog Archive » links for 2008-07-24 // Jul 23, 2008 at 5:38 pm
[...] Top 10 Things I do on Every Project | Miško Hevery (tags: java tips) [...]
I like the idea around providing a release with an embedded db and web server providing an executable web app, this is a good way of getting an easily accessible beta to your customers and business analysts
I’m a recent convert to maven too, especially with the great integration with eclipse it has
Mostly a green field list – especially the DB items.
ps
there is a new update site for the eclipse/maven plugin that was on codehaus.
http://m2eclipse.sonatype.org/update
Miško Hevery: Top 10 Things I do on Every Project | sourcecodr.com // Aug 26, 2008 at 11:30 am
[...] Here is a list of things [he] do[es] 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. Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages. [...]
Hey. Another great post.
Why do you like to include dependencies in subversion? I have been dithering back on forth over whether I should do this for personal projects. Currently I do not include them, but include instructions to install the dependencies prominently in the readme, which is visible bother before and after download.
I guess for the moment I only expect my project to be tried out by other developers, who will not be too put off by installing dependencies like this.
For users, I intend to create a stand-alone installer, which would include all dependencies. I suppose I ought to prioritise creating this, or else I am excluding some early adopters who might try my project out if they didn’t have to mess about instralling deps.
Does this match your thinking on this?
@Jonathan,
I find that I often have to set up workspace on different machines. Mine, staging, continuous build, production and so on. Having to always remember to get the dependencies from some websites is a pain. Not to mention that when the version changes everyone has to go grab a new one. I find it much simpler if you simply check the dependencies in. Than there is nothing to worry about. All of the machines will simply update themselves.
Setup a CI a daunting task at first « Vein’s Weblog // Sep 21, 2008 at 7:15 pm
[...] 10 things to do on every project [...]
Misko,
Is this list still current or have their been any significant developments in the last three years that would change (e.g. SubVersion -> GIT).
Misko, very nice and informative list,
I normally create java jars and replace them in tomcat and have qa to test. Then proceed with build
Leave a Comment