Bug 36862 - Make it easier to add JARs to ant
Summary: Make it easier to add JARs to ant
Status: RESOLVED DUPLICATE of bug 38799
Alias: None
Product: Ant
Classification: Unclassified
Component: Core (show other bugs)
Version: 1.6.5
Hardware: All All
: P2 normal (vote)
Target Milestone: ---
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-09-29 16:14 UTC by Johnny Hujol
Modified: 2008-02-22 12:18 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johnny Hujol 2005-09-29 16:14:00 UTC
Hi,
just quickly: thank you all for that tool!
Also I searched the DB and did not find anything related to that.

--What I want to do:
Having an portable custom ant repository without having to modify 
the ANT_HOME/lib all the time with new libs. Also if we upgrade 
ANT to a new version, I don't want the developers to mess around
with ANT.
It helps also the automated systems (on 3 != continents) to get the
tasks needed to run the automated JUnit tests and the auto build
systems whereever I want where ANT is installed.
Everything should be smooth for anyone or anything using ANT at work.

--How I did it:
Create a Jar of the custom tasks I have and store this jar with
all the needed jars (like junit<version>.jar) in a directory in CVS.
ANT update using CVS the local copy of that directory
and use the changes recently done to our custom tasks by including the
classpathref to the taskdef tag.

--The problem:
java.lang.NoClassDefFoundError: junit/framework/Test

Solution:
put the junit*.jar in ANT_HOME/lib fixes the problem, but need to modify
ANT_HOME/lib on all the systems and I don't want it (cf what I want to do above)

--Some details now:
0.This is on Mac OS X (10.3.9)
java version "1.4.2_09"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_09-233)
Java HotSpot(TM) Client VM (build 1.4.2-56, mixed mode)
Apache Ant version 1.6.5 compiled on June 2 2005

1. I have a task called JUnitWrapperTask that inherits from JUnitTask.
It does not really do fancy stuff.
public class JUnitWrapperTask extends JUnitTask {
    /**
     * Controls output of debugging info *
     */
    protected boolean debug = false;

    protected ArrayList jvmArgumentFileList = new ArrayList();

    public JUnitWrapperTask() throws Exception {
    }

    public void setDebug(boolean on) {
        debug = on;
    }

    public JVMArgumentFile createJvmArgFile() {
        JVMArgumentFile arg = new JVMArgumentFile();
        jvmArgumentFileList.add(arg);
        return arg;
    }

    /**
     * Location of the text file containing jvm args.  File should have 1 arg
     * per line.
     */
    public class JVMArgumentFile {
        protected String jvmArgsFilePath;

        public void setValue(String val) {
            jvmArgsFilePath = val;
            ArrayList jvmArgsList = AntUtilities.getArgumentList(new
File(jvmArgsFilePath), "jvm-args-file", getProject());
            Iterator jvmIter = jvmArgsList.iterator();
            Commandline.Argument jvmArg;
            String value;
            while (jvmIter.hasNext()) {
                value = "-" + (String) jvmIter.next();
                jvmArg = createJvmarg();
                jvmArg.setValue(value);

                if (debug)
                    System.out.println("adding jvm arg '" + value + "'");
            }
        }
    }
}

2. The taskdef definition 
<path id="taskdef.class.path">
<!--    <fileset dir="${ENV.ANT_HOME}/lib">-->
<!--        <include name="*.jar"/>-->
<!--    </fileset>-->
    <fileset dir="${bs.pub.dir}">
        <include name="*.jar"/>
    </fileset>
</path>

<taskdef name="junitWrapper" classname="com.vpharm.ant.JUnitWrapperTask"
classpathref="taskdef.class.path"/>

<target name="echo-cp">
        <property name="titi" refid="taskdef.class.path"/>
        <echo>${titi}</echo>
    </target>
en echo of the classpath

Here is the classpath:
/cvs-storage/junit_3.8.1.jar:/cvs-storage/mytasks_09-28-05-145754.jar

My guess is:
system class loader (SCL) does not find JUnitWrapperTask so delegates to taskdef
class loader (TCL). TCL finds JUnitWrapperTask. 
TCL needs JUnitTask so SCL finds it but then SCL is stupid and does not ask TCL
to look for Test.

My questions:
If u think I did not look enough in the DB point me to the bug# and sorry for that!
Do I do something wrong?
Could someone tell me if this is the normal behavior of the classpathref?
Or in another way why the 2 class loaders don't work together?

Thx for any help.
J
Comment 1 Johnny Hujol 2005-09-29 16:26:03 UTC
All right, I really did not look far enough.
Sorry!
It's actually a huge issue and some people have had the same problem.

