How to build Android project with Ant that depends on Java project? - java

I have an Android Library project, AndroidLib, that depends on a Java project in my workspace, JavaLib.
In Eclipse this is done by adding the JavaLib project to Java Build Path > Projects for AndroidLib and setting it to be exported in the Order and Export tab, and it builds fine.
However Ant doesn't seem to pick up the dependency on the JavaLib project when building AndroidLib (I have run android update lib-project). What is the best way to add this dependency to my build.xml?

I had the same problem. I ended solving it in a very hackish way.
In AndroidLib/build.xml (or better in AndroidLib/custom_rules.xml), I defined a -pre-build target that builds the JavaLib and copies the resulting jar in libs/. I also defined a -post-package target to remove the copied jar, otherwise Eclipse will get confused.
<property name="lib.javalib.project.dir" location="${basedir}/../JavaLib" />
<target name="-pre-build">
<subant buildpath="${lib.javalib.project.dir}" target="package" failonerror="true" />
<copy todir="${basedir}/libs" failonerror="true" verbose="true">
<fileset dir="${lib.javalib.project.dir}/target">
<filename name="javalib*.jar"/>
</fileset>
</copy>
</target>
<target name="-post-package">
<delete verbose="true">
<fileset dir="${basedir}/libs" includes="javalib*.jar" />
</delete>
</target>
This solution is far from satisfying, but it gets the job done.
You will find a similar question and answer there : Android Ant Include Java Library projects

I'll answer my own question: the only way to do this properly is to not use Ant.
You need a proper dependency management system. Maven is your only real choice here.
You need a build system that supports Maven. I currently use Maven again for this, because at the time it was the only mature build tool that also supported Maven dependency management -- now (albeit for Android Library Projects, since the format for these is not yet final) Gradle should be your build tool of choice.

I changed my build.xml to run the java project's ant file and then copy the jar to the libs folder:
<target name="-pre-compile">
<ant antfile="build.xml" dir="dependencies/JavaUtils" target="clean"/>
<ant antfile="build.xml" dir="dependencies/JavaUtils"/>
<copy todir="${jar.libs.dir}" failonerror="true" file="dependencies/JavaUtils/dist/Java-utils.jar"/>
<sleep seconds="3"/> <!-- Delay for the file to be recognized after the copy -->
</target>
How this helped someone.
BTW, I started reading about Gradle's dependency/build/whatever system and got the creeps from it. Ahhh, what a relief to get back to ant...

Related

Is there a single JAR somewhere for google-cloud-translate to compile with ANT vs. dealing with 40+ separate JARs?

Working with a client who still lives in the ant build environment world (on a Windows box). Want to use google-cloud-translate library in a Java program but if I include all the dependencies of google-cloud-translate that's over 40 jars with everything from guava to threetenbp to joda-time to google-cloud-core and more if I include all the dependencies of the dependencies and the optional ones. Is there an easy way to package up all the dependencies into a single JAR so I only need the one jar file referenced in the build.xml?
If you absolutely need to use Ant, there's a pretty simple option for this, although it uses a package that is no longer maintained: http://maven.apache.org/ant-tasks/index.html
With the Maven Ant Tasks, you can define an artifact in your build with the <artifact:dependencies> task, and that artifact will be resolved to your local repo along with all of its own dependencies. You can also give it a filesetId so you can easily manipulate the files after that point:
<project xmlns:artifact="antlib:org.apache.maven.artifact.ant">
<typedef
classpath="lib/maven-ant-tasks.jar"
resource="org/apache/maven/artifact/ant/antlib.xml"
uri="antlib:org.apache.maven.artifact.ant"
/>
<target name="resolve-google-cloud-translate-artifacts">
<artifact:dependencies filesetId="google-cloud-translate">
<dependency artifactId="google-cloud-translate" groupId="com.google.cloud" version="1.38.0" />
<remoteRepository id="central" url="https://repo.maven.apache.org/maven2/" />
</artifact:dependencies>
<delete dir="google-cloud-translate.libs" />
<mkdir dir="google-cloud-translate.libs" />
<copy todir="google-cloud-translate.libs">
<fileset refid="google-cloud-translate" />
<flattenmapper />
</copy>
</target>
</project>
Note the artifact: namespace definition in the project element. The Maven tasks won't work without it.

Java Ant Job how to ship Log4j jar with my jar

