Java Preprocessor Using Eclipse Part 7 PDF Print E-mail
Written by Administrator   
Monday, 04 January 2010 03:43

Java Preprocessor Using Eclipse Part 7

 <-- Prev Page      Next Page -->

 Now that we have got an Ant script building the project, we can now use the Preprocessor.   Remember what we set out to accomplish in Part 1 of this article?

 

#ifdef PRO_VERSION

   System.out.println("Welcome to the PRO version of this wonderful software.  :) ");

#else

   System.out.println("Sorry, you are using the lousy, crippled, and worthless version of our otherwise wonderful software. :( ");

#endif

 

 Ok, well we won't have something that looks just like that, but we'll come pretty close.

 

The preprocessor will read in a source file, and then modify the source and write it out somewhere else.   Then we compile that modified file based on some variables which define.   First we must add some code to our build script so it creates a folder to put the modified source code in, and deletes it when cleaned.

 

Making the build file create different temporary source folders for the 'Pro' and 'Lite' version,

(and also different output folders).

 

  Change the prebopBuild.xml file to create two new source folders in the temp directory of the system.   One is for the 'lite' version, the other is for the 'pro' version.  In addition, we will now have two build folders for the output .class files,  bin/lite and bin/pro. 

 

<?xml version="1.0"?>
<project name="Hello" default="compile" basedir=".">
    <!-- Sets variables which can later be used. -->
    <!-- The value of a property is accessed via ${} -->
    <property name="src" location="src" />
   
    <!-- We are going to temporarily write source code outside of the workspace -->
    <property name="tmpfolder" value="/tmp/Hello" />
    <property name="src_lite" value="${tmpfolder}/src_lite"/>
    <property name="src_pro" value="${tmpfolder}/src_pro"/>   
   
    <property name="build" location="bin" />
    <property name="build_lite" value="${build}/lite"/>
    <property name="build_pro" value="${build}/pro"/>   

    <!-- Creates the  build, docs and dist directory-->
    <target name="clean">
        <delete dir="${tmpfolder}" />
        <delete dir="${build}" />
    </target>

    <!-- Creates the  build, docs and dist directory-->
    <target name="makedir">
        <mkdir dir="${src_lite}" />
        <mkdir dir="${src_pro}" />
        <mkdir dir="${build_lite}" />
        <mkdir dir="${build_pro}" />
    </target>
   
    <!-- Copies source files from src folder to src_lite and src_pro folder -->
    <target name="copysource">
    <copy todir="${src_lite}"> <fileset dir="src"/> </copy>
    <copy todir="${src_pro}"> <fileset dir="src"/> </copy>
    </target>


    <!-- Compiles the java code -->
    <target name="compile" depends="makedir, copysource">
        <javac srcdir="${src_lite}" destdir="${build_lite}" />
        <javac srcdir="${src_pro}" destdir="${build_pro}" />
    </target>

</project>
 

   So when the user now selects 'Build' then the compile target gets executed.   Looking at that final target section, we see that 'compile' depends on the targets 'makedir' and 'copysource'.   So we need to execute the targets 'makedir' first, then 'copysource' before we proceed.     

 

  The target 'makedir' now creates 4 new folders.   It creates two source folders in the tmp directory which is outside the workspace.  I did this to prevent either Eclipse or myself from getting confused by duplicate packages and source files.   It also now creates two folders in the 'bin' output folder.   One for the 'lite' version, and another for the 'pro' version.

   Then the copysource target executes.   It simply copies all the source files from the src folder (and its subfolders) into the tmp folders.

  Finally, the 'Compile' target can run.   It compiles the source from the first tmp dir (/tmp/Hello/lite/*.java) and builds the class files in the bin/lite folder.  It repeats the compile from the /tmp/Hello/pro folder into the /bin/pro output folder.

 Here is what the console output from the build looks like:


 

makedir:
       [mkdir] Created dir: C:\tmp\Hello\src_lite
       [mkdir] Created dir: C:\tmp\Hello\src_pro
       [mkdir] Created dir: C:\eclipse_workspace\Hello\bin\lite
       [mkdir] Created dir: C:\eclipse_workspace\Hello\bin\pro

copysource:
        [copy] Copying 1 file to C:\tmp\Hello\src_lite
        [copy] Copying 1 file to C:\tmp\Hello\src_pro

compile:
       [javac] Compiling 1 source file to C:\eclipse_workspace\Hello\bin\lite
       [javac] Compiling 1 source file to C:\eclipse_workspace\Hello\bin\pro
BUILD SUCCESSFUL
Total time: 1 second


 

  Well whoopdeedoo, we haven't yet accomplished anything.

   And... the project no longer runs.  When we try we get this error:

 Thread [main] (Suspended (exception ClassNotFoundException))    
    URLClassLoader$1.run() line: not available [local variables unavailable]

   The reason we are getting this error is that .class output files have moved.   

  We need to change the classpath in the debug configuration so that it can find the Hello.class file.  The followin picture shows how to add the bin/lite folder to the classpath so Eclipse can find the Hello.class file to run.

 Debug Config Classpath

 

   This debug configuration should also probably have its name changed from 'Hello' to 'Hello - lite'.

So now finally, we are ready to invoke the preprocessor plugin.

Invoking the Prebop Preprocessor

   What we are going to do now is replace the 'copysource' target with a new target call  'splitsource'.   Splitsource will actually copy the source files, but modify them according to the preprocessor variables, so that the source in /tmp/Hello/pro will be different than the source code in /tmp/Hello/lite.

(... The top twenty lines or so was omitted for brevity  ...)

    <target name="splitsource"  description="preprocessor">
        <preprocess indir="${src}" outdir="${src_lite}" out="replace">
            <var name="pro" value="false"/>
            <filetype commentend="*/" commentbegin="/*" extensions="java"/>
        </preprocess>
        <preprocess indir="${src}" outdir="${src_pro}" out="replace">
            <var name="pro" value="true"/>
            <filetype commentend="*/" commentbegin="/*" extensions="java"/>
        </preprocess>
    </target>

    <!-- Compiles the java code -->
    <target name="compile" depends="makedir, splitsource">
        <javac srcdir="${src_lite}" destdir="${build_lite}" />
        <javac srcdir="${src_pro}" destdir="${build_pro}" />
    </target>

</project>

   If the project no longer builds and complains about not being able to find the 'preprocess' Ant task, then right-click on your xml file and check the configuration.   If in the JRE tab you have it set to run in a separate process, then you must change it so it run in the same JRE as the workspace.   Be advised that the default setting is incorrect.

   After making these changes and cleaning the project, the console output looks like this:

 


makedir:
       [mkdir] Created dir: C:\tmp\Hello\src_lite
       [mkdir] Created dir: C:\tmp\Hello\src_pro
       [mkdir] Created dir: C:\eclipse_workspace\Hello\bin\lite
       [mkdir] Created dir: C:\eclipse_workspace\Hello\bin\pro

splitsource:
  [preprocess] modified 0 of 1 files
  [preprocess] modified 0 of 1 files

compile:
       [javac] Compiling 1 source file to C:\eclipse_workspace\Hello\bin\lite
       [javac] Compiling 1 source file to C:\eclipse_workspace\Hello\bin\pro
BUILD SUCCESSFUL
Total time: 1 second

 


   If your console output looks like this, then the preprocessor is running.   All we need to do now is mark up the .java source code with the preprocessor commands!

 

 <-- Prev Page      Next Page -->

 

Last Updated on Monday, 04 January 2010 05:20
 

Sponsored Links

Bold Inventions, Powered by Joomla!; Joomla templates by SG web hosting