JSP is not getting copied while creating war using Ant - ant

I am using following Ant script to create a war of simple web application.
<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="war">
<path id="compile.classpath">
<fileset dir="WebContent/WEB-INF/lib">
<include name="*.jar" />
</fileset>
</path>
<target name="compile">
<javac destdir="WebContent/WEB-INF/classes" debug="true" srcdir="src">
<classpath refid="compile.classpath" />
</javac>
</target>
<target name="war" depends="compile">
<war destfile="build/myproject.war" webxml="WebContent/WEB-INF/web.xml">
<fileset dir="WebContent">
<include name="**/*.jsp" />
</fileset>
<lib dir="WebContent/WEB-INF/lib" />
<classes dir="WebContent/WEB-INF/classes" />
</war>
</target>
</project>
It's creating the war but when I am opening the war, it's not containing JSP files due to which application is not running. Any idea what is wrong?
Also, right now I am coping war manually in Weblogic. Is there any Ant command which can deploy war?

I don't know exact answer but here is my way of using Ant build.xml for webapps. Give it a try. This works inside Eclipse or run from the command line. Few key points are:
build.xml has reference to compile-time libraries, including servlet-api.jar
dynamic META-INF/MANIFEST.MF
separate targets for compile, jar and war tasks to allow easier per project custom rules
webapp war don't have individual .class files but compiled web-inf/lib/mywebapp.jar library to minimize filesystem noice
you may create web/WEB-INF/classes/ folder and put some .properties file or extreme case "binary provided" class files. They are put inside war package along with other jsp,html,js files.
folder structure is very streamlined, I can use mywebapp/web/ folder directly in Tomcat service during development. Each html, jsp etc changes are reflected at runtime. Compiling jar triggers Tomcat to reload webapp instance.
Use this common folder structure for webapp project.
/mywebapp/ant.bat
/mywebapp/build.xml
/mywebapp/classes/
/mywebapp/src/
/mywebapp/src/META-INF/MANIFEST.MF
/mywebapp/lib/
/mywebapp/web/
/mywebapp/web/WEB-INF/web.xml
/mywebapp/web/WEB-INF/lib/
/mywebapp/web/META-INF/context.xml
mywebapp/build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="mywebapp" default="build" basedir=".">
<property name="name" value="${ant.project.name}" />
<property name="classes" value="./classes" />
<property name="src" value="./src" />
<property name="webdir" value="./web" />
<property name="version" value="1.0"/>
<property environment="env"/>
<path id="libs">
<pathelement location="lib/servlet-api.jar" />
<pathelement location="web/WEB-INF/lib/somelib1.jar" />
<pathelement location="web/WEB-INF/lib/somelib2.jar" />
<pathelement location="web/WEB-INF/lib/gson-2.2.4.jar" />
</path>
<tstamp>
<format property="TODAY" pattern="yyyy-MM-dd HH:mm:ss" />
</tstamp>
<target name="updatemanifest" description="Update manifest">
<buildnumber file="build.num"/>
<copy file="${src}/META-INF/MANIFEST.MF"
todir="${classes}/META-INF/" overwrite="true" preservelastmodified="true"
/>
<manifest file="${classes}/META-INF/MANIFEST.MF" mode="update">
<attribute name="Implementation-Version" value="${version}.${build.number} (${TODAY})" />
<attribute name="Implementation-Title" value="${name}" />
</manifest>
</target>
<target name="clean" description="Clean compiled classes">
<delete dir="${classes}" />
</target>
<target name="compile" depends="clean" description="Compile classes">
<mkdir dir="${classes}"/>
<javac srcdir="${src}" destdir="${classes}" target="1.6" source="1.6" encoding="ISO-8859-1"
debug="true" debuglevel="lines,source"
excludes="" includeantruntime="false" >
<classpath refid="libs" />
<compilerarg value="-Xlint:deprecation" />
</javac>
</target>
<target name="jar" depends="updatemanifest" description="Create a .jar file">
<echo message="Build release: ${release}" />
<jar
manifest="${classes}/META-INF/MANIFEST.MF"
jarfile="${webdir}/WEB-INF/lib/${name}.jar" >
<fileset dir="${classes}">
</fileset>
</jar>
</target>
<target name="war" depends="compile,jar" description="Create a .war file">
<delete file="${name}.war" />
<zip destfile="${name}.war"
basedir="${webdir}"
excludes="
**/CVS*
"
/>
</target>
<target name="build" depends="war" description="Build lib">
</target>
</project>
src/META-INF/MANIFEST.MF
Implementation-Title: myappname
Implementation-Version: 1.0.0 (2010-03-01)
Implementation-Vendor: My Name Ltd.
Implementation-URL: http://www.myname.com
mywebapp/build.bat
call c:\apache-ant-1.7.0\bin\ant.bat build
pause
Build script creates war package and manifest.mf within web-inf/lib/mywebapp.jar is updated to have build number, title and version. Very handy you can use folder content as a template for new webapp projects. Just edit build.xml to have new project name.
Some compile-time dependencies point mywebapp/web-inf/lib folder. Non war-packaged libraries are put to mywebapp/lib/ folder for compile time only. I like keeping each dependency within project version control so thats a reason for this lib folder. You may use *.jar wildcard ant syntax but I explictly list each file for self documentation purpose.
Here is a bonus file to be used in Tomcat during development time. It publishes webapp on Tomcat and any changes in project folder is seen immediately, its very handy for client file changes (html,js,jsp).
this file is a copypaste from mywebapp/web/META-INF/context.xml file but an explicit docBase attribute is added.
It directs Tomcat to use files directly from project folder, no redeployment needed at runtime
Start tomcat and keep it running, you may run several webapp projects withing same Tomcat instance. Sometimes bigger development projects need it.
Remote debugging hook requires some java magic not included here
tomcat/conf/Catalina/localhost/mywebapp.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="C:/mywebapp/web"
debug="0" reloadable="true" crossContext="true" >
<!--
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127.0.0.1" />
-->
<!--
<Valve className="org.apache.catalina.valves.RequestDumperValve"/>
-->
<!-- pooled db connection -->
<Resource name="jdbc/mywebappDB" auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="2" maxWait="20000"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
username="myuserid" password="mypwd"
url="jdbc:sqlserver://mysqlserv1.com:1433;DatabaseName=MyDB;applicationName=mywebapp"
validationQuery="SELECT 1"
/>
<!-- <ResourceLink name="jdbc/mywebappDB" global="jdbc/mywebappDB" type="javax.sql.DataSource" /> -->
<Resource name="jdbc/mywebappDB2" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="20" maxWait="10000"
driverClassName="com.mysql.jdbc.Driver"
username="myuserid" password="mypwd"
url="jdbc:mysql://localhost:3306/myDB2?useUnicode=true&characterEncoding=utf8"
validationQuery="SELECT 1" removeAbandoned="true" removeAbandonedTimeout="300"
/>
</Context>
ps: Ant build system is fine no matter what some people may say. Go with it as you please.

