Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Ant, Eclipse and everything in between.

Options
  • 20-11-2007 7:15pm
    #1
    Registered Users Posts: 26,579 ✭✭✭✭


    right i'm doing an assignment for college - for an optional subject i didn't want to pick as i had three subjects and had to pick two - and i can't get my head around it.

    basically the assignment is to find bugs in a java project in eclipse using Junit tests. This i found was the easier bit of the assignment, but i'm having problems when it comes to using Ant.

    we were only shown one lecture in ant and that was how to creat a build.xml file that would compile files from a single directory.

    but now in this assignment we are asked to do this.
    You should create an Ant build file for your project which will include targets to do at least the following:

    * Compile all files required
    * Compile all tests required
    * Create a jar of application classes built which allows the application to be executed from that jar
    * Create a jar of test classes built which allows the tests to be executed from that jar
    * Run junit tests created and record the results of your junit tests in a file called serverresults.xml
    * Use properties to refer to the structure of your project

    You should include additional targets if you think you need them. You should comment your build file adequately explaining any choices of arguments and parameters provided for tasks.

    This build file should work within Eclipse and from the command prompt.
    the directory structure of my project so far is this.
    /assignment
         /bin                                    //stores the .class files.
              /seke/assign                   
                               /test            //stores the .class junit test files.
    
         /lib                                   //stores junit.jar
         /src                                  //stores the .java source files.
         /unittests                          //stores the junit test source files.
    
    now i have a build.xml file in the /assignment folder, that has the following in it.
    <project name="CoffeeMaker">
    	<property name="TALK" value="true" />
    	<!--base.dir = location of Coffeemaker project-->
    	<property name ="base.dir" value="U:\SEKE\assignment"/>
    	<!--src.dir = location of Coffeemaker source files-->
    	<property name="src.dir"   value="${base.dir}\src"/>
    	<!--classes.dir location of Coffeemaker class files-->
    	<property name="classes.dir"  value="${base.dir}\bin\seke\assign"/>
    	<!--junitoutput.dir where junit result file will go-->
    	<property name="junitoutput.dir" value="${base.dir}\unittest_results"/>
    	<!--junit.dir = location of junit-->
    	<property name="junit.dir" value="C:\Program Files\junit\4.31"/>
    	<!--junit.jar = location of junit.jar-->
    	<property name="junit.jar" location="${base.dir}\lib\junit-4.1.jar"/>
    	<!--tst.dir = location of project test source files-->
    	<property name="tst.dir" location="${base.dir}\unittests\seke\assign\test"/>
    
    	<!--setting up the classpath-->
    	<path id="classpath">
    		    <pathelement location="${junit.jar}" />
    			<pathelement location="${src.dir}"/>		
    		  	<pathelement location="${junit.dir}"/>
    		    <pathelement location="${classes.dir}" />
    		    <pathelement location="${tst.dir}" />
    	</path>
    
    
    		<target name="compile_src" description="Compiler the source files">
    				<javac srcdir="${src.dir}"/>
    		</target>
    		
    		<target name="compile_test" description="Compile the junit test files">
    				
    				<javac srcdir="${tst.dir}"/>
    		</target>
    </project>
    

    none of the targets compile.

    anyone know what's going on? please just a note, i'm a honest to god newbie at this so take it easy on me. also anyone got any tips on how i'd go about doing any of the other requirements of the build file per the assignment?

    i've tried searching this on google but it goes totally over my head with the likes of <filesets> / <path id> 's etc.


