Ant: Source and target files are the same. How to

2019-07-06 17:12发布

问题:

We are using JiBX. The important thing to know is that JiBX modifies the already compiled class files.

We do our compile:

<javac destdir="${main.destdir}">
    <src path="${main.srcdir}"/>
    <classpath refid="main.classpath"/>
</javac>

Then, we call JiBX:

<jibx load="true"
    binding="{$binding.file}">
    <classpath refid="main.classpath"/>
    <classpath refid="main.destdir.classpath"/>
</jibx>

This uses an XML file that updates the classfiles compiled by <javac> above. The problem is how do I know that the files have been compiled, but not processed by JiBX? I'd like to put some logic in my program, so that files are not updated twice by JiBX. Besides, it's bad form to duplicate work that already been done.

回答1:

After the jibx build step, generate a marker file, e.g.

<touch file="${target.dir}/jibx.marker" />

Only perform the jibx build step if that marker file is older than the .class files (indicating that the javac ran more recently than the last jibx).

For that bit of logic, you can use the traditional ant way:

<uptodate property="jibx.uptodate" targetfile="${target.dir}/jibx.marker">
   <srcfiles dir="${main.destdir}" includes="...../*.class" />
</uptodate>

And then use the property with an unless clause when invoking the jixb target.

Or, you can use Antcontrib's outofdate alternative:

<outofdate>
  <sourcefiles>
    <fileset dir="${main.destdir}" includes="...../*.class" />
</sourcefiles>
<targetfiles>
    <fileset dir="${target.dir}" includes="jibx.marker"/>
</targetfiles>
<sequential>
    <jibx load="true"
        binding="{$binding.file}">
        <classpath refid="main.classpath"/>
        <classpath refid="main.destdir.classpath"/>
    </jibx>
</sequential>
</outofdate>


回答2:

I'm giving this to Patrice M. because his suggestion put me on the right track. However, it didn't quite work out as he stated. (Sorry, if I got he pronoun wrong, but Patrice can be both a male or female name.)

What I had to do was create two watch files: One for the Java compile, and one for the JiBX changes.

<!-- Check if Javac is out of date. If so, create javac watcher -->
<outofdate verbose="true">
    <sourcefiles>
        <fileset dir="${main.srcdir}">
            <include name="*.java"/>
        </fileset>
    </sourcefiles>
    <mapper type="regexp"
        from="${main.srcdir}/(.*)\.java"
        to="${main.destdir}/(\1).class"/>
    <sequential>
        <echo message="Java compiled"/>
        <echo message="Java compiled"
            file="${target.dir}/${javac.monitor.file}"/>
    </sequential>
</outofdate>

<javac destdir="${main.destdir}"
    debug="${javac.debug}">
    <src path="${main.srcdir}"/>
    <classpath refid="main.classpath"/>
</javac>

<!-- Compare javac and jibx monitoring file -->
<!-- If out of date, rerun jibx -->
<outofdate>
    <sourcefiles>
        <fileset dir="${target.dir}">
            <include name="${javac.monitor.file}"/>
        </fileset>
    </sourcefiles>
    <targetfiles>
        <fileset dir="${target.dir}">
            <include name="${jibx.monitor.file}"/>
        </fileset>
    </targetfiles>
    <sequential>
        <jibx load="true"
            binding="${target.dir}/binding-gg.xml">
            <classpath refid="main.classpath"/>
            <classpath refid="main.destdir.classpath"/>
        </jibx>

        <!-- Create JiBX monitoring file -->
        <echo message="Compiled and JiBX"
            file="${target.dir}/${jibx.monitor.file}"/>
    </sequential>
</outofdate>

I create the javac monitoring file if the source is out of date with the classes because that's when I compile. I have to create the JiBX outofdate monitoring file only when I run JiBX and that's inside the <outofdate> for JiBX.

I guess I could also put a source on the XML JiBX files too just to be sure.



标签: ant