Related

Liquibase gives different results from Ant and the command line

When I run Liquibase from the command line it populates the FILENAME column of DATABASECHANGELOG with the relative paths to the changelog files, as you'd hope. But when I run exactly the same changelog from exactly the same directory, using Ant, it populates the column with the absolute paths.
Among other things this means that the Ant and the command-line versions are not interoperable for me.
But I can't find anyone else having reported this problem, so I'm sure it's something I'm doing; something that I haven't set up correctly. I've seen some suggestions that the root directory of the changelog needs to be on the classpath, so I've included it in the Ant classpath, but it doesn't make any difference.
Here's my Ant build file:
<project name="Database Build" default="build" basedir="." xmlns:liquibase="antlib:liquibase.integration.ant">
<path id="liquibase.lib.path">
<fileset dir="liquibase/lib">
<include name="**/*.jar" />
</fileset>
<fileset dir="liquibase">
<include name="liquibase.jar" />
</fileset>
</path>
<path id="driver.classpath">
<filelist files="${classpath}" />
</path>
<path id="main.classpath">
<pathelement location="." />
<path refid="driver.classpath" />
</path>
<taskdef
resource="liquibase/integration/ant/antlib.xml"
uri="antlib:liquibase.integration.ant">
<classpath refid="liquibase.lib.path" />
</taskdef>
<liquibase:database
id="main-schema"
driver="${driver}"
url="${url}"
user="${username}"
password="${password}"
defaultSchemaName="${defaultSchemaName}"
/>
<target
name="build"
description="Builds the database based on values set in the properties file">
<echo message="Building DB..." />
<liquibase:updateDatabase
databaseref="main-schema"
changelogfile="${changeLogFile}"
classpathref="main.classpath"
logLevel="debug"
>
<!-- Here we're effectively passing the values set as Ant properties in as Liquibase parameters -->
<liquibase:changeLogParameters>
<liquibase:changeLogParameter name="main.schema" value="${defaultSchemaName}" />
<liquibase:changeLogParameter name="tablespace.data" value="${tablespace.data}" />
<liquibase:changeLogParameter name="tablespace.index" value="${tablespace.index}" />
<liquibase:changeLogParameter name="tablespace.long" value="${tablespace.long}" />
</liquibase:changeLogParameters>
</liquibase:updateDatabase>
</target>
<target
name="createSchema"
description="Create a schema on the database"
>
<echo>${toString:main.classpath}</echo>
<sql
driver="${driver}"
classpathref="main.classpath"
url="${url}"
userid="${username}"
password="${password}"
expandProperties="true"
>
<transaction>
CREATE SCHEMA ${defaultSchemaName};
</transaction>
</sql>
</target>
<target
name="createOracleUsers"
description="Create a user in Oracle"
>
<sql
rdbms="oracle"
print="true"
driver="${driver}"
classpathref="main.classpath"
url="${url}"
userid="${username}"
password="${password}"
expandProperties="true"
>
<transaction>
CREATE USER ${defaultSchemaName} IDENTIFIED BY ${defaultSchemaName}
default tablespace ${tablespace.data}
temporary tablespace TEMP quota unlimited on ${tablespace.data}
quota unlimited on ${tablespace.index};
GRANT create session, alter session, create sequence,
create table, create view to ${defaultSchemaName};
</transaction>
</sql>
</target>
</project>
Edited to add some changelog files.
Here's the root changelog file:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<include file="changes/sequences/sequences.xml" relativeToChangelogFile="true" />
<include file="changes/baseobjects/db-511.xml" relativeToChangelogFile="true" />
<include file="changes/data/data-511.xml" relativeToChangelogFile="true" />
</databaseChangeLog>
The first of the included ones starts like this:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet dbms="oracle,db2,db2i" author="mccallim (generated)" id="1419011907193-1">
<createSequence schemaName="${main.schema}" cacheSize="100" cycle="false" incrementBy="1" minValue="1" sequenceName="SEQ_ALLOWEDCURRENCIES" startValue="1"/>
</changeSet>
...
</databaseChangeLog>
It has lots of other sequences. The next one does the tables, indexes and views, and is pretty much as you'd expect.
It looks like a bug. I created https://liquibase.jira.com/browse/CORE-2290 to track the fix for 3.3.3

