Best practice for modifying code during ant build

Say this doesn't sound like best practice, but let me explain. During assembly, we need to insert the assembly number and version of the system into a class whose sole purpose is to contain these values ​​and make them available.

Our first idea was to use the properties of the system, but due to the volatility of the deployment environment (another way of saying that system administrators do strange, wicked, creepy things), we would like them to be hard-coded.

In fact, I see 4 possibilities to achieve this in ant:

  • use <replace> in the token in the class

    The problem with this approach is that the file was modified, so you need to replace the token after compilation with <replaceregexp> ... sooo ugly, I don't want to touch the source code with a regular expression. Plus time dependencies.

  • copy the file, replace it with a copy, copy the copy, delete the copy

    One must remember the sequence - the original class must be compiled first in order to be overwritten by the copy. Temporal dependencies are also ugly.

  • copy the file, replace the token on the original, compile, replace the shaded original with a copy

    The same time dependency problem if it is not included in the compilation target. Which is also ugly because all of our build files use the same imported compilation target.

  • create the file from scratch in the assembly script / save the file outside the source path

    It is an improvement over the first three because there are no time dependencies, but the compiler / IDE is very unhappy because it does not pay attention to the class. Red markers are terribly ugly.

What do you think of the alternatives?

Are there any recommendations for this?

I hope I skipped a perfectly reasonable approach.

thanks

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

+6
source share
6 answers

I think a simpler approach would be for your Version.java class Version.java read from a simple .properties file included in the JAR and just generate that .properties file during assembly in the Ant build. For example, just generate:

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

in does half of this (see second example).

+10
source

# 2, as a rule, I saw this, except that your sources, not ready for compilation, should be in a separate place from your sources ready for compilation. This avoids the temporary problems you are talking about, as they should only be compiled once.

This is a common template that is constantly displayed in software assembly processes.

Sample: Create a source from some resource and then compile it.

This applies to many things from pre-compilation filtering sources to creating interface stubs for RMI, CORBA, web services, etc.

Copy the source to the designated location of the generated sources and replace the marker in the copy files to generate the sources, and then compile the generated sources into the assigned classes.

The compilation order will depend on whether your other sources depend on the generated sources.

+2
source

My solution would be:

  • use in token in class:

     <replace dir="${source.dir}" includes="**/BuildInfo.*" summary="yes"> <replacefilter token="{{BUILD}}" value="${build}" /> <replacefilter token="{{BUILDDATE}}" value="${builddate}" /> </replace> 

This replacement should only be done in the build steps performed by your build system, never within the compilation / debugging session inside the IDE.

Customizing the build system should not transfer the changed source code back to the source repository, so the problem with the modified code does not exist with this approach.

In my experience, this does not help when you put assembly information in a property file, since administrators tend to keep property files on upgrade β€” replacing the property file that exited the installation. (The assembly information in the properties file is informational for us. It makes it possible to check during startup if the properties file is synchronized with the version of the code.)

+1
source

I remember that we used the fourth approach a little differently. You can pass the release number to the ant script when creating the release.Ant script should include what is in the release (configuration / properties file) and your class should read it, maybe use a properties file or a configuration file.

0
source

I always recommend creating some kind of directory and putting all the embedded code there. Do not touch the directories you checked. Usually I create the target directory and place all files modified and created there.

If there are not many * .java files (or * .cpp files), copy them to target/source' and compile there. You can use the target/source' and compile there. You can use the task with a `to change this file to one file with the build number when copying it.

 <javac srcdir="${target.dir}/source" destdir="${target.dir}/classes" [yadda, yadda, yadda] </java> 

Thus, you do not make changes to the written source directory, so no one will accidentally check for changes. Alternatively, you can do a clean by simply deleting the target directory.

If there are thousands, if not millions *.java files, you can copy the templates to target/source , and then compile the source code in both {$basedir}/source and target/source . Thus, you still do not discard the extracted code and leave a chance that someone accidentally checks the modified version. And you can still do clean just by deleting target .

0
source

I was looking for a solution to the same problem by reading this link: http://ant.apache.org/manual/Tasks/propertyfile.html I was able to find a solution.

I work with netbeans, so I just need to add this piece of code to my build.xml file

 <target name="-post-init"> <property name="header" value="##Generated file - do not modify!"/> <propertyfile file="${src.dir}/version.prop" comment="${header}"> <entry key="product.build.major" type="int" value="1" /> <entry key="product.build.minor" type="int" default="0" operation="+" /> <entry key="product.build.date" type="date" value="now" /> </propertyfile> </target> 

This will increase the minor version every time you compile the project with clean and build. Thus, you save to run the project at any time, while the minor version remains in place.

And I just need to read the file in Runtime. I hope this help.

0
source

Source: https://habr.com/ru/post/887950/


All Articles