So I have a basic Java program I am trying to package as an RPM using Ant's rpm task. I am running this through Cygwin. My problem is when I run the ant build script, it seems to be trying to use the rpm command instead of the needed rpmbuild command. From what I have read, the ant rpm task should use rpmbuild unless it is not found, in which case it then uses rpm. I know for a fact both are installed properly, as I can manually create RPMs using the command line just fine. I am not sure if there is something I need to change in the build script or the spec file to get this working, as I am new to this sort of thing. Or if this is a Cygwin dependency issue?
Proof of rpm and rpmbuild install in Cygwin:
$ which rpm
/usr/bin/rpm
and
$ which rpmbuild
/usr/bin/rpmbuild
Here is my build.xml file:
<project name="SimpleJavaApp" default="all">
<property name="src" value="${basedir}/src" />
<property name="output" value="${basedir}/output" />
<property name="classes" value="${output}/classes" />
<property name="jars" value="${output}/jars" />
<property name="build.dir" value="${basedir}/build"/>
<target name="clean">
<delete dir="${output}" />
</target>
<target name="compile">
<mkdir dir="${classes}" />
<javac srcdir="${src}" destdir="${classes}" />
</target>
<target name="jar">
<mkdir dir="${jars}" />
<jar basedir="${classes}" destfile="${jars}/app.jar">
<manifest>
<attribute name="Main-Class" value="Main"/>
</manifest>
</jar>
</target>
<!-- Create directories -->
<mkdir dir="${build.dir}/BUILD"/>
<mkdir dir="${build.dir}/SOURCES"/>
<mkdir dir="${build.dir}/RPMS/noarch"/>
<mkdir dir="${build.dir}/SPECS"/>
<!-- copy spec files -->
<copy todir="${build.dir}/SPECS" preservelastmodified="true" failonerror="true">
<fileset dir="${basedir}" includes="*.spec"/>
</copy>
<target name="rpm" description="Compile single binary rpm by spec file">
<rpm
specFile="project.spec"
topDir="build"
cleanBuildDir="false"
removeSpec="false"
removeSource="false"
command = "ba"
failOnError="false"
/>
</target>
<target name="all" depends="clean, compile, jar, rpm" />
And here is my spec file, pretty simple:
Summary: An RPM Spec example
Name: Application-Example
Version: 1.0
Release: 1
Group: Applications/Sample
URL: http://www.mycompany.com
Packager: Name <name#name.com>
BuildArch: noarch
%description
This is a sample SPEC file for the RPM project
demonstrating how to build, package, install(deploy)
%files
And finally, here is the output of the ant build (only the rpm portion):
rpm:
[rpm] Building the RPM based on the project.spec file
[rpm] RPM version 4.1
[rpm] Copyright (C) 1998-2002 - Red Hat, Inc.
[rpm] This program may be freely redistributed under the terms of the GNU GPL
[rpm]
[rpm] Usage: rpm [-a|--all] [-f|--file] [-g|--group] [-p|--package] [--specfile]
[rpm] [--whatrequires] [--whatprovides] [-c|--configfiles] [-d|--docfiles]
[rpm] [--dump] [-l|--list] [--queryformat=QUERYFORMAT] [-s|--state]
[rpm] [--nomd5] [--nofiles] [--nodeps] [--noscript] [--addsign]
[rpm] [-K|--checksig] [--import] [--resign] [--nodigest] [--nosignature]
[rpm] [--initdb] [--rebuilddb] [--allfiles] [--allmatches] [--badreloc]
[rpm] [-e|--erase <package>+] [--excludedocs] [--excludepath=<path>]
[rpm] [--force] [-F|--freshen <packagefile>+] [-h|--hash] [--ignorearch]
[rpm] [--ignoreos] [--ignoresize] [-i|--install] [--justdb] [--nodeps]
[rpm] [--nomd5] [--noorder] [--nosuggest] [--noscripts] [--notriggers]
[rpm] [--oldpackage] [--percent] [--prefix=<dir>] [--relocate=<old>=<new>]
[rpm] [--repackage] [--replacefiles] [--replacepkgs] [--test]
[rpm] [-U|--upgrade <packagefile>+] [-D|--define 'MACRO EXPR']
[rpm] [-E|--eval 'EXPR'] [--macros=<FILE:...>] [--nodigest] [--nosignature]
[rpm] [--rcfile=<FILE:...>] [-r|--root ROOT] [--querytags] [--showrc]
[rpm] [--quiet] [-v|--verbose] [--version] [-?|--help] [--usage]
[rpm] [--scripts] [--setperms] [--setugids] [--conflicts] [--obsoletes]
[rpm] [--provides] [--requires] [--info] [--changelog] [--triggers]
[rpm] [--last] [--filesbypkg] [--redhatprovides] [--redhatrequires]
[rpm] [--buildpolicy=<policy>] [--with=<option>] [--without=<option>]
all:
BUILD SUCCESSFUL
Total time: 1 second
if you'd like to see what is happening in ant run, you should understand the sources of the task you're interested in. Not sure what ant version you have but the latest sources can be seen here: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java?view=markup
The method of your interest seems to be:
/**
* Checks whether <code>rpmbuild</code> is on the PATH and returns
* the absolute path to it - falls back to <code>rpm</code>
* otherwise.
*
* #return the command used to build RPM's
*
* #since 1.6
*/
protected String guessRpmBuildCommand() {
Map/*<String, String>*/ env = Execute.getEnvironmentVariables();
String path = (String) env.get(PATH1);
if (path == null) {
path = (String) env.get(PATH2);
if (path == null) {
path = (String) env.get(PATH3);
}
}
if (path != null) {
Path p = new Path(getProject(), path);
String[] pElements = p.list();
for (int i = 0; i < pElements.length; i++) {
File f = new File(pElements[i],
"rpmbuild"
+ (Os.isFamily("dos") ? ".exe" : ""));
if (f.canRead()) {
return f.getAbsolutePath();
}
}
}
return "rpm";
}
the reffered constants are:
private static final String PATH1 = "PATH";
private static final String PATH2 = "Path";
private static final String PATH3 = "path";
So as you mentioned, it basically just tries to find the rpmbuild on your path. If it can't be found it goes for rpm.
The thing is, that I don't have cygwin installed (as I'm a linux user), but let me propose, what I'd try.
try to run ant with -verbose option (as suggested here: http://ant.apache.org/problems.html) and see if it tells you something useful
if not, try to download ant sources (of the version you use), import them to your favourite java ide and do the remote debugging to see what's happening. I'd put breakpoint somewhere around line 333 to see if rpmbuild has been found. If you're not sure how to setup remote debugging for ant, see: http://www.vitorrodrigues.com/blog/2009/07/10/debugging-ant-tasks-in-eclipse/
I don't know how executables look in cygwin, but the question is if they have .exe extension. And another important question is if Os.isFamily("dos") will be evaluated to true in cygwin.
have fun :)
Related
I have ant installed in my RedHat 7 machine. I have a project which has ant libraries inside lib folder. That lib folder is present inside installer. There is a jar file known as xmltask.jar inside lib folder. I had defined
<property name="dependencyfinder.home" value="."/>
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask">
<classpath location="${dependencyfinder.home}/lib/xmltask.jar"/>
</taskdef>
In that line i am getting
BUILD FAILED
installer\build.xml:37: taskdef class com.oopsconsultancy.xmltask.ant.XmlTask cannot be found
using the classloader AntClassLoader[]
Total time: 296 milliseconds
I am using an install script for executing build.xml which is responsible to set the class path.
The code for the script is as follows:
OLD_DIR=$(pwd)
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
cd ${SCRIPT_DIR}
ANT_HOME=$SCRIPT_DIR/ant
ANT_LIB=${ANT_HOME}/lib
${ANT_HOME}/bin/ant -q -e
cd ${OLD_DIR}
exit 0
I have an ant file called jarPLCExample.xml that takes some class files and produces a jar file. What would the <jar> tag section of this file look like in sbt?
<project name="jar_myplc" default="jar_myplc" basedir=".">
<property file="../resources/v2.properties"/>
<property name="dist.dir" value="C://where_jar_files_go/lib"/>
<property name="dist.file" value="${dist.dir}/PLC.jar"/>
<target name="jar_myplc">
<tstamp>
<format property="TODAY" pattern="dd/MM/yyyy hh:mm aa" locale="au"/>
</tstamp>
<delete file="${dist.file}" quiet="true"/>
<jar destfile="${dist.file}">
<fileset dir="${v2.out.root}" includes="com/companyname/server/applic/**/*.class"/>
<fileset dir="${v2.out.root}" includes="com/companyname/common/utils/SeaDef*.class"/>
</jar>
<copy file="${dist.file}" todir="C:/deploy"/>
</target>
sbt-assembly no good for this as it seems you can exclude and include jars, but not source file packages and source file names as needs to be done here.
Obviously important to 'go with the flow': I expect sbt will want to compile from source, so no need to explicitly use .class files as the ant task above does.
I already have a build.sbt in the base directory, and it would be sensible to call this file jarPLCExample.sbt, but I don't know how to get sbt to load one particular file. So instead I will have two projects in the one file and manually set the current project by changing their order. (As they both have the same key the second one seems to overwrite the first one - the projects command will always show only one project).
This answer has two shortcomings. It only includes the applic directory rather than all directories (recursively) below applic. Also it will pick up all SeaDef*.class, no matter which directories they are in.
def filter3(file: File, greatGrandParent:String, grandParent:String, parent:String, excludes:List[String]):Boolean = {
file.getParentFile.getName == parent &&
file.getParentFile.getParentFile.getName == grandParent &&
file.getParentFile.getParentFile.getParentFile.getName == greatGrandParent &&
!excludes.exists( _ == file.getName)
}
/*
* <fileset dir="${v2.out.root}" includes="com/companyname/server/applic/**/*.class"/>
* <fileset dir="${v2.out.root}" includes="com/companyname/common/utils/SeaDef*.class"/>
*/
lazy val jarPLCExample = project.in(file(".")).
settings(commonSettings: _*).
settings(
includeFilter in (Compile, unmanagedSources) :=
new SimpleFileFilter(file => filter3(file, "companyname", "server", "applic", List())) ||
new SimpleFileFilter(file => file.getName.startsWith("SeaDef"))
)
build.xml
<?xml version="1.0"?>
<project default="main" basedir=".">
<echo message="pulling in property files" />
<property file="axis_bujava.properties" />
<echo message="calling the RPM Build Ant" />
<target name="main">
<rpm specfile="example.spec" topdir="${basedir}" command="-bs" />
</target>
</project>
example.spec
Summary: xxx
Name: cdplayer
Version: 1.0
Release: 1
Copyright: xxx
Group: Applications/Sound
Source: xxx.tgz
URL: http://xxx.html
Distribution: xxxx
Vendor:xxx.
Packager: xxx
%description
xxxx
%build
make
%install
make install
output:
Buildfile: /home/user1/workspace/antdemo/build.xml
[echo] pulling in property files
[echo] calling the RPM Build Ant
main:
[rpm] Building the RPM based on the example.spec file
[rpm] -bs: unknown option
[rpm] 'rpm' failed with exit code 1
BUILD SUCCESSFUL
Total time: 848 milliseconds
I had this issue too. In my case the OS did not have the 'rpmbuild' command installed, so the ant task was calling 'rpm' instead as Aaron suggested.
While I'm not sure what "-bs" option is, you might try changing it to "-bb", which is the default. My own builds, plus a few I've seen, usually use -bb (http://richardfriedman.blogspot.com/2007/02/rpm-java-and-frustration.html)
Also see:
http://ant.apache.org/manual/Tasks/rpm.html
I am having trouble getting my Ant script (for BlackBerry build) to run the preverify.exe command & pass the correct parameters to it.
In the command prompt (Windows 7), this works 100% - the parameters as given work properly:
preverify -verbose -classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar -d build\classes\preverified build\classes\preverified build\classes\unverified
I tried to put this into my Ant script using the following target - trying to use the same parameters:
<target name="preverify">
<mkdir dir="${dest.dir}/classes/preverified" />
<exec executable="${jde.home}/bin/preverify">
<arg value="-verbose" />
<arg value="-classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar" />
<arg value="-d build\classes\preverified" />
<arg value="build\classes\unverified" />
</exec>
</target>
This does not work. I get the following error:
Illegal option
-classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar
this classpath was perfectly acceptable from the command line (often java commands accept JAR files as directories, since they are basically ZIP files).
How can I get Ant to send the correct parameters to this command, as in the command line version? There must be something about exec that I'm missing?
Here is the full Ant output from running this target in verbose mode, if it helps:
Apache Ant(TM) version 1.8.2 compiled on December 20 2010
Trying the default build file: build.xml
Buildfile: C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\build.xml
Detected Java version: 1.6 in: C:\Java\jdk1.6.0_24\jre
Detected OS: Windows 7
parsing buildfile C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\build.xml with URI = file:/C:/development/ant/test_using_javac_jar_preverify_then_rapc/Cobi/build.xml
Project base dir set to: C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi
parsing buildfile jar:file:/C:/development/tools/apache-ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml with URI = jar:file:/C:/development/tools/apache-ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml from a zip file
Importing file C:\development\ant\common\constants.xml from C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\build.xml
Overriding previous definition of reference to ant.projectHelper
parsing buildfile C:\development\ant\common\constants.xml with URI = file:/C:/development/ant/common/constants.xml
parsing buildfile jar:file:/C:/development/tools/bb-ant-tools/bb-ant-tools.jar!/bb-ant-defs.xml with URI = jar:file:/C:/development/tools/bb-ant-tools/bb-ant-tools.jar!/bb-ant-defs.xml from a zip file
Overriding previous definition of reference to ant.projectHelper
[property] Loading C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\project.properties
[property] Loading C:\development\ant\common\jde5.0.properties
[property] Loading C:\development\ant\common\common.properties
[pathconvert] Set property net_rim_api.jar.dos = C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar
Build sequence for target(s) `preverify' is [preverify]
Complete build sequence is [preverify, javac, build, sign, clean, ]
preverify:
[mkdir] Skipping C:\development\ant\test_using_javac_jar_preverify_then_rapc\Cobi\build\classes\preverified because it already exists.
[exec] Current OS is Windows 7
[exec] Executing 'C:\development\tools\bb-jde\jde5.0\components\bin\preverify' with arguments:
[exec] '-verbose'
[exec] '-classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar'
[exec] '-d build\classes\preverified'
[exec] 'build\classes\unverified'
[exec]
[exec] The ' characters around the executable and arguments are
[exec] not part of the command.
[exec] preverify: Illegal option -classpath C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar
[exec]
[exec] Usage: preverify [options] classnames|dirnames ...
[exec]
[exec] where options include:
[exec] -classpath <directories separated by ';'>
[exec] Directories in which to look for classes
[exec] -d <directory> Directory in which output is written (default is ./output/)
[exec] -cldc1.0 Checks for existence of language features prohibited
[exec] by CLDC 1.0 (native methods, floating point and finalizers)
[exec] -nofinalize No finalizers allowed
[exec] -nonative No native methods allowed
[exec] -nofp No floating point operations allowed
[exec] #<filename> Read command line arguments from a text file
[exec] Command line arguments must all be on a single line
[exec] Directory names must be enclosed in double quotes (")
[exec]
[exec] Result: 1
BUILD SUCCESSFUL
Total time: 1 second
This doesn't look like an ANT issue. The error message is being returned by the preverify command, proving that ANT is executing it...
I don't understand what this command is supposed to be doing, however the usage message gives a hint as to the root cause:
[exec] Usage: preverify [options] classnames|dirnames ...
[exec]
[exec] where options include:
[exec] -classpath <directories separated by ';'>
[exec] Directories in which to look for classes
You haven't specified a list of directories as the "classpath" parameter.... You've supplied a jar file. Is the command able support jar files?
The way you are passing the parameters is incorrect. The space between the -classpath tag, and the JAR name is not allowed.
You must break that line (and the -d below it) onto 2 lines. This works:
<exec executable="${jde.home}/bin/preverify">
<arg value="-verbose" />
<!-- classpath to the RIM api -->
<arg value="-classpath" />
<arg value="C:\development\tools\bb-jde\jde5.0\components\lib\net_rim_api.jar" />
<!-- destination folder -->
<arg value="-d" />
<arg value="build\classes\preverified" />
<!-- source folder -->
<arg value="build\classes\unverified" />
</exec>
I solved this problem by including the jdk\bin directory path in environment variable PATH.
When you define an extension-point in an Ant build file you can have it conditional by using the if or unless attribute. On a target the if/unless prevent it's tasks from being run. But an extension-point doesn't have any tasks to conditionally run, so what does the condition do? My thought (which proved to be incorrect in Ant 1.8.0) is it would prevent any tasks that extend the extension-point from being run. Here is an example build script showing the problem:
<project name = "ext-test"
default = "main">
<property name = "do.it" value = "false" />
<extension-point name = "init"/>
<extension-point name = "doit" depends = "init" if = "${do.it}" />
<target name = "extend-init" extensionOf = "init">
<echo message = "Doing extend-init." />
</target>
<target name = "extend-doit" extensionOf = "doit">
<echo message = "Do It! (${do.it})" />
</target>
<target name = "main" depends = "doit">
<echo message = "Doing main." />
</target>
</project>
Using the command:
ant -v
Relults in:
Apache Ant version 1.8.0 compiled on February 1 2010
Trying the default build file: build.xml
Buildfile: /Users/bob/build.xml
Detected Java version: 1.6 in: /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home
Detected OS: Mac OS X
parsing buildfile /Users/bob/build.xml with URI = file:/Users/bob/build.xml
Project base dir set to: /Users/bob
parsing buildfile jar:file:/Users/bob/Documents/Development/3P-Tools/apache-ant-1.8.0/lib/ant.jar!/org/apache/tools/ant/antlib.xml with URI = jar:file:/Users/bob/Documents/Development/3P-Tools/apache-ant-1.8.0/lib/ant.jar!/org/apache/tools/ant/antlib.xml from a zip file
Build sequence for target(s) `main' is [extend-init, init, extend-doit, doit, main]
Complete build sequence is [extend-init, init, extend-doit, doit, main, ]
extend-init:
[echo] Doing extend-init.
init:
extend-doit:
[echo] Do It! (false)
doit:
Skipped because property 'false' not set.
main:
[echo] Doing main.
BUILD SUCCESSFUL
Total time: 0 seconds
You will notice the target extend-doit is executed but the extention-point itself is skipped. Since an extention-point doesn't have any tasks exactly what has been skipped? Any targets that depend on the extention-point still get executed since a skipped target is a successful target. What is the value of the if/unless attributes on an extention-point?
I'm guessing there is no actual use for them, they probably appear as attributes because extension-point extends target (the associated java classes do).