ant - build jar with lib inside and in MANIFEST classpath - jar

I have the following for building my jar currently:
<jar jarfile="${bin.dir}/${name}.jar" basedir="${build.src.dir}">
<zipfileset src="${bin.lib.dir}/dependencies-compact.jar"
excludes="META-INF/*.SF" />
</jar>
But this makes everything jumbled inside the jar. The plan now is inside the jar, there will be a folder called lib, and the MANIFEST.MF's classpath variable will be updated with the list of all the jars in lib folder. How to achieve this on ant?

The classpath in the Manifest refers to external jars, not classes that you have pulled inside your jar file.
The following is a sample of how I use ivy to put my jar's dependencies into an adjacent "lib" directory and then use the ANT manifestclasspath task to construct the string that goes into the jar manifest:
<target name="build" depends="compile">
<ivy:retrieve pattern="${dist.dir}/lib/[artifact].[ext]"/>
<manifestclasspath property="jar.classpath" jarfile="${dist.jar}">
<classpath>
<fileset dir="${dist.dir}/lib" includes="*.jar"/>
</classpath>
</manifestclasspath>
<jar destfile="${dist.jar}" basedir="${build.dir}/classes">
<manifest>
<attribute name="Main-Class" value="${dist.main.class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</jar>
</target>
For more detailed examples that include ivy files and unit tests see:
How to avoid copying dependencies with Ivy
Class not found with Ant, Ivy and JUnit - error in build.xml?

Related

possible to change build directory in jwrapper?

when I use ANT to invoke the jwrapper task, is there a possibility to (re-)define the build directory ?
jwrapper uses automatically "build" and this collides with the existing build task and folder structure...
Thank you!
Peter
OK, I found a solution by using the "dir" attribute of the java ant task
<mkdir dir="${basedir}/build_jwrapper"/>
<java jar="${JWrapperJAR}" failonerror="true" fork="true"
dir="${basedir}/build_jwrapper">
<jvmarg value="-Xmx512m"/>
<arg value="${basedir}/jwrapper.xml"/>
</java>

Adding of external jar file into classpath for jBoss 7

I would like to include external jar files into classpath for all configurations of jBoss7.
Is there any way to do this without moving my files somewhere into jboss lib directories? Or better - is there any way to include all jar files in some external directory?
No answer actually outlines exactly what to do here so here goes.
In your jboss-deployment-structure.xml file, which should be in webapp/WEB-INF you need to add the module reference :
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
<deployment>
<dependencies>
<module name="javaee.api">
<imports>
<exclude path="org/apache/xml/security/**" />
</imports>
</module>
<module name="com.sun.xml.bind" slot="main" />
<module name="com.mycompany.mypackage" slot="1_0" />
<module name="com.oracle.ojdbc14" slot="main" />
</dependencies>
</deployment>
</jboss-deployment-structure>
then copy the jar file this dir :
C:\[JBoss-Home]\modules\com\mycompany\mypackage\1_0
There's a directory called modules where you can put your jars. But to know how to do that you should read this guide. You may also create a global module that is accessible to all deployments. Look at this doc.

Using ANT with Flex, building dependent target fails