And so far the only reasonable solution is to:
"* For this (like me) who want to create a user-friendly build process that does
not require users to 
modify their ant installs, I can redistribute the relevant jars with my project
and load them within my 
build.xml file."

Same case here.


*** This bug has been marked as a duplicate of 6606 ***
Comment 2 Steve Loughran 2005-09-29 17:50:06 UTC
not a duplicate. The proposed solution is a duplicate, but that is not the
solution, because messing with classloaders after the fact is just dangerous,
especially when you consider embedded ant, or even embedded signed ant in a
secure enviroment.

Comment 3 Steve Loughran 2005-09-29 17:50:48 UTC
the solution is to 
1. use the -lib command to add all JARS in  the directory under SCM to the ant
classpath.
2. set your ANT_ARGS env variable to do this
or
3. have your developers put the JARs in ${user.home}/.ant/lib
Comment 4 Johnny Hujol 2005-09-29 18:25:26 UTC
Steve thx for the attention!
I want to have a developer and system 'ANT manipulation free' environment.
I mean no interactions or whatsoever with file system or anything related
to ANT installation.
I want to have users and systems just checking out their code 
and our custom ANT tasks from CVS, then run the stuff, without 
even noticing ANT enhancements or changes.

Each time I need to update our custom tasks, I don't want to update the
${user.home}/.ant/lib directory. Your solution is more squared that just
putting the ant-junit.jar in the taskdef classpath and probably the 
cleanest way to do it. 
But, it does not fit my 1st mandatory requirement: 
no installation or modification from a user or system or 
'do your job with what you find and bring with you'.

Our automated systems run JUnit tests, autobuild and SOAP tests among 
other things on different OSes, continents and machines, that way I 
don't care about them missing libraries.
I know everything they need is in CVS. The solution by putting the 
ant-junit.ajr in my taskdef class path works fine for the purpose
I have.
I keep this in mind though in case I run into more complex issues.

I appreciate your help and thank you guys for all the good work and
time ANT saves me on a daily basis.
J
Comment 5 Matt Benson 2005-09-29 20:43:22 UTC
If you want the user to have no interaction with Ant installation, why don't 
you install Ant in one central location, drop the extra stuff in ANT_HOME/lib 
and just let your users run over the network?
Comment 6 Johnny Hujol 2005-09-29 22:31:39 UTC
Matt, thx for jumping in!

Wouldn't that be overkilling it each time one
compiles or jars or runs tests due to network latency?

The systems right now update anytime they run tests by pulling
everything they from CVS.
Users manually have to call an ANT target, that just CVS update a 
storage directory. 
So everything is local and ANT installation untouched.

I'm interested in your thought, please could you explain
more how that would be set up and work?

Comment 7 Matt Benson 2005-09-29 22:52:27 UTC
This is about to leave the realm of bugzilla and more appropriately move to 
user@ant.apache.org .  However, I wanted to clarify a point here for 
documentation's sake.  I think marking this as a duplicate of bug 6606 
generated some confusion, esp. as that issue is still open.  I think it should 
be perfectly legitimate, if a little unorthodox, to send your custom tasks 
along with your projects and use classpaths within your taskdefs to make your 
builds more portable.  I don't think that practice is what Steve took issue 
with above, so this comment is intended to clarify that point or give Steve an 
opportunity to contradict me if I am wrong here.

As to your questions re: running a network Ant installation, on re-reading I 
see your comment about being spread across the globe.  Latency may well be an 
issue there, but I'm sure you can say much better than I on that point.  Of 
course, what would it hurt to test it?
Comment 8 Steve Loughran 2005-09-30 10:03:23 UTC
I agree with matt; this is not a duplicate of #6606. 

Johnny: read ant-in-anger ; it comes with the docs

Latency is not an issue if you keep the entire custom ant installation under SCM.
Comment 9 Jose Alberto Fernandez 2005-09-30 11:45:37 UTC
Our practice here is very simple. ANT is in CVS. You do not run ANT directly 
but use a script (e.g. "build" ) that calls ANT with the correct -lib 
arguments as required for the project. Any additional libraries or antlibs 
required for the project are stored in CVS as part of the project.

When time to upgrade comes, you do just use CVS and pull out new versions of 
ANT or libraries or whatever. You can test new releases in braches and you can 
go back in time if needed to fix some old version of the project with the 
corresponding version of ANT and libraries.

We have had no problem what so ever with such an arangement.
Comment 10 Jesse Glick 2006-02-27 20:44:39 UTC
More precise duplicate.
Comment 11 Jesse Glick 2006-02-27 20:45:00 UTC

*** This bug has been marked as a duplicate of 38799 ***