TestNg/Selenium call by ant always return Cannot find class in the classpath

I'm pretty new with this setup. And having issue to call my project with TestNG by ant.
I can run the testng.xml without any problem in Eclipse but I alway receive Cannot find class in classpath by ant.
Build.xml
<project basedir="." default="runTest" name="Ant file for TestNG">
<property name="src" location="src" />
<property name="bin" location="bin" />
<property name="telus" location="C:\ESP_Testware\ESP_Projects\Selenium\telus-pharma-integration-tests\src\test\resources\suite\local" />
<property name="libs" location="lib" />
<path id="class.path">
<pathelement location="${libs}/testng-6.4.jar" />
<pathelement location="${libs}/selenium-java-client-driver.jar" />
<pathelement location="${libs}/selenium-server-standalone-2.39.0.jar" />
<pathelement location="${bin}"/>
<pathelement location="${telus}"/>
</path>
<taskdef name="testng" classname="org.testng.TestNGAntTask">
<classpath>
<pathelement location="${libs}/testng-6.4.jar"/>
</classpath>
</taskdef>
<target name="runTest">
<echo message="mkdir"/>
<mkdir dir="testng_output"/><!-- Create the output directory. -->
<echo message= "TestNg Start"/>
<testng outputdir="testng_output" classpathref="class.path">
<xmlfileset dir="${telus}" includes="testng.xml"/>
<!-- <xmlfileset dir="." includes="TestNG2.xml"/> -->
</testng>
</target>
</project>
Testng.xml
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Bolt harness QA" verbose="1">
<parameter name="test.env" value="qa" />
<parameter name="selenium.url" value="https://www.google.com" />
<!-- Valid values for browser: FF, IE, Chrome -->
<parameter name="selenium.browser" value="Chrome" />
<listeners>
<listener class-name="com.gdo.test.integration.listener.SoftAssertTestListener" />
</listeners>
<test name="Test_MS_Website" preserve-order="true">
<classes>
<class name="com.gdo.telus.SC006">
<methods>
<include name="Web_InvalidPassword" />
<exclude name="Web_LockedAccount" />
</methods>
</class>
</classes>
</test>
</suite>
My Class are at this path :
C:\ESP_Testware\ESP_Projects\Selenium\telus-pharma-integration-tests\src\test\java\com\gdo\telus
Thanks for your help.
Try my build.xml file, I did add the ReportNG plugin into this build.xml file to generate better looking reports instead of the default TestNG reports. You can just download the jar file for ReportNG and place it into your lib folder and it should still work fine:
<project name="Some Bullshit Goes Here" default="clean" basedir=".">
<!-- Initilization properties -->
<!-- <property name="lib.dir" value="${basedir}/lib"/> -->
<!-- using the ${basedir} allows you to use relative paths. It will use the working directory and add folders that you specify -->
<property name="build.dir" value="${basedir}/build"/>
<property name="lib.dir" value="hardcoded value can go here"/>
<property name="src.dir" value="${basedir}/src"/>
<property name="bin.dir" value="${basedir}/bin"/>
<property name="output.dir" value="${basedir}/output"/>
<!-- I chose to hardcode the location where my jar library files will be, it will be used for compilation. Again you can set relative path if you wish.-->
<path id="assloadoflibs">
<fileset dir="/automated/tests/library">
<include name="*.jar"/>
</fileset>
<pathelement path="${basedir}/bin"/>
</path>
<!-- setting libraries -->
<target name="setClassPath">
<path id="classpath_jars">
<pathelement path="${basedir}/"/>
<fileset dir="/automated/tests/library" includes="*.jar"/>
</path>
<!-- Convert jar collection from a given reference into one list, storing the result into a given property, separated by colon -->
<pathconvert pathsep=":" property="test.classpath" refid="classpath_jars"/>
</target>
<target name="loadTestNG" depends="setClassPath">
<!-- Creating task definition for TestNG task -->
<taskdef resource="testngtasks" classpath="${test.classpath}"/>
</target>
<target name="init">
<!-- Creating build directory structure used by compile -->
<mkdir dir="${build.dir}"/>
</target>
<target name="clean">
<echo message="deleting existing build directory"/>
<delete dir="${build.dir}"/>
</target>
<!-- In compile target dependency is given over clean target followed by init,
this order makes sure that build directory gets created before compile takes place
This is how a clean complile is achieved.
-->
<target name="compile" depends="clean,init,setClassPath,loadTestNG">
<echo message="classpath:${test.classpath}"/>
<echo message="compiling..."/>
<javac destdir="${build.dir}" srcdir="${src.dir}" classpath="${test.classpath}"/>
</target>
<target name="run" depends="compile">
<!-- testng classpath has been provided reference of jar files and compiled classes
this will generate report NG report.
-->
<testng classpath="${test.classpath}:${build.dir}" outputdir="${basedir}/output" haltonfailure="false" useDefaultListeners="true" listeners="org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter" classpathref="reportnglibs">
<xmlfileset dir="${basedir}" includes="testng.xml"/>
<!-- This value here will show the title of the report -->
<sysproperty key="org.uncommons.reportng.title" value="Example Test Report"/>
</testng>
</target>
</project>
Here is my TestNG.xml file:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Example Test Suite">
<test name ="Example TestCase Name">
<classes>
<class name="packageName.JavaFilename"></class>
</classes>
</test>
</suite>
I've found my answer on this site. I need to use maven to call my solution.
http://rationaleemotions.wordpress.com/2012/05/14/continuous-integration-with-selenium/
but thanx anyway for your help

