开发者

java ant build several editions of software

Suppose I have a piece of software which I market as two editions.

How would I build both editions using Ant?

I mean, inside the code, as far I can see, I'd check for example:

if(Editions.PRO)
{
    // 'P开发者_开发知识库ro' edition code
}
else
{
    // 'Normal' edition code
}

and since Editions.PRO is "static final boolean" only one part of the above code will be compiled.

I could also use different source files but that sounds painful to maintain.

I could also use interfaces, but thats...... nm.

So, the "conditinoal compilation" (above) method seems best to me.

How would I implement that on Ant?

Can Ant manipulate the value of "Editions.PRO" in its file?

That actually doesn't sound very good to me.

Instead, I was thinking about replacing files (using Ant commands), or even better, exclude the (real, dev) file that defines "Editions.PRO" and add as a class-path another folder that has the same file but with "Editions.PRO" configured accordingly (to the desired edition).... I hope I'm clear.

How do/would you do that?


First, find a way to restructure your code, where there are "PRO Edition" classes and "Demo Edition" classes that both share a common interface, and the rest of the code then calls the variable functionality through the interfaces.

Then create two ant targets, a "pro" target and a "demo" target. Each target then excludes the compilation or packaging (depending on where you want to make the differentiation) of the non-edition specific implementations of the abstract interfaces.

This way you only get pro implementations with a pro product, demo implementations with a demo product, etc.

Attempting to embed the functionality in if statements is taking the wrong path. If you do that, for the code to compile, you need both pro and demo code at the same time to build either a pro or demo product. In addition, you (likely) need to ship both sets of code with the demo product. This leaves open the possibility of a person defeating your pro/demo selection mechanism and activating the pro version code in a demo product.


There is no conditional compilation in Java. What you've described is conditional execution. All of the code is compiled and available to the user. If your goal is to keep the user from being able to execute one code path and not the other, this will work at a basic level. It's very easily defeated if your intention is to control features through some sort of licensing scheme, though.

If you really want to keep some features from the user, you need to refactor the code into two different front ends to some common back end code. Then use Ant's exclusion properties in the FileSet of your javac task to exclude the appropriate front end for the edition you're building. You can have a separate target for each edition.


Replacing tokens in Java code is working for me. I use something like this, prior to the compile task:

<copy todir="${target.dir}/java" filtering="false">
    <fileset dir="${src.dir}/java"/>
</copy>
<replace dir="${target.dir}/java" value="DEMO_MODE = ${demo.mode}">
  <replacetoken>DEMO_MODE = true</replacetoken>
</replace>

First I copy Java files into a temporary location, then I replace tokens. Javac these copied files. ${demo.mode} can be given as a parameter even in command line or property file. DEMO_MODE is a public static final boolean variable in a class.

Two more things which can be useful for you:

You can set up conditinal property assignments in targets:

<condition property="distribution.postfix" value="-demo" else="">
<equals arg1="${demo.mode}" arg2="true" />
</condition>

And you can use if and unless conditions for targets:

<target name="demotarget" depends="jar" if="demo.mode">
       ...
</target>

Actually, I would prefer modularization and different targets for PRO and DEMO releases, maybe switchable functions, but we use this tricks for something else, particularly Development vs. Production releases: Development code contains more debug logging which we don't want to be visible in production software with a logLevel=DEBUG config. Furthermore, production code obfuscated, development isn't, thus the latter throws readable stack traces for example.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