1
votes

I am very new in Ant (I came from Maven) and I am finding some difficulties with this simple Ant script that compile a Java project located into Eclipse workspace:

The Ant script code is:

<?xml version="1.0"?>
<project>

    <!-- ============================================ -->
    <!-- Load build properties                        -->
    <!-- ============================================ -->

    <property name="project.buildfile" value="build.num" />
    <property file="${project.buildfile}" />
    <property file="info.properties" />

    <!-- Elimina le cartelle contenenti le classi compilate ed i jar -->
    <target name="clean">
        <delete dir="../Release" />
        <!-- Elimina directory del jar finale -->
        <delete dir="bin" />
        <!-- Elimina directory delle classi compilate -->
    </target>

    <target name="compile">
        <mkdir dir="bin" />
        <javac srcdir="src" destdir="bin" />
    </target>
</project>

So this script have a first target named clean that simply delete 2 directory into my project (this part work well)

The other target is named compile that implements 2 simple tasks related the compilation of the project:

1) Create a directory named bin in my project (this is ok)

2) Compile the sources that are into src project folder and put the .class file into the bin directory.

And here I have some problem because when I execute this ant script I obtain these errors messages:

Buildfile: /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/build.xml
clean:
   [delete] Deleting directory /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/bin
compile:
    [mkdir] Created dir: /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/bin
    [javac] /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/build.xml:22: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 35 source files to /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/bin
    [javac] /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/src/com/techub/crystalice/xmlhandler/Settings.java:12: package org.apache.log4j does not exist
    [javac] import org.apache.log4j.Logger;
    [javac]                        ^
    [javac] /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/src/com/techub/crystalice/xmlhandler/Settings.java:14: package com.adamtaft.eb does not exist
    [javac] import com.adamtaft.eb.EventBusService;
    [javac]                       ^
    [javac] /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/src/com/techub/crystalice/xmlhandler/Settings.java:26: cannot find symbol
    [javac] symbol  : class Logger
    [javac] location: class com.techub.crystalice.xmlhandler.Settings
    [javac]     public static final Logger logger = Logger.getLogger("gui");
    [javac]                         ^
    [javac] /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/src/com/techub/crystalice/xmlhandler/Utils.java:9: package org.apache.log4j does not exist
    [javac] import org.apache.log4j.Logger;
    [javac]                        ^
    [javac] /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/src/com/techub/crystalice/xmlhandler/Utils.java:16: cannot find symbol
    [javac] symbol  : class Logger
    [javac] location: class com.techub.crystalice.xmlhandler.Utils
    [javac]     private static final Logger logger = Logger.getLogger("gui");
    [javac]                          ^
    [javac] /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/src/com/techub/crystalice/xmlhandler/Settings.java:26: cannot find symbol
    [javac] symbol  : variable Logger
    [javac] location: class com.techub.crystalice.xmlhandler.Settings
    [javac]     public static final Logger logger = Logger.getLogger("gui");
    [javac]                                         ^
    [javac] /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/src/com/techub/crystalice/xmlhandler/Settings.java:130: cannot find symbol
    [javac] symbol  : variable EventBusService
    [javac] location: class com.techub.crystalice.xmlhandler.Settings
    [javac]         EventBusService.publish(new SettingsEvent(this, SettingsEventType.UPDATED));
    [javac]         ^
    [javac] /home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/src/com/techub/crystalice/xmlhandler/Utils.java:16: cannot find symbol
    [javac] symbol  : variable Logger
    [javac] location: class com.techub.crystalice.xmlhandler.Utils
    [javac]     private static final Logger logger = Logger.getLogger("gui");
    [javac]                                          ^
    [javac] 8 errors
BUILD FAILED
/home/andrea/Documenti/XCloud/Implementazione/CrossPlatform/CrystalIceXMLHandler/Project/build.xml:22: Compile failed; see the compiler error output for details.
Total time: 1 second

Why I have these errors? How can I solve?

Tnx

Andrea

5

5 Answers

1
votes

It seems ant is not able to find the required libraries/jars. You need to have the required libraries/jars in either of these two places:

  1. ANT_HOME/lib
  2. A user specific directory, ${user.home}/.ant/lib