Javadoc errors when building Ant project

I am trying to write a build.xml file for my project. When I run build.xml as an Ant project, I get the following error:
D:\workspace\LogAlerter\src\com\j32bit\alerter\launcher\LogAlerter.java:9:
error: package org.apache.log4j does not exist
[javadoc] import org.apache.log4j.Logger;
I have imported log4j in LogAlerter.Java. Here is my build.xml file:
<?xml version="1.0"?>
<project name="LogAlerter" default="main" basedir=".">
<!-- Sets variables which can later be used. -->
<!-- The value of a property is accessed via ${} -->
<property name="src.dir" location="src" />
<property name="build.dir" location="build" />
<property name="dist.dir" location="dist" />
<property name="docs.dir" location="docs" />
<property name="libs.dir" location="lib" />
<!--
Create a classpath container which can be later used in the ant task
-->
<path id="build.classpath">
<fileset dir="${libs.dir}">
<include name="**/*.jar" />
</fileset>
</path>
<!-- Deletes the existing build, docs and dist directory-->
<target name="clean">
<delete dir="${build.dir}" />
<delete dir="${docs.dir}" />
<delete dir="${dist.dir}" />
</target>
<!-- Creates the build, docs and dist directory-->
<target name="makedir">
<mkdir dir="${build.dir}" />
<mkdir dir="${docs.dir}" />
<mkdir dir="${dist.dir}" />
</target>
<!-- Compiles the java code (including the usage of library for JUnit -->
<target name="compile" depends="clean, makedir" >
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="build.classpath" includeantruntime="false">
</javac>
</target>
<!-- Creates Javadoc -->
<target name="docs" depends="compile">
<javadoc packagenames="src" sourcepath="${src.dir}" destdir="${docs.dir}">
<!-- Define which files / directory should get included, we include all -->
<packageset dir="${src.dir}" defaultexcludes="yes">
<include name="**" />
</packageset>
</javadoc>
</target>
<!--Creates the deployable jar file -->
<target name="jar" depends="compile">
<jar destfile="${dist.dir}\LogAlerter.jar" basedir="${build.dir}">
<manifest>
<attribute name="Main-Class" value="LogAlerter.Main" />
</manifest>
</jar>
</target>
<target name="main" depends="compile, jar, docs">
<description>Main target</description>
</target>
</project>
Try adding a classpath ref to your javadoc task:
<javadoc packagenames="src"
sourcepath="${src.dir}"
destdir="${docs.dir}"
classpathref="build.classpath">
What the warning is telling you is that you've not provided the full classpath to the javadoc task. Try adding a similar classpath ref to that in your compile task and see where that leads.
Importing is fine but make sure it is available at run time for the JavaDoc tool. log4j.jar should be present in your build.classpath.
Make use of the classpathref inside the docs target like so:
<javadoc packagenames="src" sourcepath="${src.dir}" destdir="${docs.dir}" classpathref="build.classpath">

Blackberry Apps - Importing a code-signed jar into an application project

I'm working on a library project that Blackberry Java developers can import into their projects. It uses protected RIM APIs which require that it be code-signed, which I have done. But, I can't get my Jar imported and working with a simple helloWorld app. I'm using the eclipse plug-in Blackberry-JDE.
EDIT : Solution found....
since I found the solution I removed the things I've tried, leaving only the solution ...
BUILDING THE SDK/Libary (use BB-ANT-TOOLS, either in eclipse or standalone)
steps:
A) I had to build my SDK's jar as an 'cldc' application not as a 'library'
project, using BB-ANT-TOOLS. This solved most of the issues I had above.
B) I then added an ANT task to take the resulting JAR from step A and
do the following:
unzip it,
edit the manifest file to remove the line "MicroEdition-Profile: MIDP-2.0" -- This line causes an error when you try to mark the jar for export.
then re-zipped the jar.
NOTE: I wrote a chopped down BB-ANT-TOOLS ant script to show how you could use
it to do these two steps above. The script is included below.
Consuming the SDK jar as an end-user or in your own project.
Then to integrate the jar in bb-eclipse you do the following:
A) Add the jar to the BuildPath
B) under "Java Build Path" on the "Order and Export" tab, Select the jar for
export. This causes rapc to build the jar into the COD file, so that you only
have one COD at the end.
now when a user builds this project the jar become integrated into the final
cod file, and it's very easy to deliver to the phone or sim.
<?xml version="1.0" encoding="UTF-8"?>
<project name="XXXXXMobileLib" default="full" basedir=".">
<description>
Description: Builds the BBLIB. Uses bb-ant-tools to build, sign and package for blackberry.
</description>
<taskdef resource="bb-ant-defs.xml" classpath="BIN/BB_ANT_lib/bb-ant-tools.1.x.x.jar" />
<property environment="env" />
<!-- User defined Vars -->
<property name="builderRoot" value="." />
<property name="SIG_PASSWORD" value="XXXXXXXXX" />
<property name="javaHome" value="${env.JAVA_HOME}" />
<echo>${javaHome}</echo>
<property name="jdehome" value="${env.BBJDE_HOME}\" />
<property name="simulator" value="${jdehome}\simulator" />
<property name="bin" value="${jdehome}\bin" />
<property name="releaseBuildOut" value="${builderRoot}\release_out\" />
<property name="srcBuildOut" value="${builderRoot}\srcBuild_out\" />
<property name="JarFixTemp" value="${builderRoot}\.tempZip\" />
<property name="buildVersion" value="${env.BUILD_VERSION}" />
<property name="application_id" value="com.XXXXX.foo.bar.${buildVersion}" />
<property name="application_name" value="XXXXX BBLIB v${buildVersion}" />
<property name="application_desc" value="XXXXX BBLIB v${buildVersion}" />
<property name="application_vendor" value="XXXXX" />
<property name="applicaiton_filename" value="XXXXXBBLIB${buildVersion}" />
<property name="applicaiton_srcs" value="${builderRoot}/src_in_location/" />
<property name="zipOutName" value="XXXXX-${buildVersion}BBLIB.zip" />
<property name="zipOutNameJavadocs" value="XXXXX-${buildVersion}BBLIBjavadoc.zip" />
<property name="jde.home" location="${jdehome}" />
<!--
MAIN ENTRY TARGET.
-->
<target name="full" depends="clean,javadoc,buildRIM,FixJarManifest,sign,distribute" />
<target name="FixJarManifest">
<tstamp/>
<mkdir dir="${JarFixTemp}"/>
<unzip src="${builderRoot}/release_out/${applicaiton_filename}.jar" dest="${JarFixTemp}"/>
<delete dir="${builderRoot}/release_out/${applicaiton_filename}.jar"/>
<!-- For some reason rapc puts this line into the manifest file, but it breaks the JDE plug-in when you try to
set the jar for export. Giving an error like this "Project {0} missing......"
To avoid having an empty line in the manifest, Im just injecting a new attribute BuildTime-->
<replace file="${JarFixTemp}/META-INF/MANIFEST.MF" token="MicroEdition-Profile: MIDP-2.0" value="Build-Time: ${DSTAMP}-${TSTAMP}"/>
<zip destfile="${builderRoot}/release_out/${applicaiton_filename}.jar"
basedir="${JarFixTemp}"
/>
<delete dir="${JarFixTemp}"/>
</target>
<!-- Cleanup any existing files in the outdir -->
<target name="clean">
<delete>
<fileset dir="${releaseBuildOut}" includes="**" />
</delete>
</target>
<!-- Generate the Javadocs -->
<target name="javadoc">
<javadoc access="public" destdir="${releaseBuildOut}/JavaDocs" author="true" version="true" use="true" defaultexcludes="yes" excludepackagenames="net.rim.*" windowtitle="FOO_BAR">
<fileset dir="${applicaiton_srcs}/XXXXXMobileLib">
<include name="src/**/*.java" />
</fileset>
</javadoc>
<zip destfile="${releaseBuildOut}/${zipOutNameJavadocs}" basedir="${releaseBuildOut}/JavaDocs" />
<delete dir="${releaseBuildOut}/JavaDocs"/>
</target>
<target name="buildRIM" description="Builds Project">
<rapc jdehome="${jdehome}" jdkhome="${javaHome}" destdir="${releaseBuildOut}" output="${applicaiton_filename}" quiet="false">
<!-- Building as a cldc applicaiton, so it can be packaged up with our final cod, as a single cod -->
<jdp type="cldc"
title="${application_desc}"
vendor="${application_vendor}"
version="${buildVersion}"
description="${application_desc}"
arguments=""
systemmodule="false"
runonstartup="false"
startuptier="7"
ribbonposition="0">
</jdp>
<src>
<fileset dir="${applicaiton_srcs}/MobileLib">
<include name="src/**/*.java" />
</fileset>
</src>
</rapc>
</target>
<target name="sign" depends="clean,buildRIM">
<sigtool password="${SIG_PASSWORD}">
<fileset dir="${releaseBuildOut}" includes="*.cod" />
</sigtool>
<echo>Contents of the signingtool's logfile: </echo>
<echo file="LogFile.txt" />
</target>
<!-- build and distribute the jar -->
<target name="distribute" depends="buildRIM" description="generate the distribution">
<alx destdir="${releaseBuildOut}" filename="${applicaiton_filename}.alx">
<application id="${application_id}" name="${application_name}">
<codset>
<fileset dir="${releaseBuildOut}" includes="*.cod" />
</codset>
</application>
</alx>
<!-- Create release zip -->
<delete file="${releaseBuildOut}/${zipOutName}" />
<zip destfile="${releaseBuildOut}/${zipOutName}">
<!-- zip up the BB jar and drop it for distribution -->
<zipfileset dir="${releaseBuildOut}" includes="**/*.jar" />
</zip>
<move todir="${releaseBuildOut}/UNUSED_BUILD_OUTPUT_FILES/"><!-- move unwanted files, leaving the zip behind -->
<fileset dir="${releaseBuildOut}">
<include name="**/*.*"/>
<exclude name="**/*.zip"/>
</fileset>
</move>
</target>
</project>
I have used your steps A & B to create a 'library' - thanks.
The latest Eclipse plugin for Blackberry (1.3.0.201102031007-19) has a "Blackberry | Package Project" command. I used this to create the jar file (it put it in a 'deliverables' folder in the project).
I then changed the manifest as you suggest to remove MIDP line (which apparently is a known bug). Finally, I followed the steps to add and deploy the lib to my project. (These, btw, are the same steps to adding the Banner / advertising library - very easy.)
I too have a stand-alone / external build script process that uses bb-ant-tools. I recently added the 'external library jar' feature to accommodate this. But using the new feature in Eclipse makes me question if I need to maintain my command-line build scripts as the GUI now does it for me.
The key for me was to switch the build of my library project to a "Blackberry Application" (e.g. CDLC app) as per your instructions. With it set as a 'Library' I was getting that "eviscerated" error.
Thanks for your post.

