kostja kostja - 4 months ago 7
Java Question

Best practice for code modification during ant build

Admitted, this doesn't sound like a best practice altogether, but let me explain. During the build, we need to paste the build number and the system version into a class whose sole purpose is to contain these values and make them accessible.

Our first idea was to use system properties, but due to the volatility of the deployment environment (an other way of saying "the sysadmins are doing weird unholy creepy things") we would like to have them hard-coded.

Essentially I see 4 possibilities to achieve it in ant :


  1. use
    <replace>
    on a token in the class


    The problem with this approach is that the file is changed, so you have to replace the token back after compilation with a
    <replaceregexp>
    ...sooo ugly, I don't want to touch source code with regex. Plus temporal dependencies.

  2. copy the file, make replace on the copy, compile copy, delete copy

    One one has to mind the sequence - the original class has to be compiled first in order to be overwritten by the copy. Temporal dependencies are ugly too.

  3. copy the file, replace the token on the original, compile, replace the stained original with the copy

    Same temporal dependency issue unless embedded in the compile target. Which is ugly too, because all our build files use the same imported compile target.

  4. create the file from scratch in the build script / store the file outside the source path

    Is an improvement over the first three as there are no temporal dependencies, but the compiler/IDE is very unhappy as it is oblivious of the class. The red markers are disturbingly ugly.



What are your thoughts on the alternatives?

Are there any best practices for this?

I sure hope I have missed a perfectly sane approach.

Thank you

EDIT
We ended up using the manifest to store the build number and system version in the
Implementation-Version
attribute, unsing
MyClass.class.getPackage().getImplementationVersion()
. I have found this solution was one of the answers to this thread, which was posted in the comment by andersoj

Answer

I think a simpler approach would be to have your Version.java class read from a simple .properties file included in the JAR, and just generate this .properties file at build-time in the Ant build. For example just generate:

build.number = 142
build.timestamp = 5/12/2011 12:31

The built-in <buildnumber> task in Ant does half of this already (see the second example).