I have a flex project called framework and another one called commons. Commons depends on framework.
Build script for framework :
<project name="imanager-framework" basedir=".">
<property name="src" location="src"/>
<property name="dist" location="dist"/>
<property name="FLEX_HOME" value="C:/Program Files (x86)/Adobe/Adobe Flash Builder 4.5/sdks/4.6.0"/>
<taskdef resource="flexTasks.tasks" classpath="${basedir}/libs/flexTasksFlash4.jar"/>
<target name="clean">
<delete dir="${dist}"/>
</target>
<target name="dist">
<echo>src dir: ${src}</echo>
<mkdir dir="${dist}"/>
<compc output="${dist}/${ant.project.name}.swc">
<source-path path-element="src" />
<library-path dir="libs" includes="*.swc" append="true"/>
<include-sources dir="${src}" includes="*" />
</compc>
</target>
</project>
Build script for commons :
<?xml version="1.0" encoding="UTF-8"?>
<project name="imanager-commons" basedir=".">
<property name="src" location="src"/>
<property name="dist" location="dist"/>
<property name="FLEX_HOME" value="C:/Program Files (x86)/Adobe/Adobe Flash Builder 4.5/sdks/4.6.0"/>
<taskdef resource="flexTasks.tasks" classpath="${basedir}/libs/flexTasksFlash4.jar"/>
<target name="clean">
<delete dir="${dist}"/>
</target>
<target name="init">
<echo>Running Target: init</echo>
<echo>Running ant dist on framework</echo>
<!-- THIS PART FAILS --> <ant dir="../framework/" target="dist" inheritall="false"/>
<copy file="../framework/dist/imanager-framework.swc" todir="libs"/>
</target>
<target name="dist" depends="init">
<mkdir dir="${dist}"/>
<compc output="${dist}/${ant.project.name}.swc">
<source-path path-element="src" />
<library-path dir="libs" includes="*.swc" append="true"/>
<include-sources dir="${src}" includes="*" />
</compc>
</target>
</project>
Calling <ant> from the commons build file gives me spurious compile errors about bad imports and classes not being found. But running framework's build separately doesn't give any errors.
Here's some of the output I get
Buildfile: E:\flexspace\imanager\commons\build.xml
init:
[echo] Running Target: init
[echo] Running ant dist on framework
Trying to override old definition of task asdoc
Trying to override old definition of task compc
Trying to override old definition of task mxmlc
Trying to override old definition of task html-wrapper
dist:
[echo] src dir: E:\flexspace\imanager\framework\src
[compc] Loading configuration file C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.5\sdks\4.6.0\frameworks\flex-config.xml
...some warnings from my code here...
[compc] E:\flexspace\imanager\framework\src\com\iwobanas\controls\dataGridClasses\MDataGridColumn.as(72): col: 88 Error: Access of undefined property WildcardFilterEditor in package com.iwobanas.controls.dataGridClasses.filterEditors.
[compc] filterEditor = new ClassFactory(com.iwobanas.controls.dataGridClasses.filterEditors.WildcardFilterEditor);
[compc] ^
[compc] E:\flexspace\imanager\framework\src\com\iwobanas\controls\dataGridClasses\MDataGridColumn.as(24): col: 60 Error: Definition com.iwobanas.controls.dataGridClasses.filterEditors:WildcardFilterEditor could not be found.
[compc] import com.iwobanas.controls.dataGridClasses.filterEditors.WildcardFilterEditor;
[compc] ^
[compc] E:\flexspace\imanager\framework\src\org\syspire\erp\component\tooltip\components\ExtendedToolTip.as(3): col: 48 Error: Definition org.syspire.erp.component.tooltip.skins:ExtendedToolTipSkin could not be found.
[compc] import org.syspire.erp.component.tooltip.skins.ExtendedToolTipSkin;
[compc] ^
[compc] E:\flexspace\imanager\framework\src\org\astrika\shared\components\gridSearch\view\SearchDatePopup.mxml(14): Error: Type was not found or was not a compile-time constant: SearchDateView.
[compc] <gridSearch:SearchDateView id="searchDateView"/>
...similar errors...
BUILD FAILED
E:\flexspace\imanager\commons\build.xml:17: The following error occurred while executing this line:
E:\flexspace\imanager\framework\build.xml:17: compc task failed
Total time: 4 seconds
What's going wrong here?
Thanks
EDIT
As requested, here are the config dumps:
Framework build using Flash Builder: http://pastebin.com/kLai6j7X
Framework build using ANT: http://pastebin.com/FGHBAXZX
Framework build called from commons using ANT: (This is same as the previous dump)
UPDATE
I ended up just changing the structure of my build files to eliminate the <ant> call. I now how one build.xml for all the projects, will all targets in it. Not pretty, but it works for me.
It's a bit off-topic but I found Ant does bad at managing the build of Flex projects, especially when you have dependencies.
Have you considered using Maven with FlexMojos ? Adobe released a series of articles about this great tool. Much recommended !
One thing you can definitely try is to move the taskdef into target, at least that'll get rid of "Trying to override old definition of task" warning.

How to avoid copying dependencies with Ivy

I'm looking into using Ivy to manage dependencies but wow - that thing really likes to make multiple copies of jars! It spreads like the ivy in my back yard and is just as undesirable!
Is it possible to have Ivy simply define a classpath (for a specified profile) that references the resolved dependencies so my javac can reference them directly in the ivy repository (or cache?).
I've read the reference docs buy only see the option to set up symbolic links to the repository cache. I guess this will suffice, but it seems like a waste. Also, I'm not sure that a "war" task can build the war from symbolic links... but I guess I'll find out when I give it a try.
Any better suggestions?
Here's my standard Java build file that creates an executable jar.
The objective is to manage project specific stuff via a combination of ANT properties and an ivy.xml file for the 3rd-party dependencies.
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="demo" default="build">
<property name="src.dir" location="src"/>
<property name="build.dir" location="build"/>
<property name="dist.dir" location="dist"/>
<property name="dist.jar" location="${dist.dir}/${ant.project.name}.jar"/>
<property name="dist.main.class" value="HelloWorld"/>
<target name="retrieve">
<ivy:resolve/>
<ivy:cachepath pathid="build.path" conf="build"/>
<ivy:cachepath pathid="runtime.path" conf="runtime"/>
</target>
<target name="compile" depends="retrieve">
<mkdir dir="${build.dir}/classes"/>
<javac srcdir="${src.dir}" destdir="${build.dir}/classes" classpathref="build.path"/>
</target>
<target name="build" depends="compile">
<ivy:retrieve pattern="${dist.dir}/lib/[artifact].[ext]"/>
<manifestclasspath property="jar.classpath" jarfile="${dist.jar}">
<classpath>
<fileset dir="${dist.dir}/lib" includes="*.jar"/>
</classpath>
</manifestclasspath>
<jar destfile="${dist.jar}" basedir="${build.dir}/classes">
<manifest>
<attribute name="Main-Class" value="${dist.main.class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</jar>
</target>
<target name="clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
</project>
As you've discovered in the Ivy docu, the cachepath Ivy task is used to manage two ANT paths. One for the build dependencies the other for the run-time dependencies of the executable jar.
The real power of Ivy is in something called configurations. I found it difficult to grasp initially until I realised it was simple a logical grouping of jars that I can define for my project. This example has two configurations:
build
runtime
Here's the ivy file demonstrating how dependencies can be associated with configurations:
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="build" description="Libraries needed to for compilation"/>
<conf name="runtime" extends="build" description="Libraries that need to be included with project jar" />
</configurations>
<dependencies>
<dependency org="commons-lang" name="commons-lang" rev="2.0" conf="build->default"/>
<dependency org="commons-cli" name="commons-cli" rev="1.0" conf="runtime->default"/>
</dependencies>
</ivy-module>
In conclusion I hope this example helps in understanding Ivy. I like the way it concentrates on only one thing, the management of 3rd-party dependencies.
After battling through the badly written Ivy documentation (sigh - what is wrong with these people? - did they not attend high-school literacy classes in any language?), I see there is a post-resolve task called cachepath that will construct an ant path to the resolved dependency artifacts instead of copying files to a lib directory. This might be just what I'm looking for!
Just to augment #Mark's answer.
Note that cachepath result can also be directly used in build without the need to copy jars with retrieve:
<target name="build" depends="compile">
<jar destfile="${dist.ear}">
<mappedresources>
<resources refid="runtime.path"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</mappedresources>
</jar>
</target>

