Our build.xml file contains the following:
<path id="our.classpath">
<fileset dir="${in.libs}"/>
<fileset file="/home/ouruser/fortify/Core/lib/sourceanalyzer.jar"/>
</path>
<target name="compile">
<pathconvert property="test" refid="our.classpath"/>
<echo message="CLASSPATH=${test}"/>
<javac debug="true"
debuglevel="source,lines,vars"
destdir="${out.classes}"
includeAntRuntime="no"
fork="false"
source="1.7" target="1.7">
<src path="${src1.dir}"/>
<src path="${src2.dir}"/>
<classpath refid="our.classpath"/>
<compilerarg value="-Xlint:-path"/>
<compilerarg line="-proc:none"/>
<compilerarg line="-s "${out.classes}""/>
</javac>
</target>
<target name="fortify">
<antcall target="compile">
<param name="build.compiler" value="com.fortify.dev.ant.SCACompiler"/>
</antcall>
</target>
When I run ant fortify, I get the following output:
fortify:
compile:
[echo] CLASSPATH=<a long list of jar files snipped>:/home/ouruser/fortify/Core/lib/sourceanalyzer.jar
BUILD FAILED
/home/ouruser/build.xml:542: The following error occurred while executing this line:
/home/ouruser/build.xml:230: Class not found: com.fortify.dev.ant.SCACompiler
As you can see from the echo output, the sourceanalyzer.jar file is in the classpath that is used by the javac task.
When I run jar -tvf /home/ouruser/fortify/Core/lib/sourceanalyzer.jar | grep SCACompiler.class, the SCACompiler class is listed:
8408 Fri Apr 04 11:17:26 EDT 2014 com/fortify/dev/ant/SCACompiler.class
So why does Ant say Class not found: com.fortify.dev.ant.SCACompiler?
In place of com/fortify/dev/ant/SCACompiler.class class, use
com.fortify.dev.ant.SourceanalyzerTask
Related
I am trying to compile this simple code using Java 10, Ant and the Eclipse compiler:
import java.util.ArrayList;
import javax.xml.bind.JAXBException;
class Test {
void foo() throws JAXBException {
throw new JAXBException("hi there");
}
void bar() {
new ArrayList<String>();
}
}
This is the Ant file I am using:
<project name="Java 10 test">
<target name="compile-javac" depends="clean, print-version-info">
<javac release="10" includeantruntime="false">
<src path="."/>
<compilerarg value="--add-modules"/>
<compilerarg value="java.xml.bind"/>
</javac>
</target>
<target name="compile-ecj-4.7" depends="clean, print-version-info">
<javac compiler="org.eclipse.jdt.core.JDTCompilerAdapter"
release="10" includeantruntime="false">
<src path="."/>
<compilerclasspath>
<pathelement path="ecj-4.7.3a.jar"/>
</compilerclasspath>
<compilerarg value="--add-modules"/>
<compilerarg value="java.xml.bind"/>
</javac>
</target>
<target name="compile-ecj-4.8" depends="clean, print-version-info">
<javac compiler="org.eclipse.jdt.core.JDTCompilerAdapter"
release="10" includeantruntime="false">
<src path="."/>
<compilerclasspath>
<pathelement path="ecj-4.8RC2.jar"/>
</compilerclasspath>
<compilerarg value="--add-modules"/>
<compilerarg value="java.xml.bind"/>
</javac>
</target>
<target name="clean">
<delete file="Test.class"/>
</target>
<target name="print-version-info">
<echo message="Java home is ${java.home}"/>
<echo message="Java version is ${java.version}"/>
<echo message="Ant version is ${ant.version}"/>
</target>
</project>
The code compiles fine if I'm using javac (compile-javac target) but I can't get it to work with either the 4.7.3a or 4.8RC2 Eclipse compilers:
with 4.7.3a, I get the error parameterized types are only available if source level is 1.5 or greater even though I specify release="10"
with 4.7.3a, if I use source="10" and target="10" instead of release="10", the source level error disappears but I get a invalid module name: javax.xml.bind error
with 4.8RC2, I get the source level error and another JAXBException cannot be resolved to a type error, even though I specify that I would like to add the java.xml.bind module where JAXBException is defined.
The print-version-info target gives the following as output:
print-version-info:
[echo] Java home is C:\Program Files\Java\jdk-10
[echo] Java version is 10
[echo] Ant version is Apache Ant(TM) version 1.10.3 compiled on March 24 2018
May be it is a follow up for ecj bug 487421 or I just don't understand the command line options?
in my project there are - among others - two classes: TheProblem and Server.
public class TheProblem {
public static void main (String args []) throws ClassNotFoundException {
ClassLoader.getSystemClassLoader().loadClass("Server");
}
}
When I execute the code from the command line, everything works just fine.
But when I use ANT to execute the code, I get a ClassNotFoundException - although both Server.class and TheProblem.class are inside of the same directory.
The directory structure of my project is fairly simple - I will try to illustrate it here:
root_folder/
- build.xml
- src/
- TheProblem.java
- Server.java
- build/
- TheProblem.class
- Server.class
Here is an excerpt of my build.xml file:
<?xml version="1.0" encoding="UTF-8" ?>
<project name="JAXB" default="compile">
<path id="project.class.path">
<pathelement path="${java.class.path}" />
<pathelement location="build" />
</path>
<target name="init" >
<mkdir dir="build" />
</target>
<target name="compile" depends="init" >
<javac classpathref="project.class.path" srcdir="src" destdir="build"
includeAntRuntime="false" />
</target>
<target name="execute-problem" depends="compile">
<java classpathref="project.class.path" classname="TheProblem" />
</target>
<target name="clean" depends="init">
<delete dir="build" />
</target>
</project>
When I execute ant compile, everything compiles, but when I execute ant execute-problem, the ClassLoader cannot find the Server class and throws a ClassNotFoundException.
When I navigate into the build directory and call java TheProblem, it works just fine. I really have no clue, why it doesn't work using ANT.
Thank you very much for taking the time to read this post.
Instead of
<target name="execute-problem" depends="compile">
<java classpathref="project.class.path" classname="TheProblem" />
</target>
try to use this
<target name="execute-problem" depends="compile">
<java fork="true" dir="." classname="TheProblem">
<classpath>
<path refid="project.class.path" />
</classpath>
</java>
</target>
Here is a very simplified version of what I am trying to achieve. I have two directories, Directory1 and Directory2. Both directories contain Java source files. Some of the files in Directory2 can have the same fully qualified class name as the files in Directory1.
Using ant, the files are compiled to a directory called CompileDirectory, first from Directory1 and then from Directory2. I want the files in Directory2 to be compiled and overwrite the compiled class files from Directory1. However, ant seems to ignore the classes that have the same fully qualified class name.
Here's a simple example -
Directory structure
$ ls -R
.:
build.xml CompileDirectory Directory1 Directory2
./CompileDirectory:
./Directory1:
A.java
./Directory2:
A.java
build.xml
<project name="TestProject" default="build" basedir=".">
<target name="build" depends="javac1, javac2" />
<target name="javac1">
<javac srcdir="${basedir}/Directory1" destdir="CompileDirectory" includeantruntime="false"/>
</target>
<target name="javac2">
<javac srcdir="${basedir}/Directory2" destdir="CompileDirectory" includeantruntime="false"/>
</target>
</project>
Ant run
$ ant -buildfile build.xml
Buildfile: ...(path).../build.xml
javac1:
[javac] Compiling 1 source file to ...(path).../CompileDirectory
javac2:
build:
BUILD SUCCESSFUL
Total time: 0 seconds
As can be seen, the javac2 target above does nothing.
When I run the Java program, I see that the class file is the one from Directory1.
$ cd CompileDirectory/
$ java A
I am class A from directory 1
Is there a way to force the javac task in the javac2 target to compile the source file in Directory2 and overwrite the class file in the CompileDirectory?
It has to do with timestamp of files and whether the compiler thinks the source is newer than class file.
<project name="TestProject" default="build" basedir=".">
<target name="build" depends="javac1, touch2, javac2" />
<target name="javac1">
<javac srcdir="${basedir}/Directory1" destdir="CompileDirectory" includeantruntime="false"/>
</target>
<target name="touch2">
<sleep seconds="2" />
<touch datetime="now">
<fileset dir="${basedir}/Directory2" />
</touch>
</target>
<target name="javac2">
<javac srcdir="${basedir}/Directory2" destdir="CompileDirectory" includeantruntime="false"/>
</target>
</project>
Other possible way to avoid this is create a stage directory and compile the classes there and copy back to original directory using overwrite option.
<project name="TestProject" default="build" basedir=".">
<target name="build" depends="javac1, javac2, copy1" />
<target name="javac1">
<javac srcdir="${basedir}/Directory1" destdir="CompileDirectory" includeantruntime="false"/>
</target>
<target name="javac2">
<javac srcdir="${basedir}/Directory2" destdir="CompileDirectory1" includeantruntime="false"/>
</target>
<target name="copy1">
<copy overwrite="on" todir="CompileDirectory">
<fileset dir="CompileDirectory1">
<include name ="**/*.*"/>
</fileset>
</copy>
</target>
Compiling works fine, but it's not packaging into a jar file.
The final message is BUILD SUCCESSFUL with compiled classes but I cannot find a jar.
<project name="thisIsMyProject" basedir="." default="build">
.
.
.
.
.
Load Classpath and such.....
.
.
.
.
<target depends="init" name="build-project">
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="my.classpath"/>
</javac>
</target>
<mkdir dir="build"/>
<target name="jar" description="Make My Jar File" depends="init">
<jar destfile="myFile.jar" destdir="build" basedir="bin" compress="true" />
</target>
</project>
It looks like your target names are wrong.
Your default target is "build", but you don't actually have a target called "build" - perhaps you should change the default to "jar"
Your "jar" target depends on "init", but it should probably also depend on "build-project" if you want it to compile BEFORE it packages the jar.
Is there a way to set the value of the javac classpath property in Apache Ant (v1.9.6) so that I don't have to literally specify all the jars that I want to include e.g. a directory or file glob.
So, if I have something like:
<javac classpath="./lib/one.jar":./lib/two.jar:./lib/three.jar..."
...is there anyway to just specify my ./lib directory once, like the way you can do when you run a java application like:
java -cp ./lib/'*'
I've tried that, and just using ./lib, or./lib/* or ./lib/*.jar but they don't work.
And another solution using a reusable classpath reference:
<path id="compile.path">
<fileset dir="lib" includes="*.jar"/>
</path>
<javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false" debug="true" classpathref="compile.path"/>
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<path refid="compile.path"/>
<pathelement path="${classes.dir}"/>
</classpath>
..
..
Try putting a <classpath> element under <javac>:
<javac ...>
<classpath>
<fileset dir="lib" includes="*.jar"/>
</classpath>
</javac>