Just trying to upgrade some old stuff and part of that I need to bundle my custom jar which uses Log4j. I did add the following for my <javac> task which compiles successfully.
<path id="my.classpath">
<fileset dir="${mainpath}">
<include name="**/*log4j*.jar"/>
</fileset>
</path>
<javac srcdir="src/java" destdir="build/filez/java" debug="on" deprecation="no"
includes="my/instruments/**/*, org/apache/log4j/**/*">
<classpath refid="my.classpath"/>
</javac>
However, In my <jar> job I cannot see any log4j dependency packed with my custom jar. This might be a silly question, but how do ensure that my custom-jar does not fail when called from another application since the dependency isn't packed? Will it be okay as long as log4j has been loaded by classloader in the target application?
Additionally, do I need to add something in my Manifest for this?
I cannot use Maven (yes I know) for a little while, so cannot solve this problem with maven
You can use One-JAR to package your code along with it's dependencies into one big executable JAR.
It can be used either as a standalone tool from the command line or as a task defined in build.xml.
<!-- Construct the One-JAR file -->
<one-jar destfile="hello.jar" manifest="hello.mf">
<main>
<!-- Construct main.jar from classes and source code -->
<fileset dir="${classes.dir}/src"/>
</main>
<lib>
<fileset file="${build.dir}/lib.jar" />
</lib>
</one-jar>

Javac inexplicably failing on Hudson

Our application is built my Hudson from Ant scripts. In my latest work I've recently included Maven. Now Hudson's build process fails when it reaches the compilation task without any explanation.
Hudson build:
[echo] Using Maven Repo at ../.maven/repo/
[javac] Compiling 134 source files to C:\Users\administrator1\.hudson\jobs\SAP_RC\workspace\current\classes
BUILD FAILED
C:\Users\administrator1\.hudson\jobs\SAP_RC\workspace\current\build.xml:68: Error running C:\Program Files (x86)\Java\jdk1.8.0_66\bin\javac.exe compiler
Ant script:
<javac classpathref="lib" destdir="${classesDir}" debug="true" debuglevel="lines,vars,source" verbose="true" fork="true" nowarn="true" memoryMaximumSize="320m" srcdir="${srcDir}" includeantruntime="false" />
I specifically included the Maven repo into the classpath, and that's when it fails inexplicably. When I remove the Maven repo the build throws a compilation error complaining that it can't find Maven dependencies. This makes me suspect that I'm hitting some classpath length limit.
I did it this way because I'm not sure what is the correct way to include Maven dependencies into the classpath. If there is a better way please tell me and I'll open a new question specifically for that.
It seems as though my wildcard in my fileset was the culprit.
<path id="lib">
<fileset dir="${env.maven_repo}">
<include name="*/**"/>
</fileset>
</path>
I changed the ** to *.jar and the build process is no longer (inexplicably) failing.
<path id="lib">
<fileset dir="${env.maven_repo}">
<include name="*/*.jar"/>
</fileset>
</path>

Java - How to create JavaDocs in Apache Ivy