Compiling mxml files with ant and flex sdk

I am just getting started with flex and am using the SDK (not Flex Builder). I was wondering what's the best way to compile a mxml file from an ant build script.
The Flex SDK ships with a set of ant tasks. More info at:
http://livedocs.adobe.com/flex/3/html/help.html?content=anttasks_1.html
Here is an example of compiling Flex SWCs with ant:
http://www.mikechambers.com/blog/2006/05/19/example-using-ant-with-compc-to-compile-swcs/
mike chambers
I would definitely go with the ant tasks that are included with Flex, they make your build script so much cleaner. Here is a sample build script that will compile and then run your flex project
<?xml version="1.0"?>
<project name="flexapptest" default="buildAndRun" basedir=".">
<!--
make sure this jar file is in the ant lib directory
classpath="${ANT_HOME}/lib/flexTasks.jar"
-->
<taskdef resource="flexTasks.tasks" />
<property name="appname" value="flexapptest"/>
<property name="appname_main" value="Flexapptest"/>
<property name="FLEX_HOME" value="/Applications/flex_sdk_3"/>
<property name="APP_ROOT" value="."/>
<property name="swfOut" value="dist/${appname}.swf" />
<!-- point this to your local copy of the flash player -->
<property name="flash.player" location="/Applications/Adobe Flash CS3/Players/Flash Player.app" />
<target name="compile">
<mxmlc file="${APP_ROOT}/src/${appname_main}.mxml"
output="${APP_ROOT}/${swfOut}"
keep-generated-actionscript="true">
<default-size width="800" height="600" />
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.library-path dir="${APP_ROOT}/libs" append="true">
<include name="*.swc" />
</compiler.library-path>
</mxmlc>
</target>
<target name="buildAndRun" depends="compile">
<exec executable="open">
<arg line="-a '${flash.player}'"/>
<arg line="${APP_ROOT}/${swfOut}" />
</exec>
</target>
<target name="clean">
<delete dir="${APP_ROOT}/src/generated"/>
<delete file="${APP_ROOT}/${swfOut}"/>
</target>
</project>
There is another option - it's called Project Sprouts.
This is a system built with Ruby, RubyGems and Rake that provides many of the features found in Maven and ANT, but with a much cleaner syntax and simpler build scripts.
For example, the ANT script shown above would look like this in Sprouts:
require 'rubygems'
require 'sprout'
desc 'Compile and run the SWF'
flashplayer :run => 'bin/SomeProject.swf'
mxmlc 'bin/SomeProject.swf' do |t|
t.input = 'src/SomeProject.as'
t.default_size = '800 600'
t.default_background_color = '#ffffff'
t.keep_generated_actionscript = true
t.library_path << 'libs'
end
task :default => :run
After installing Ruby and RubyGems, you would simply call this script with:
rake
To remove generated files, run:
rake clean
To see available tasks:
rake -T
Another great benefit of Sprouts, once installed, is that it provides project, class and test generators that will get any development box ready to run with a couple simple command line actions.
# Generate a project and cd into it:
sprout -n mxml SomeProject
cd SomeProject
# Compile and run the main debug SWF:
rake
# Generate a new class, test case and test suite:
script/generate class utils.MathUtil
# Compile and run the test harness:
rake test
If you're open to Maven, try the flex-compiler-mojo plugin:
http://code.google.com/p/flex-mojos/
Christiaan

Resources