1
votes

Try this:

<target name="compile">
    <mkdir dir="bin" />
    <javac srcdir="src" destdir="bin" />
    <classpath>
        <fileset dir="${lib}">
            <include name="**/*.jar" />
        </fileset>
    </classpath>
</target>
0
votes

The errors are there because ant does not fulfil all the dependencies in the way that Maven does. You'll need to manually build a classpath and supply it to your javac command.

0
votes

I am not sure how much this might help because i am a newbie when it comes to ant , but then when i faced the same issues, i added the following lines

<path id="project.classpath">
<pathelement location="${src.dir}" /> 
<path refid="external.jars" /> 
</path>

and also

<jar destfile="${dist.dir}\jarnamehere.jar">
<fileset dir="${bin.dir}" includes="**/*.class" /> 
<zipgroupfileset dir="${lib.dir}" includes="**/*.jar" /> 
</jar>
0
votes

When you compile Java code, you usually dependent on classes that are in other files. For example, I have a database of pies I offer for sale. I write a class to track my pie inventory.

Another program which rings up transactions at my register uses my pie inventory class described above to see if a pie is available, and removes it from my inventory. To be able to do this, I include that pie inventory class in my sales program. However, when I compile my sales program, it needs access to the pie inventory class in order to make sure it can interface with it correctly.

When I compile Java code, I have to have a classpath to all of the classes that are referenced in my code. Thus, I need to do something like this:

 javac -classpath lib/pie_inventory.jar:lib/foo.jar:lib/bar.jar src/main/java/sales.java

You need to do the same thing with your <javac> command. Let's look at your error message:

Settings.java:12: package org.apache.log4j does not exist
    [javac] import org.apache.log4j.Logger;

Your code is referencing the org.apache.log4j package. This package contains classes that you're using in your code, and the compile needs to be able to examine these classes to make sure you're using them correctly. I happen to know that you need a file called log4j.jar and this must be put into your Javac classpath.

The question is do you have this log4j.jar in your working directory? There are two ways to deal with things like this:

The wrong but really, really simple way.

When you need third party jars, you download them, and add them manually to your project. Sometimes these third party jars need other third party jars, and their documentation usually will tell you what they are.

If you're not quite sure what jarfile you need use a tool like Grep Code to help you figure that out.

Why is this the wrong way? Because the jars never get updated, and you quickly lose your ability to tell where they came from.

The correct, but much more difficult way.

You should use a dependency management system that will download the jars for you. There are a few of them:

  • Maven: The granddaddy of them all. Maven has a world wide network system of jar repositories. Maven also handles dependencies of your dependencies. You merely specify the interfaces you depend upon (I need version 1.2.18 of log4j from the org.apache.logging project), and Maven will hunt down that needed jar and all of its dependencies for you. The main problem with Maven is that it simply does way too much. Maven isn't just a dependency management system. It also is a way of describing your project and your build. If you are starting a new project, Maven maybe a the way to go, but it can be hell to convert an existing project to use Maven.

  • Ant with Ivy: Ivy does all the same things Maven does, but works with Ant. The two biggest issues is that you still need build.xml files which developers rarely know how to do, and Ivy's documentation makes Maven's sparse documentation look detailed.

  • Gradle: Build Automation Evolved!

We'll stick with the really wrong way for now...


In your project, you need to put all the jars you need into a particular directory (usually ${basedir}/lib is the standard.

Now, change your <javac> task to include your third party jars:

From:

<javac srcdir="src" destdir="bin" />

To:

<!-- Here's all of my dependencies for compiling -->
<path id="compile.path">
    <fileset dir="${basedir}/lib"/>
</path>

<javac srcdir="src" destdir="bin" classpathref="compile.path"/>

I could have included the classpath directly in my <javac> task, but I prefer to do it this way. If you do JUnit testing, you'll need to reuse that compile.path again. Plus, if you move to Ivy, you can simply redefine that classpath a bit differently:

<!-- Here's all of my dependencies for compiling -->
<ivy:cachepath pathid="compile.path" conf="compile"/>

<javac srcdir="src" destdir="bin" classpathref="compile.path"/>