Configure specific package for generated classes in ADT / ant build - java

I'm developing an application for various customers that use exactly the same code (it just displays a WebView). The only differences are one config file, the icon and the android package name, all generated via a custom ant task.
If I run the ant release target or build the project in eclipse, the generated Java classes (like R) are generated in a package named like the android package. As a result, imports of these classes in my project are invalid, because their package has changed.
Newsnet.java
package ch.newsnet.app;
import ch.newsnet.app.R; // <- cannot be found after build
public class Newsnet extends FragmentActivity {
//...
}
Running my custom ant target will set my android package to ch.customer1.app, wich makes R a class of package ch.customer1.app. But I want it always to be ch.newsnet.app. How can I achieve that in a) the ant build and b) in the eclipse builder? I don' want to setup 20+ projects and maintain their buildfile and resources when I can have all in one code base.

For those who face the same issue, I solved this problem as follows (allthough it's not the best solution, but it worked for me):
I created the ant target moveGeneratedFiles, where I copy the generated package to the correct one, replace the package name and delete the generated one (which will not really work in eclipse because the classes will be generated again).
<target name="moveGeneratedFiles">
<loadproperties>
<file file="assets/customer.properties"/>
</loadproperties>
<copy todir="gen/ch/newsnet/app" overwrite="true">
<fileset dir="gen/ch/${customer.name}/app" />
</copy>
<replace dir="gen/ch/newsnet/app" token="package ch.${customer.name}.app;" value="package ch.newsnet.app;" />
<delete>
<fileset dir="gen/ch/${customer.name}/app" />
</delete>
</target>
In the project properties, I added an ant builder executing this target so the generated classes will be synced after saving.

Related

Java and ProGuard - taskdef class proguard.ant.ProGuardTask cannot be found using the classloader AntClassLoader

I have the pleasure of working on a embeded java program, which was writen 10+ years ago from a third party company. Source and project files were included.
It was imported into Eclipse and ported to a higher java version (17).
Now I'm stuck when trying to build the program. It uses ProGuard. The newest version was added to the project files. Config file proguard.pro was changed to discard rt.jar utilization in favore of the new methods. However, now I'm getting a error message:
BUILD FAILED
C:\mypath\build.xml:16: taskdef class proguard.ant.ProGuardTask cannot be found
using the classloader AntClassLoader[C:\mypath\obf\proguard.jar]
build.xml (original) is as follows:
<target name="obfuscate" description="obfuscate a jar file" depends="jar">
<taskdef name="proguard" classname="proguard.ant.ProGuardTask" classpath="obf/proguard.jar" />
<proguard configuration="obf/proguard.pro" />
</target>
The 'obf' folder is inside the project (sublevel of build.xml). File proguard.jar is inside of it. Anyone haveing any clues why would this error show? No other changes were made beside the listed ones.
So, it turned out that with new versions, the notation is not as it once was.
<taskdef resource="proguard/ant/task.properties" classpath="${proguard.path}/lib/proguard-ant.jar" />

Ignore minor errors using javadoc

I'm trying to generate the documentation, using javadoc, from one or two downloaded jar files (with the source of course, after having extracted everything).
But using javadoc, even in an Ant file, I'm being prevented from generating this because of silly things, specifically "package XXX does not exist" and "cannot find symbol"... I just want javadoc to put the text of these things (external references) in the html docs, but to document all the .java files it finds...
NB for anyone interested this is the download page with the download files (containing source) from which I'm trying to generate the API documentation: http://logback.qos.ch/download.html
Following Mark Rotteveel's help, my Ant build file now looks like this:
<?xml version="1.0" ?>
<project name="document logback core" default="doc">
<target name="doc">
<mkdir dir="javadoc" />
<property name="excludedPackages"
value="org.codehaus.*,javax.mail.*"/>
<javadoc destdir="javadoc" sourcepath="src" packagenames="main.*"
excludepackagenames="${excludedPackages}"
additionalparam="-Xdoclint:none" />
</target>
</project>
... but it still gives errors 1) about packages not being found, including "org.codehaus.[xxx...]" and "javax.mail.[xxx...]" and 2) about symbols not being found (although this may go away if I can solve the missing packages errors).
NB the build is said to be successful, but I get complaints about no source files being found (where there are indeed commented .java files), and no html at all is generated under \javadoc.
later, following Tony Pierce's success in generating these docs
Installed Ant 1.9.6, changed path accordingly, checked to make sure this was the version being used... tried again. Failed again. This was the end of my output:
[javadoc]
D:\Desktop\Downloads\logback-1.1.7.tar\logback-1.1.7\logback-core\src\test\java\ch\qos\logback\core\appender\ConsoleAppenderTest.java:32:
error: package org.junit does not exist [javadoc] import static
org.junit.Assert.assertEquals; [javadoc]_______________________^
[javadoc] javadoc: error - No public or protected classes found to
document. [javadoc] 1 error [javadoc] 100 warnings
BUILD SUCCESSFUL Total time: 2 seconds
It does create the javadoc folder... but this is empty.
NB about the above "package does not exist" error (there were many others): this one is particularly mystifying as I thought Ant somehow included junit by default (NB I am a complete newbie at Ant, just working through "Ant in Action").
But... with the Ant javac task you can set includeAntRuntime="true" ... according to this book that makes Ant's own junit.jar be included. Unfortunately the javadoc task doesn't support this attribute.
later still
My thinking was a bit muddled on this, to be honest: the simplest way I have found to compile javadocs from third-party source jars is just by extracting and then using the command line, typically:
javadoc -d docs -Xmaxwarns 10 -Xmaxerrs 10 -Xdoclint:none -sourcepath
. -subpackages ch.qos.logback.core
... as for javadoc for one's own code this doesn't seem to be a problem in Gradle (I was only glimpsing at Ant, aware that the future is Gradle... and it's not particularly difficult to get to grips with the basics).
NB If you install the Gradle STS plugin for Eclipse, and then create a new project using Gradle STS wizard your build file contains the line
apply plugin: 'eclipse'
... one of the effects of which is that by default the source as well as the executables for all your third-party dependencies will be downloaded under GRADLE_HOME during the build. Pretty good!
Java 8 introduced doclint which will treat certain problems as an error and not produce the documentation. It is possible to disable this by specifying the commandline option -Xdoclint:none.
See also: Turning off doclint in JDK 8 Javadoc
Eg in Ant you would need to do add a additionalparam="-Xdoclint:none" attribute to the javadoc task. A (slightly modified) example from Jaybird:
<target name="javadocs" depends="init,set-driver-sources">
<mkdir dir="${build.docs}"/>
<javadoc destdir="${build.docs}"
author="true"
version="true"
windowtitle="${Name} API"
doctitle="${Name}"
extdirs="${module.thirdparty}"
additionalparam="-Xdoclint:none"
excludepackagenames="${excludedPackages}"
bottom="Copyright © 2001-2015 Jaybird (Firebird JDBC/JCA) team. All rights reserved.">
<arg line="${java.module.arg}"/>
<classpath refid="javac.driver.classpath"/>
<sourcepath>
<pathelement path="${source.java}"/>
<pathelement path="${source.jna-client}"/>
</sourcepath>
<sourcepath refid="source.java.openoffice"/>
<sourcepath refid="source.java.additional"/>
<link href="http://docs.oracle.com/javase/7/docs/api/"/>
</javadoc>
</target>
Compile Errors With Custom Doclet with Java 9 or later
The -Xdoclint:none is an option of the standard doclet which will not work for custom doclets.
If you have a custom doclet and don't care about compilation errors, you can pass the --ignore-source-errors option either to the javadoc command line tool or to javax.tools.DocumentationTool.getTask(...) if you invoke your doclet programmatically.
The --ignore-source-errors option is not documented. Maybe because it might be removed in future. The clean way is to add all required libraries to the classpath (via the -classpath option to actually resolve the compilation errors).
I simplified your build file a bit and built the javadoc successfully. Here's what I did:
Downloaded the logback zip
Expanded the sources jars inside into a src directory
Ran ant 1.9.6 under java 8 with this:
<?xml version="1.0" ?>
<project name="document logback core" default="doc">
<target name="doc">
<mkdir dir="javadoc" />
<javadoc destdir="javadoc" sourcepath="src"
additionalparam="-Xdoclint:none" />
</target>
</project>
It produced a lot of warnings, but created a javadoc directory filled with html.
I removed excludepackagenames and dropped the packagenames element. In any case, packagenames="main.*" prevents the javadoc generation because the only root packages in the jar are ch and org.

Building either a Swing and Android app from the same code base using Ant

Based on suggestions from my previous question on programmers.SE, I have split my current project into three subdirectories (swing, common, and android) and created separate Ant scripts in each one. Now I easily created NetBeans projects in the swing and common and was able to set the proper dependencies to compile the Swing app. Then when I go to use classes from the "common" project, I realize that I need to have another Ant script for the Android build process.
So now I have four Ant scripts used to build different parts of my project, along with separate src, test, and other supporting directories for each project. The first problem I encountered is that both NetBeans and the ant script for my "android" project want to use "build.xml" in my "common" project for various build tasks, some of which have name clashes. I decided I want to consolidate all of these projects back into one directory with src, test, etc. subdirectories. The source code is already organized into separate packages for each of the projects and I thought this would make it simpler since I can have a single Ant build script with separate tragets for the Swing and Android builds.
Now the problem I am running into is that when I try to build the "android" project, it wants to build all the Swing classes as well. This brings up a lot of compiler errors. I have even modified the <javac> task in an attempt to exclude the bbct.swing package hierarchy from compileing:
<javac encoding="${java.encoding}"
source="${java.source}" target="${java.target}"
debug="true" extdirs="" includeantruntime="false"
destdir="${out.classes.absolute.dir}"
bootclasspathref="project.target.class.path"
verbose="${verbose}"
classpathref="project.javac.classpath"
fork="${need.javac.fork}"
excludes="${source.dir}/bbct/swing/**"> <------- here
<src path="${source.absolute.dir}" />
<src path="${gen.absolute.dir}" />
<compilerarg line="${java.compilerargs}" />
</javac>
Ant still insists on compiling my classes which use Swing, though.
So I have two questions:
What is the best way to organize this project? Would you suggest one of the two that I have tried or something else entirely?
If I stick with my most recent solution, how do I make javac ignore the Swing-based source files in my project?
Between How to exclude a source package using javac in Ant? and How can I exclude sources in a javac task in ant?, I found a solution using an <exclude> elements, rather than the excludes attribute. Here is the relevant <javac> task:
<javac encoding="${java.encoding}"
source="${java.source}" target="${java.target}"
debug="true" extdirs="" includeantruntime="false"
destdir="${out.classes.absolute.dir}"
bootclasspathref="project.target.class.path"
verbose="${verbose}"
classpathref="project.javac.classpath"
fork="${need.javac.fork}">
<src path="${source.absolute.dir}" />
<exclude name="bbct/swing/**" />
<src path="${gen.absolute.dir}" />
<compilerarg line="${java.compilerargs}" />
</javac>
Addendum:
I suspect that the core of this solution lies in using a path relative to the source attribute or the <src> element. This means that an excludes element should work just as well using a relative path. I haven't tested this yet, though.

Android.App.Activity - package does not exist

I got an andorid project files that are supposed to compile correctly.
I installed the latest eclipse and Andriod ADT plugins.
I then imported the project and right clicked build.xml to run as ANT build. but I got erors on some basic code which I am sure is originating from my misconfigured setup.
I also tried to run it using ANT from the command line. both times I got the same type of errors
What is wrong ?
Buildfile: /Users/admin/Downloads/moshe-5/build.xml
init:
process.annotations:
[javac] Compiling 9 source files to /Users/admin/Downloads/moshe-5/build/classes
[javac] /Users/admin/Downloads/moshe-5/src/ti/moshe/CustomAdapter.java:7: package android.app does not exist
[javac] import android.app.Activity;
[javac] ^
[javac] /Users/admin/Downloads/moshe-5/src/ti/moshe/CustomAdapter.java:8: package android.content does not exist
[javac] import android.content.Context;
[javac] ^
[javac] /Users/admin/Downloads/moshe-5/src/ti/moshe/CustomAdapter.java:9: package android.graphics does not exist
[javac] import android.graphics.Color;
In my case, it was due to the problem that I didn't have a default.properties file with the target field in it.
I had to manually create the file and put
target=android-9
Or other Android target version.
If you run
ant -v
with your build command, you'll probably see this line
Property "target" has not been set
and
[property] Unable to find property file: /PATH_TO/default.properties
Those messages are enough hints.
Hope this solves your problem too.
It is not finding the android packages. IN the build step you should include android.jar corresponding to the android version you want to port to.
When you write your compile target, you are overriding the default one given by android_rules.xml located in: C:\Program Files (x86)\Android\android-sdk\platforms\android-8\templates or wherever android_rules.xml is located on your computer.
Like Potter mentioned above it is not finding the android library and other libraries, so please look at android_rules.xml to see how it sets up the proper libraries:
<target name="compile" depends="-resource-src, -aidl"
description="Compiles project's .java files into .class files">
<!-- If android rules are used for a test project, its classpath should include
tested project's location -->
<condition property="extensible.classpath"
value="${tested.project.absolute.dir}/bin/classes" else=".">
<isset property="tested.project.absolute.dir" />
</condition>
<condition property="extensible.libs.classpath"
value="${tested.project.absolute.dir}/libs" else="./libs">
<isset property="tested.project.absolute.dir" />
</condition>
<javac encoding="ascii" target="1.5" debug="true" extdirs=""
destdir="${out.classes.absolute.dir}"
bootclasspathref="android.target.classpath"
verbose="${verbose}" classpath="${extensible.classpath}">
<src path="${source.absolute.dir}" />
<src path="${gen.absolute.dir}" />
<classpath>
<fileset dir="${external.libs.absolute.dir}" includes="*.jar" />
<fileset dir="${extensible.libs.classpath}" includes="*.jar" />
</classpath>
</javac>
</target>
Inside the classpath tags is where android.jar is included. You can add other libraries by adding more filesets
Some other good examples of code for writing the ANT compile target are:
Can't build and run an android test project created using "ant create test-project" when tested project has jars in libs directory <-- this worked for me
http://www.vogella.de/articles/ApacheAnt/article.html
http://www.alittlemadness.com/2010/05/31/setting-up-an-android-project-build/ <-- setting up ANT project
It's most likely not finding Android because you didn't define the sdk.dir property, which tells the build process where to find Android. This property is usually in a local.properties file and is populated when you do:
android update project
as described here:
http://developer.android.com/tools/projects/projects-cmdline.html#UpdatingAProject
Don't bother building using ANT.
Eclipse and the ADT plugin provide excellent tool to save you the trouble.
Simply right click the project, choose run as -> Android application

Javadoc on Android (Eclipse)

I am trying to generate Javadoc html pages for my Android project in Eclipse. I have tried using the -linkoffline argument, as suggested here, as well as using the -classpath argument pointing to my android.jar file. Neither of these worked, as I still get package android.app does not exist (and other) warnings. I have also tried running the javadoc tool from the command line, rather than using Eclipse.
Ideally I would like to have my own generated pages for my classes, with all android.* and java.* classes linking to the online pages. I am using Mac OS 10.6 with Java version 1.6.0_20.
While trying to resolve a similar issue myself, the two main points I've found have been:
To include the android.jar file you're linking to within the classpath attribute of the javadoc Ant task. That means something like the following:
<javadoc ...
classpath="some/local/library.jar;
C:/Android/platforms/android-8/android.jar;
D:/another/library.jar" ... >
To add a link subitem under javadoc task in order to match the online Android Reference URL with a local copy of Android Reference package-list. That means something like the following:
<javadoc ...>
<link offline="true"
href="http://developer.android.com/reference/"
packagelistloc="C:/Android/docs/reference" />
</javadoc>
This was enough for me in order to show Android links within my project Javadoc.
Have you tried using an ant script for the javadocs? Name it javadoc.xml or something other than build.xml - else eclipse will pick it up as the default build script. Run the ant script either from inside eclipse (RMB on file | Run As | Ant Build), or from the console: ant -f <file-name.xml>.
Mine looks something similar to this:
<project basedir="." default="doc" name="metagloss api docs">
<property
name="android-sdk-docs"
value="/home/blackrax/opt/dev/android-sdk-linux_86/docs/reference"/>
<target name="doc" description="api docs - no piwik" depends="clean, delombok">
<javadoc destdir="docs">
<link offline="true"
href="http://d.android.com/reference"
packagelistLoc="${android-sdk-docs}" />
<fileset dir="src" includes="**/*.java" />
</javadoc>
</target>
<!-- more implementation, any remaining targets -->
</project>

Categories