How to parameterize a path in ANT?

I have the following defined in a file called build-dependencies.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="build-dependencies">
...
<path id="common-jars">
<fileset file="artifacts/project-1/jar/some*.jar" />
<fileset file="artifacts/project-2/jar/someother*.jar" />
</path>
...
</project>
I include it at the top of my build.xml file. Now I need to make the artifacts folder a parameter so it can be changed during execution of different targets.
Having this...
<?xml version="1.0" encoding="UTF-8"?>
<project name="build-dependencies">
...
<path id="common-jars">
<fileset file="${artifacts}/project-1/jar/some*.jar" />
<fileset file="${artifacts}/project-2/jar/someother*.jar" />
</path>
...
</project>
...and defining an "artifacts" property (and changing it) in the target does not work because it seems that the property substitution happens when the path is defined in build-dependencies.xml
How can I solve this? One way I was thinking was to have a parameterized macro and call that before the path is actually used, but that seems not elegant. Something like this:
<macrodef name="create-common-jars">
<attribute name="artifacts"/>
<sequential>
<path id="common-jars">
<fileset file="#{artifacts}/project-1/jar/some*.jar" />
<fileset file="#{artifacts}/project-2/jar/someother*.jar" />
</path>
</sequential>
</macrodef>
EDIT: Ivy and command line parameters are not an option.
You don't want a parameterized path. You want a PatternSet. You can define the patternset at the top-level and then just refer to it in individual targets when you need it. For your example:
<?xml version="1.0" encoding="UTF-8"?>
<project name="build-dependencies">
...
<patternset id="common-jars">
<include name="project-1/jar/some*.jar" />
<include name="project-2/jar/someother*.jar" />
</patternset>
...
<path id="instrumented-jars">
<fileset dir="instrumented">
<patternset refid="common-jars" />
</fileset>
</path>
...
<path id="standard-jars">
<fileset dir="not-instrumented">
<patternset refid="common-jars" />
</fileset>
</path>
...
</project>
I'd recommend using ivy to manage your classpath dependencies. Ivy has a neat concept called configurations that allows you to group collections of artifacts based on their usage.
Here's an adaption from one of my own build files:
<target name="retrieve" description="3rd party dependencies">
<ivy:resolve/>
<ivy:cachepath pathid="build.path" conf="build"/>
<ivy:cachepath pathid="runtime.path" conf="runtime"/>
</target>
The configurations are managed in the ivy.xml file (Would replace your build-dependencies.xml file)
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="HelloWorld"/>
<configurations>
<conf name="build" description="jars needed for build" />
<conf name="runtime" extends="build" description="jars needed at runtime" />
</configurations>
<dependencies>
<dependency org="org1" name="project1" rev="1.0" conf="build->default"/>
<dependency org="org2" name="project2" rev="1.0" conf="build->default"/>
<dependency org="org3" name="project3" rev="1.0" conf="runtime->default"/>
<dependency org="org4" name="project4" rev="1.0" conf="runtime->default"/>
</dependencies>
</ivy-module>
The jar artifacts associated with each project would be downloaded and cached automatically from the on-line maven repositories or you can create your own local repository to hold collections of locally owned artifacts.
Lets call your file build.xml. So you execute it by running ant command. In the first case the artifacts names is hardcoded in the property defined on the third line below
<?xml version="1.0" encoding="UTF-8"?>
<project name="build-dependencies">
<property name="artifacts" value="first-value" />
...
<path id="common-jars">
<fileset file="artifacts/project-1/jar/some*.jar" />
<fileset file="artifacts/project-2/jar/someother*.jar" />
</path>
...
</project>
Now when you want to change it and use another value for that artifacts property, we run the script thus
ant -Dartifacts=new-value
This will override the hardcoded artifacts value in build.xml
If working in terms of ant targets you can do something similar, in the target on first line define the property, and if you want to overwrite the default value then pass the property as a parameter when that target is called.
Your comment reminded me of something else. Have your developers create a artifacts-dir-name.xml file. It will have only one line:
<?xml version="1.0" encoding="UTF-8"?>
<project name="artifacts-file">
<property name="artifacts" value="new-value" />
</project>
Now in your build.xml file, before the line where artifacts property is defined, import that file thus:
<import file="artifacts-dir-name.xml" optional="true" />
Now in Eclipse if this file exists, then the property is read from it and artifacts is set to "new-value", else the property is read from build.xml and is set to "first-value". All the developers need to do is to ensure artifacts-dir-name.xml file exists in that directory. This can run within Eclipse too.
is using environment variables an option (if they are set when eclipse is launched they will be picked up)? If so, have each one set ARTIFACTS and this should work:
<?xml version="1.0" encoding="UTF-8"?>
<project name="build-dependencies">
<property environment="env"/>
<path id="common-jars">
<fileset file="${env.ARTIFACTS}/project-1/jar/some*.jar" />
<fileset file="${env.ARTIFACTS}/project-2/jar/someother*.jar" />
</path>
</project>
OK, I think there is no other obvious way for me to do what I am trying to do, except use a macro that takes a parameter and creates the path with the appropriate artifacts folder.
To give a bit of context, why I was trying to what I wanted is to have "instrumented" and "not-instrumented" artifacts in separate folders. And in my "targets" I could just vary the artifacts mode. So what I do now is I have a macro: <initialise-build-settings artifacts-mode="instrumented" /> that sets up all the paths and other variables.
Thanks for your answers guys.
You can do this with different dependencies:
setpath.xml:
<project name="setpath">
<target name="setCommonJars">
<path id="common-jars">
<fileset file="${param1}/some*.jar" />
<fileset file="${param1}/someother*.jar" />
</path>
</target>
</project>
build.xml:
<project name="Test path" basedir=".">
<import file="./setpath.xml" />
<target name="buildT1" depends="setT1,setCommonJars">
<property name="jar-str" refid="common-jars" />
<echo message="buildT1: ${jar-str}" />
</target>
<target name="buildT2" depends="setT2,setCommonJars">
<property name="jar-str" refid="common-jars" />
<echo message="buildT2: ${jar-str}" />
</target>
<target name="setT1">
<property name="param1" value="t1" />
</target>
<target name="setT2">
<property name="param1" value="t2" />
</target>
</project>
If you call target buildT1 then the t1 directory will be used, if you call buildT2 then the t2 directory will be used.

Resources