I know how to create javadocs for my source file in Apache Ant Build.
<target name="doc" description="generate documentation">
<delete dir="${doc.dir}"/>
<mkdir dir="${doc.dir}"/>
<javadoc sourcepath="${source.dir}" destdir="${doc.dir}"/>
</target>
But I don't know how to create them in Apache Ivy.
Could some one show me a sample example ?
Apache Ivy is a dependency management library for use with (not a replacement for) Apache Ant. Therefore, you will use the same <javadoc> task as always.
Apache Ivy is a dependency manager that works with Ant (a build manager). Apache Ivy is usually (or possible always?) used with Ant to handle builds. Since javadoc creation is a build task not a dependency task, it wouldn't make sense to generate javadocs using Ivy.
It looks like you're going around in a circle here. Ivy works with Ant. You still have a build.xml file that you use for your builds. The ivy.xml file simply contains a list of the third-party jars your project needs in order to build. Thus, the direct answer to your question would be:
Put the following in your build.xml:
<target name="doc" description="generate documentation">
<delete dir="${doc.dir}"/>
<mkdir dir="${doc.dir}"/>
<javadoc sourcepath="${source.dir}" destdir="${doc.dir}"/>
</target>
When you use Ivy, you still use Ant. And, you still have a build.xml file. And, you still write compose your build with various Ant tasks.
Download this project. It's a simple build that contains three class files and a build.xml file. You will notice there's a jar directory with the following two jars:
commons-logging-1.1.1.jar
spring.jar
If you look at lines 36 to 40 of the build.xml file, the project is creating a compile classpath like this:
<path id="java">
<fileset file="jar/spring.jar"/>
<fileset file="jar/commons-logging-1.1.1.jar"/>
</path>
So, when he compiles, he does this:
<javac destdir="bin">
<src path="${src}"/>
<classpath refid="java"/>
</javac>
Now, let's look at how this may change with Ivy. In Ivy, I create a ivy.xml file that contains a description of what jars I need. However, I only have to specify classes I use directly. In this case, I only need the spring.jar. Here's my ivy.xml:
<ivy-module version="1.0>
<info organisation="com.seantheflexguy"
name="ContextExample"
revision="1.0"/>
<configurations>
<conf="default" visibility="public"/>
<conf="compile" visibility="public"/>
</configurations>
<dependencies>
<dependency org="org.springframework" name="spring"
rev="2.0.4" conf="compile->default"/>
</dependencies>
</ivy-module>
Now, instead, of using the jars in the jar directory, I'll have Ivy construct the classpath:
<ivy:resolve/>
<ivy:cachepath pathid="java"/>
<javac destdir="bin">
<src path="${src}"/>
<classpath refid="java"/>
</javac>
Notice instead of using the <path> task to create a classpath, I use two Ant tasks that Ivy uses. The <ivy:resolve/> looks at my ivy.xml and resolves my dependencies on the jars I request. These jars will be downloaded into my $HOME/.ivy2/cache directory.
The <ivy:cachepath> task creates a classpath I'm calling the classpath java because that's what it was previously called.
With those two Ivy tasks, I've created a classpath that I can use with the <javac> task. In fact, I'm not even bothering to change the <javac> task.
So, in Ivy:
I still need my build.xml. It's how I define the various build tasks I need to do. In fact, Ivy defines even more Ant tasks I need in my build.xml file.
The ivy.xml file simply defines my jar dependencies. When I implement Ivy in this project, I can delete the jar directory.
Does this help you understand how Ivy works?

Eclipse: Ant script to export User Library/Libraries for project

I am new to Java programming. I initially started with NetBeans but have moved to Eclipse given the advice from a friend.
In NetBeans, a pre-written ant build script for the project would generate a Project.jar file and place all required libraries/jars in a lib/ folder.
However, in Eclipse it appears that I need to write my own ant script. I have written a few lines to generate the jar file:
<target name="compile">
<mkdir dir="${build.dir}"/>
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="jars" debug="on"/>
</target>
How do I write a command to copy all of the jars in my User Library to a ${build.dir}/lib/ folder?
Thanks.
Use the copy task
like so, with the appropriate include or exclude pattern
<copy todir="${build.dir}/lib/">
<fileset dir="src_dir">
<include name="**/*.jar"/>
</fileset>
</copy>
<copy todir="${build.dir}/lib/">
<fileset dir="src_dir" excludes="**/*.java"/>
</copy>
If you are new to Java take the chance to have a look at maven. It is a build tool like ant with a lot of predefined 'goals' and a fully developed dependency (to other libraries) handling. You will find a eclipse plugin which will be very useful.
Maven projects have a special directory layout which is kind of best practise and helpful for beginners. If you work on a maven project you can just use the command
mvn dependency:copy-dependencies
as a console command (or eclipse run configuration) to copy your project dependencies (libraries) to the <project>\target\dependency directory.
I recommend to use ant4eclipse library for ant based eclipse projects. When you use it, you can access eclipse workspace/project settings, and can iterate tought eclipse project class path in ant.
See the example code bellow:
<path id="ant.classpath">
<fileset dir="${lib.dir}/ant4eclipse">
<include name="*.jar" />
</fileset>
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<taskdef resource="net/sf/ant4eclipse/antlib.xml" />
<targetPlatform
<target name="copy_jars">
<getEclipseClasspath workspace="${basedir}/.."
projectname="TestProject"
targetPlatformLocation="c:/eclipse"
property="classpath"
relative="false"
runtime="true"
pathseparator="#" />
<!-- iterate over all classpath entries -->
<foreach list="${classpath}" delimiter="#"
target="copy_jar_file" param="classpath.entry" />
</target>
<target name="copy_jar_file">
<!-- check if current is a .jar-file ... -->
<if>
<isfileselected file="${classpath.entry}">
<filename name="**/*.jar" />
</isfileselected>
<then>
<!-- copy the jar file to a destination directory -->
<copy file="${classpath.entry}" tofile="${dest.dir}"/>
</then>
</if>
</target>
If you would like to use user libraries, you can define it by userlibraries command.

Categories

Resources