{"id":9,"date":"2008-02-28T18:18:18","date_gmt":"2008-02-28T23:18:18","guid":{"rendered":"http:\/\/www.naturalobjects.co.uk\/blog\/2008\/02\/28\/conditional-compilation-in-java-almost\/"},"modified":"2008-02-28T18:18:18","modified_gmt":"2008-02-28T23:18:18","slug":"conditional-compilation-in-java-almost","status":"publish","type":"post","link":"http:\/\/matthewwells.org.uk\/blog\/2008\/02\/conditional-compilation-in-java-almost\/","title":{"rendered":"Conditional Compilation in Java &#8211; Almost"},"content":{"rendered":"<p>Being a little bit long in the tooth and originally coming from an embedded C background, I occasionally hanker after the flexibility of conditional compilation.<\/p>\n<blockquote><p>This is a C based mechanism that allows you to build different flavours of a product from the same code base at compile time by a combination of <code>#define<\/code> and <code>#ifdef<\/code> primitives and a pre-processing step which occurred before compilation.  As the name suggests, this process enabled blocks of code to be included in the final executable (or not) dependent on predefined conditions.<\/p><\/blockquote>\n<p>I&#8217;ve dabbled with various ways of achieving a similar effect in Java and so far this is the simplest approach that I&#8217;ve come up with.  Let me know if you have a better strategy.  The scheme involves simply running a single ant task prior to invoking the Java compiler which effectively selects the product flavour that you intend to build.<br \/>\nFirstly, define all of the different flavours of product that you wish to build in a class <code>ProductType.java<\/code>. For example:<\/p>\n<ol class=\"code\">\n<li class=\"t0\">public class ProductType  {<\/li>\n<li class=\"t1\">public static final String BANANAS = &#8220;bananas&#8221;;<\/li>\n<li class=\"t1\">public static final String APPLES = &#8220;apples&#8221;;<\/li>\n<li class=\"t1\">public static boolean isBananas() {<\/li>\n<li class=\"t2\">return SetProduct.THIS_PRODUCT.equals(BANANAS);<\/li>\n<li class=\"t1\">}<\/li>\n<li class=\"t1\">public static boolean isApples() {<\/li>\n<li class=\"t2\">return SetProduct.THIS_PRODUCT.equals(APPLES);<\/li>\n<li class=\"t1\">}<\/li>\n<li class=\"t0\">}<\/li>\n<\/ol>\n<p>Next, somewhere outside your source code tree, create a product directory for each of the product flavours you need to support.  Each of these directories will hold its own version of the <code>SetProduct.java<\/code> class, which takes the following form:<\/p>\n<ol class=\"code\">\n<li class=\"t0\">public final class SetProduct  {<\/li>\n<li class=\"t1\">public static final String THIS_PRODUCT = ProductType.BANANAS;<\/li>\n<li class=\"t0\">}<\/li>\n<\/ol>\n<p>The ant task for each product flavour copies the <code>SetProduct.java<\/code> class from the specified product directory into the correct location in your java source code tree.<\/p>\n<ol class=\"code\">\n<li class=\"t0\">&lt;target name=&#8221;bananas&#8221;&gt;<\/li>\n<li class=\"t1\">&lt;copy overwrite=&#8221;true&#8221; todir=&#8221;src\/mypackage&#8221;&gt;<\/li>\n<li class=\"t2\">&lt;fileset dir=&#8221;products\/bananas&#8221;&gt;<\/li>\n<li class=\"t3\">&lt;include name=&#8221;SetProduct.java&#8221;&gt;<\/li>\n<li class=\"t2\">&lt;\/fileset&gt;<\/li>\n<li class=\"t1\">&lt;\/copy&gt;<\/li>\n<li class=\"t0\">&lt;\/target&gt;<\/li>\n<\/ol>\n<p>It is important that no version of this class exists in the source code tree within your version control system.  This ensures that a product flavour must be selected via an ant task before the code can be compiled successfully.  (Other non-java files, such as web.xml which vary between product flavours can also be copied across at this point by the same ant task, but the <code>SetProduct.java<\/code> file is the only one that is required to support conditional compilation.)<\/p>\n<p>Within your code base you can now define conditional blocks in the following way:<\/p>\n<ol class=\"code\">\n<li class=\"t1\">if (ProductType.isBananas()){<\/li>\n<li class=\"t2\">yellow = true;<\/li>\n<li class=\"t2\">peelable = true;<\/li>\n<li class=\"t1\">}<\/li>\n<li class=\"t1\">else if (ProductType.isApples()){<\/li>\n<li class=\"t2\">yellow = false;<\/li>\n<li class=\"t2\">peelable = true;<\/li>\n<li class=\"t1\">}<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Being a little bit long in the tooth and originally coming from an embedded C background, I occasionally hanker after the flexibility of conditional compilation. This is a C based mechanism that allows you to build different flavours of a product from the same code base at compile time by a combination of #define and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,6,10],"tags":[],"class_list":["post-9","post","type-post","status-publish","format-standard","hentry","category-ant","category-java","category-software-process"],"_links":{"self":[{"href":"http:\/\/matthewwells.org.uk\/blog\/wp-json\/wp\/v2\/posts\/9","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/matthewwells.org.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/matthewwells.org.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/matthewwells.org.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/matthewwells.org.uk\/blog\/wp-json\/wp\/v2\/comments?post=9"}],"version-history":[{"count":0,"href":"http:\/\/matthewwells.org.uk\/blog\/wp-json\/wp\/v2\/posts\/9\/revisions"}],"wp:attachment":[{"href":"http:\/\/matthewwells.org.uk\/blog\/wp-json\/wp\/v2\/media?parent=9"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/matthewwells.org.uk\/blog\/wp-json\/wp\/v2\/categories?post=9"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/matthewwells.org.uk\/blog\/wp-json\/wp\/v2\/tags?post=9"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}