Using the Ant classpath in Eclipse

I have an Ant build.xml file that works fine on the command line: it compiles, creates a JAR, and I can just execute the main method from the JAR. The build.xml file refers to several third-party libraries that are scattered here and there. When creating a JAR, the script does not include all third-party libraries in the JAR. Instead, it puts its way into the JAR manifest. This helps keep my JAR slim and neat.

I would like to be able to edit and debug my project in Eclipse, but I cannot find an easy way to do this. Can I use the Ant project to create a project and it seems to work. However, Eclipse has difficulty finding third-party rights, and therefore, Eclipse has two problems:

  • it shows (in a text editor) many compilation errors, because the many classes are undefined and
  • he cannot perform a jar.

I can solve both of these problems by manually specifying in two difference places (i.e. the build path through Properties->Java Build Path->Libraries and the execution class path through Run Configurations->Classpath ), all third-party libraries. But it seems to me that I do not need to do this manually, since all third-party libraries are already listed in the JAR manifest. What am I doing wrong?

Here is my build.xml file:

 <!-- Set global properties for this build --> <property name="src" location="./src" /> <property name="build" location="./build"/> <property name="dist" location="./dist"/> <property name="logs" location="./logs"/> <property name="docs" location="./docs"/> <property name="jar" location="${dist}/dynamic_analyzer.jar"/> <property name="lib" location="../../thirdparty/lib"/> <property name="hive-util" location="../../hive-utils/dist"/> <property name="hpdb" location="../../hive-db/hpdb/dist"/> <property name="static" location="../../hive-backend/static_analyzer/dist"/> <property name="mainclass" value="com.datawarellc.main.DynamicMain"/> <path id="dep.runtime"> <fileset dir="${lib}" includes="**/*.jar"/> <fileset dir="${hive-util}" includes="**/*.jar"/> <fileset dir="${hpdb}" includes="**/*.jar"/> <fileset dir="${static}" includes="**/*.jar"/> </path> <target name="clean"> <delete dir="${build}"/> <delete dir="${dist}"/> <delete dir="${docs}"/> <delete dir="${logs}"/> </target> <target name="init"> <tstamp/> <mkdir dir="${build}"/> <mkdir dir="${dist}"/> <mkdir dir="${logs}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}" debug="on" includeantruntime="false"> <classpath refid="dep.runtime" /> </javac> <!-- Debug output of classpath --> <property name="myclasspath" refid="dep.runtime"/> <echo message="Classpath = ${myclasspath}"/> </target> <target name="jar" depends="compile"> <!-- Put the classpath in the manifest --> <manifestclasspath property="manifest_cp" jarfile="${jar}" maxParentLevels="10"> <classpath refid="dep.runtime" /> </manifestclasspath> <jar jarfile="${jar}" basedir="${build}"> <manifest> <attribute name="Main-Class" value="${mainclass}"/> <attribute name="Class-Path" value="${manifest_cp}"/> </manifest> <zipfileset dir="${src}" includes="**/*.xml" /> </jar> </target> 

You can see that I have third-party libraries in several directories ( ${lib} , ${hive-util} , ${hpdb} and ${static} ). I use them to create a path called dep.runtime . Then I include dep.runtime in the manifest when creating my jar. How can I force Eclipse to use the same dep.runtime for the build path and class path at runtime?

+6
source share
2 answers

I came up with the following workaround inspired by the link provided by @ leeand00.

First I wrote a simple Perl script (called genClasspath.pl ) that generates a .classpath file that uses Eclipse.

 #!/usr/bin/perl use strict; if (@ARGV != 2) { print STDERR "Usage: $0 OUTFILE CLASSPATHSTRING\n"; print STDERR "eg, $0 .classpath path1:path2:path3\n"; exit 1; } my $OUTFILE = $ARGV[0]; my $CLASSPATHSTRING = $ARGV[1]; open my $out_fh, '>', $OUTFILE or die "Couldn't open output file: $!"; print $out_fh q{<?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="output" path="build"/> }; my @libs = split(":", $CLASSPATHSTRING); foreach my $thisLib (@libs){ print $out_fh " <classpathentry kind=\"lib\" path=\"$thisLib\"/>\n"; } print $out_fh "</classpath>\n"; 

Then I have a build.xml file that calls this script with the contents of dep.runtime :

 <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}" debug="on" includeantruntime="false"> <classpath refid="dep.runtime" /> </javac> <property name="myclasspath" refid="dep.runtime"/> <exec dir="." executable="../../scripts/genClasspath.pl" os="Linux"> <arg value=".classpath"/> <arg value="${myclasspath}"/> </exec> </target> 

The only thing I need to run Ant is on the command line at least once before I open the project in Eclipse. But when I do this, Eclipse can compile and execute my project just fine, because the class path is exactly the same as Ant.

+2
source

An alternative to perl is to use the built-in groovy task :

 <project name="demo" default="eclipse-files"> <property name="src.dir" location="src"/> <property name="classes.dir" location="build/classes"/> <path id="dep.runtime"> <fileset dir="${lib}" includes="**/*.jar"/> <fileset dir="${hive-util}" includes="**/*.jar"/> <fileset dir="${hpdb}" includes="**/*.jar"/> <fileset dir="${static}" includes="**/*.jar"/> </path> <target name="bootstrap"> <mkdir dir="${user.home}/.ant/lib"/> <get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.1.4/groovy-all-2.1.4.jar"/> </target> <target name="eclipse-files"> <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/> <groovy> import groovy.xml.MarkupBuilder project.log "Creating .classpath" new File(".classpath").withWriter { writer -> def xml = new MarkupBuilder(writer) xml.classpath() { classpathentry(kind:"src", path:properties["src.dir"]) classpathentry(kind:"output", path:properties["classes.dir"]) classpathentry(kind:"con", path:"org.eclipse.jdt.launching.JRE_CONTAINER") project.references."dep.runtime".each { classpathentry(kind:"lib", path:it) } } } </groovy> </target> <target name="clean"> <delete file=".classpath"/> </target> </project> 

Notes:

  • Target bootstrap will load a third-party groovy banner (no perl dependency)
  • groovy can directly access the dep.runtime ANT path and iterate over its contents
  • groovy has excellent support for writing XML files.

The following answer is similar and additionally generates an Eclipse.project file.

+3
source

Source: https://habr.com/ru/post/946500/


All Articles