Comments

  • Registered Users Posts: 1,996 ✭✭✭lynchie


    They wont compile because it doesnt find any of your java files or it finds them but the compile fails due to a bad classpath??


  • Registered Users Posts: 26,579 ✭✭✭✭Creamy Goodness


    sorry should of said, when i run the build file from eclipse or command line ant i get this message

    Buildfile: U:\SEKE\assignment\build.xml
    BUILD SUCCESSFUL
    Total time: 453 milliseconds

    i'm assuming it would give me an error if it couldn't compile. searching the folders it doesn't output any class files.

    also if i start off the build file with this....

    <project name="CoffeeMaker" default="compile_src">

    it compiles the three .java files in the ${src.dir} directory.


  • Registered Users Posts: 11,980 ✭✭✭✭Giblet


    <path id="master-classpath">
            <fileset dir="${lib.dir}">
                <include name="*.jar"/>
            </fileset>        
    </path>
    
    <target name="build" description="Compile main source tree java files">
            <mkdir dir="${build.dir}"/>
            <javac destdir="${build.dir}"  debug="true"
                   deprecation="false" optimize="false" failonerror="true">
                <src path="${src.dir}"/>
                <classpath refid="master-classpath"/>
            </javac>
        </target>
    
    <target name="clean" description="Clean output directories">
            <delete>
                <fileset dir="${build.dir}">
                    <include name="**/*.class"/>
                </fileset>
            </delete>
        </target>
    
    
    <target name="junit" depends="build" description="Run JUnit Tests">
            <junit printsummary="on"
                   fork="false"
                   haltonfailure="false"
                   failureproperty="tests.failed"
                   showoutput="true">
                <classpath refid="master-classpath"/>
                <formatter type="brief" usefile="false"/>
    
                <batchtest>
                    <fileset dir="${build.dir}">
                        <include name="**/Test*.*"/>
                    </fileset>
                </batchtest>
    
            </junit>
    
            <fail if="tests.failed">
            tests.failed=${tests.failed}
            ***********************************************************
            ***********************************************************
            ****  One or more tests failed!  Check the output ...  ****
            ***********************************************************
            ***********************************************************
            </fail>
        </target>
    

    build.dir being the output and lib.dir being the lib folder.


  • Registered Users Posts: 26,579 ✭✭✭✭Creamy Goodness


    ok so this is what i have now...
    <project name="CoffeeMaker" default="junit">
    	<property name="TALK" value="true" />
    	<property name ="base.dir" value="."/>
    	<property name="src.dir"   value="${base.dir}\src\seke\assign"/>
    	<property name="build.dir" value="${base.dir}\build"/>
    	<property name="lib.dir" value="${base.dir}\lib"/>
    	<property name="classes.dir"  value="${base.dir}\bin\seke\assign"/>
    	<property name="junitoutput.dir" value="${base.dir}\unittest_results"/>
    	<property name="junit.dir" value="C:\Program Files\junit\4.31"/>
    	<property name="junit.jar" location="${base.dir}\lib\junit-4.1.jar"/>
    	<property name="tst.dir" location="${base.dir}\unittests\seke\assign\test"/>
    
    	<path id="master-classpath">
    	        <fileset dir="${lib.dir}">
    	            <include name="*.jar"/>
    	        </fileset>        
    	</path>
    
    	<target name="build" description="Compile main source tree java files">
    	        <mkdir dir="${build.dir}"/>
    	        <javac destdir="${build.dir}"  debug="true"
    	               deprecation="false" optimize="false" failonerror="true">
    	            <src path="${src.dir}"/>
    	            <classpath refid="master-classpath"/>
    	        </javac>
    	    </target>
    	
    	<target name="buildtests" depends="build" description="Compile main source unit test files">
    		        <javac destdir="${build.dir}"  debug="true"
    		               deprecation="false" optimize="false" failonerror="true">
    		            <src path="${tst.dir}"/>
    		            <classpath refid="master-classpath"/>
    		        </javac>
    		    </target>
    
    	<target name="clean" description="Clean output directories">
    	        <delete>
    	            <fileset dir="${build.dir}">
    	                <include name="**\*.class"/>
    	            </fileset>
    	        </delete>
    	</target>
    	
    	<target name="junit" depends="buildtests" description="Run JUnit Tests">
    	        <junit printsummary="on"
    	               fork="false"
    	               haltonfailure="false"
    	               failureproperty="tests.failed"
    	               showoutput="true">
    	            <classpath refid="master-classpath"/>
    	            <formatter type="brief" usefile="false"/>
    
    	            <batchtest>
    	                <fileset dir="${build.dir}">
    	                    <include name="**\*Test.*"/>
    	                </fileset>
    	            </batchtest>
    
    	        </junit>
    
    	        <fail if="tests.failed">
    	        tests.failed=${tests.failed}
    	        One or more tests failed!  Check the output ...
    	        </fail>
    	 </target>
    </project>
    

    both the source files (CoffeeMaker.java/Recipe.java/Inventory.java/Main.java) and the unittests (CoffeeMakerTest.java/InventoryTest.java/RecipeTest.java) compile and the .class files are put in the directory ./build/seke/assign for the source files and ./build/seke/assign/test for the test files.

    running the junit tests from the build file fails and i get a whole summary of what's going wrong but i can't make heads nor tails of it.

    before i post up the output, i ran the test files in junit using eclipse,

    CoffeeMakerTest.java has 8 tests, 8 successfully run and no errors/failures.

    RecipeTest.java has 12 tests, 12 successfully run and no errors/failures.

    InventoryTest.java has 9 tests, 9 successfully run and no errors/failures.

    Despite this i can this huge output when i run the above build.xml file in eclipse.
    Buildfile: /Users/neil/Desktop/SEKE/assignment/build.xml
    build:
        [javac] Compiling 4 source files to /Users/neil/Desktop/SEKE/assignment/build
    buildtests:
        [javac] Compiling 3 source files to /Users/neil/Desktop/SEKE/assignment/build
    junit:
        [junit] Running seke.assign.test.CoffeeMakerTest
        [junit] Testsuite: seke.assign.test.CoffeeMakerTest
        [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
        [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
        [junit] Null Test: 	Caused an ERROR
        [junit] seke.assign.test.CoffeeMakerTest
        [junit] java.lang.ClassNotFoundException: seke.assign.test.CoffeeMakerTest
        [junit] 	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        [junit] 	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:374)
        [junit] 	at java.lang.Class.forName0(Native Method)
        [junit] 	at java.lang.Class.forName(Class.java:242)
        [junit] 	at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
        [junit] 	at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
        [junit] 	at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
        [junit] Test seke.assign.test.CoffeeMakerTest FAILED
        [junit] Running seke.assign.test.InventoryTest
        [junit] Testsuite: seke.assign.test.InventoryTest
        [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
        [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
        [junit] Null Test: 	Caused an ERROR
        [junit] seke.assign.test.InventoryTest
        [junit] java.lang.ClassNotFoundException: seke.assign.test.InventoryTest
        [junit] 	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        [junit] 	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:374)
        [junit] 	at java.lang.Class.forName0(Native Method)
        [junit] 	at java.lang.Class.forName(Class.java:242)
        [junit] 	at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
        [junit] 	at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
        [junit] 	at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
        [junit] Test seke.assign.test.InventoryTest FAILED
        [junit] Running seke.assign.test.RecipeTest
        [junit] Testsuite: seke.assign.test.RecipeTest
        [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
        [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
        [junit] Null Test: 	Caused an ERROR
        [junit] seke.assign.test.RecipeTest
        [junit] java.lang.ClassNotFoundException: seke.assign.test.RecipeTest
        [junit] 	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        [junit] 	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:374)
        [junit] 	at java.lang.Class.forName0(Native Method)
        [junit] 	at java.lang.Class.forName(Class.java:242)
        [junit] 	at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
        [junit] 	at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
        [junit] 	at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
        [junit] Test seke.assign.test.RecipeTest FAILED
    
    BUILD FAILED
    /Users/neil/Desktop/SEKE/assignment/build.xml:61: tests.failed=true
    	        One or more tests failed!  Check the output ...
    
    Total time: 996 milliseconds
    

    how come it's only running one test in the CoffeeMakerTest.java file?


  • Registered Users Posts: 11,980 ✭✭✭✭Giblet


    It can't find the classes. Make sure the JUnit tests can find your build files.


  • Advertisement
  • Moderators, Science, Health & Environment Moderators Posts: 10,079 Mod ✭✭✭✭marco_polo


    The master-classpath only refers to the lib/ directory. But to be able to find your compiled test classes, the junit task must have the build directory where your tests were compilled to its classpath as well.
    <target name="junit" ..>
    .....
    <classpath>
                      <fileset dir="${lib.dir}">
    	            <include name="*.jar"/>
    	        </fileset> 
                       <fileset dir="${build.dir}">
    	            <include name="*.class"/>
    	        </fileset> 
    </classpath>
    </target>
    


  • Registered Users Posts: 26,579 ✭✭✭✭Creamy Goodness


    i've added this new path.
    <path id="new">
    		<fileset dir="${lib.dir}">
    			<include name="*.jar"/>
    		</fileset> 
    		
    		<fileset dir="${src.dir}">
    			<include name="*.java"/>
    		</fileset>
    		
    		<fileset dir="${build.dir}\seke\assign\test">
    			<include name="*.class"/>
    		</fileset>
    		
    	</path>
    


    and have my junit target like this adding in the path "new".
    <target name="junit" depends="buildtests" description="Run JUnit Tests">
    		<classpath refid="new"/>
    		<junit printsummary="on"
    	               fork="false"
    	               haltonfailure="false"
    	               failureproperty="tests.failed"
    	               showoutput="true">
    	            <classpath refid="master-classpath"/>
    	            <formatter type="brief" usefile="false"/>
    
    	            <batchtest>
    	                <fileset dir="${build.dir}\seke\assign\test">
    	                    <include name="**\*Test.*"/>
    	                </fileset>
    	            </batchtest>
    
    	        </junit>
    
    	        <fail if="tests.failed">
    	        tests.failed=${tests.failed}
    	        One or more tests failed!  Check the output ...
    	        </fail>
    	 </target>
    

    still getting the error that i was above.


  • Moderators, Science, Health & Environment Moderators Posts: 10,079 Mod ✭✭✭✭marco_polo


    Cremo wrote: »
    i've added this new path.
    <path id="new">
    		<fileset dir="${lib.dir}">
    			<include name="*.jar"/>
    		</fileset> 
    		
    		<fileset dir="${src.dir}">
    			<include name="*.java"/>
    		</fileset>
    		
    		<fileset dir="${build.dir}\seke\assign\test">
    			<include name="*.class"/>
    		</fileset>
    		
    	</path>
    


    and have my junit target like this adding in the path "new".
    <target name="junit" depends="buildtests" description="Run JUnit Tests">
    		<classpath refid="new"/>
    		<junit printsummary="on"
    	               fork="false"
    	               haltonfailure="false"
    	               failureproperty="tests.failed"
    	               showoutput="true">
    	            <classpath refid="master-classpath"/>
    	            <formatter type="brief" usefile="false"/>
    
    	            <batchtest>
    	                <fileset dir="${build.dir}\seke\assign\test">
    	                    <include name="**\*Test.*"/>
    	                </fileset>
    	            </batchtest>
    
    	        </junit>
    
    	        <fail if="tests.failed">
    	        tests.failed=${tests.failed}
    	        One or more tests failed!  Check the output ...
    	        </fail>
    	 </target>
    

    still getting the error that i was above.

    I see two possible causes

    Firstly the <classpath refid="new"/> tag should be within the <junit> task tag itself not declared before it in the target, I still see <classpath refid="master-classpath"/> in the junit task itself .

    Secondly (I am assuming that ${build.dir} is the root dir that contains the test package directories and classes) ie. that CoffeeMakerTest.class is in a directory called ${build.dir}\seke\assign\test\seke\

    The current classpath that you posted there means that if junit is looking for seke.assign.test.CoffeeMakerTest.class would look for the class in a directory called ${build.dir}\seke\assign\test\seke\assign\test, which does not exist.

    Going on the above assumption (I am not sure of your exact directory stuucture) the new path should contain this
    <fileset dir="${build.dir}">
            <include name="*.class"/>
        </fileset> 
    

    instead of
    <fileset dir="${build.dir}\seke\assign\test">
            <include name="*.class"/>
        </fileset> 
    


  • Registered Users Posts: 26,579 ✭✭✭✭Creamy Goodness


    the ${build.dir} contains a folder called seke/assign in this directory there is .class relating to the CoffeeMaker.java / Inventory.java / Recipe.java / Main.java (the program i'm testing.) in the seke/assign directory i have another directory called test that holds the .class files of the Junit tests (RecipeTest.class / Inventory.class / CoffeeMaker.class).

    i changed the new path id to contain this.
    <path id="new">
                <fileset dir="${lib.dir}">
                    <include name="*.jar"/>
                </fileset> 
                
                <fileset dir="${src.dir}">
                    <include name="*.java"/>
                </fileset>
                
                <fileset dir="${build.dir}">
                    <include name="*.class"/>
                </fileset>
                
    </path>
    
    and referred to it in my junit target under the junit tag so now my junit target looks like this.
    <target name="junit" depends="buildtests" description="Run JUnit Tests">
            <junit printsummary="on" fork="false" haltonfailure="false" failureproperty="tests.failed"
             showoutput="true">
                <classpath refid="new"/>
                <formatter type="brief" usefile="false"/>
    
                <batchtest>
    
                    <fileset dir="${build.dir}">
                        <include name="**\*Test.*"/>
                    </fileset>
                </batchtest>
    
            </junit>
    
            <fail if="tests.failed">
                tests.failed=${tests.failed}
                One or more tests failed!  Check the output ...
            </fail>
    </target>
    

    i'm still getting the tests to fail. :(


  • Moderators, Science, Health & Environment Moderators Posts: 10,079 Mod ✭✭✭✭marco_polo


    Is it still the ClassNotFoundException, or are the tests failing in some other way?


  • Advertisement
  • Registered Users Posts: 21,264 ✭✭✭✭Hobbes


    If you run ant with the -debug option and pipe it to a file it can generally tell you exactly where your messing up.

    Most likely cause is that you either have your classpath wrong for the Junit part or you haven't actually compiled your Test scripts prior to running them.


Advertisement