You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ant.apache.org by Craig Longman <cr...@begeek.com> on 2001/09/20 09:31:22 UTC

global properties

i have a situation where i want one and only one of a set of three
targets executed.  i've been playing around with setting properties
values inside each target, and the other targets would first check to
see if that property has been set, and if so then exit out.  i started
running into problems where properties set in the sub-targets would not
be visible outside of that target.  i upgraded to 1.4 but still found
the same behaviour.

it seems that this is behaviour by design, but i'm not sure what to do
now.  because 'child' targets cannot set/modify parent properties (even
for themselves), how is this sort of thing handled?  i must be missing a
tag or an attr somewhere, but i can't find it in the docs, nor searchign
the archives.  here is a very basic build.xml i have:


<project name="test" default="default">

<target name="default">
 <property name="use.target1" value="true"/>
 <property name="use.target2" value="true"/>
 <antcall target="target1"/>
 <antcall target="target2"/>
 <echo message="${prop2}"/>
</target>

<target name="target1" depends="check" if="use.target1">
 <property name="prop1" value="test1"/>
 <property name="prop2" value="test2"/>
</target>

<target name="target1" depends="check" if="use.target2">
 <property name="prop1" value="test1"/>
 <property name="prop2" value="test2"/>
</target>

<target name="check" if="prop1">
 <fail message="prop1 already set"/>
</target>

</project>


so, now the problem.  the default target sets the use.target1 and
use.target2 props, so both the target1 and target2 will _try_ to run. 
what is supposed to happen here is that the prop1 gets set in the
target1 target, so when the target2 runs, the check target will fail. 
problem #1 is that prop1 isn't being recognized in the default or
target2 targets.  which also messes me up for the prop2 property, which
is supposed to be a real property that is used in later targets.

in the example, for normal conditions, only one of the use.targetX props
would be set.  i'm just trying to catch the error cases gracefully in
the build file.

below is the output from the sample build.xml file.  another interesting
thing that confused me a bit; the output shows that the default target
was called, followed by check+target1 and then check+target2, then the
[echo] is printed out.  but, there is no indication that the current
target is now the default target again.  perhaps something that
indicated when a target returned from an antcall?  this problem doesn't
show itself with the 'depends', because those are executed BEFORE the
current target, i think this only affects the antcall task.

Buildfile: build.xml

default:

check:

target1:

check:

target2:
     [echo] ${prop2}

BUILD SUCCESSFUL


any assistance would be greatly appreciated.


sincerely,

     CraigL->Thx();




Re: global properties

Posted by Craig Longman <cr...@begeek.com>.
On Thu, 2001-09-20 at 13:41, Diane Holt wrote:
> --- Craig Longman <cr...@begeek.com> wrote:
> > to answer my own question, and basically exclude this type of solution,
> > i think the reason it doesn't work is that ant runs the 'check' target
> > the first time, but then assumes that target is now _done_.  so the next
> > depends="check" is just silently skipped, as that target was already
> > executed.  is this right?
> 
> Yep.

sigh.

i guess there is no way to indicate that a target should _always_ be
executed, regardless of what ant thinks?  this also sounds like it might
be something that could be of some use.  sure would be here, the only
other 'solution' would be to have a separate target to check for each
target that needs checking.  thats probably as confusing as it sounds
(!? ;-)

cheers,

     CraigL->Thx();




Re: global properties

Posted by Diane Holt <ho...@yahoo.com>.
--- Craig Longman <cr...@begeek.com> wrote:
> to answer my own question, and basically exclude this type of solution,
> i think the reason it doesn't work is that ant runs the 'check' target
> the first time, but then assumes that target is now _done_.  so the next
> depends="check" is just silently skipped, as that target was already
> executed.  is this right?

Yep.

Diane

=====
(holtdl@yahoo.com)



__________________________________________________
Terrorist Attacks on U.S. - How can you help?
Donate cash, emergency relief information
http://dailynews.yahoo.com/fc/US/Emergency_Information/

Re: global properties

Posted by Craig Longman <cr...@begeek.com>.
On Thu, 2001-09-20 at 12:12, Craig Longman wrote:
> any idea why this doesn't do the right thing?
> 
> > <project name="test" default="default2">
> > 
> > <target name="default1">
> >          <property name="use.target1" value="true"/>
> >          <property name="use.target2" value="true"/>
> > </target>
> > 
> > <target name="default2" depends="default1, target1, target2">
> >          <echo message="${prop2}"/>
> > </target>
> > 
> > <target name="target1" depends="check" if="use.target1">
> >          <property name="prop1" value="test1a"/>
> >          <property name="prop2" value="test2a"/>
> > </target>
> > 
> > <target name="target2" depends="check" if="use.target2">
> >          <property name="prop1" value="test1b"/>
> >          <property name="prop2" value="test2b"/>
> > </target>
> > 
> > <target name="check" if="prop1">
> >          <fail message="prop1 already set"/>
> > </target>
> > 
> > </project>

to answer my own question, and basically exclude this type of solution,
i think the reason it doesn't work is that ant runs the 'check' target
the first time, but then assumes that target is now _done_.  so the next
depends="check" is just silently skipped, as that target was already
executed.  is this right?  here is the output from this project:

Buildfile: build.xml

default1:

check:

target1:

target2:

default2:
     [echo] test2a

BUILD SUCCESSFUL

Total time: 0 seconds


cheers,

     CraigL->Thx();




RE: global properties

Posted by Craig Longman <cr...@begeek.com>.
On Thu, 2001-09-20 at 19:54, Conor MacNeill wrote:
> It does have its
> uses, though. In your example, the check target needs to be run in a
> separate context so that it is run more than once - so antcall is
> appropriate, but just for the check. Try this version

hehe, pretty clever also.  this does get exactly what i want, the check
one tested everytime.  thanks!


     CraigL->Thx();




RE: global properties

Posted by Conor MacNeill <co...@cortexebusiness.com.au>.
> From: Craig Longman [mailto:craigl@begeek.com]
> Sent: Friday, 21 September 2001 2:13 AM
> To: ant-user@jakarta.apache.org
> Subject: Re: global properties
>
>
> On Thu, 2001-09-20 at 07:54, Conor MacNeill wrote:
> > Why not just do without the antcall's altogether - something like this,
> > perhaps
>
> i had considered doing almost exactly this, and aside from the desire to
> not use the depends in such a way,

That is exactly what "depends" is for.

it was appearing that the antcall was
> just not going to be up to snuff.  my main concern was that you have no
> direct control over the ORDER of the depends.

You have complete control. You just need to structure your dependcies to
control what gets done and when.

in this example, the
> default2 assumes the responsibility of the 'init' target, and absolutely
> has to be run before the other targets.

Indeed.

>
> so, i was doing it this way but it was not appearing to work.  so, i
> tried your suggestion, although i couldn't see any difference.  and
> guess what?  the <fail.../> is never called!  it almost seems like the
> decision to run or not run a target is made before any one of the
> depends is executed.

OK, I'm getting a better idea of what you are trying to do now. In general I
try to avoid <antcall> because it can lead to spaghetti build files, which
look like programs rather than simple build structures. It does have its
uses, though. In your example, the check target needs to be run in a
separate context so that it is run more than once - so antcall is
appropriate, but just for the check. Try this version


<project name="test" default="default2">

<target name="default1">
         <property name="use.target1" value="true"/>
         <property name="use.target2" value="true"/>
</target>

<target name="default2" depends="default1, target1, target2">
         <echo message="${prop2}"/>
</target>

<target name="target1" if="use.target1">
         <antcall target="check"/>
         <property name="prop1" value="test1a"/>
         <property name="prop2" value="test2a"/>
</target>

<target name="target2" if="use.target2">
         <antcall target="check"/>
         <property name="prop1" value="test1b"/>
         <property name="prop2" value="test2b"/>
</target>

<target name="check" if="prop1">
         <fail message="prop1 already set"/>
</target>

</project>


Re: multiple filesets in a task

Posted by Peter Donald <do...@apache.org>.
On Fri, 21 Sep 2001 12:57, JohnA wrote:
> I am writing a taskdef that requires two FileSets. I need to distinguish
> between them. I am currently using the description= attribute. I do not
> want to get into using position i.e. the first fileset vs the second
> fileset.
>
> Is there a better technique?

just using different names ? ie. createX(), createY(), addX(), addY()

See the War task which has different names like <webinf/>, <fileset>, <lib> 
etc.

-- 
Cheers,

Pete

----------------------------------
   "Don't play dumb with me. 
I happen to be an expert at that" 
           - Maxwell Smart
----------------------------------


RE: multiple filesets in a task

Posted by JohnA <jo...@arrizza.com>.
> -----Original Message-----
> From: Conor MacNeill [mailto:conor@cortexebusiness.com.au]
> Yes, use different addXXX methods to add the filesets
> Have a look at the war task in Ant for an example of this in practice.

I tried this an hour ago and it did not work. Now it works. Go figure.

Thanks!

John

RE: multiple filesets in a task

Posted by Conor MacNeill <co...@cortexebusiness.com.au>.
> From: JohnA [mailto:john.mlist1@arrizza.com]
> 
> I am writing a taskdef that requires two FileSets. I need to distinguish
> between them. I am currently using the description= attribute. I 
> do not want
> to get into using position i.e. the first fileset vs the second fileset.
> 
> Is there a better technique?
> 

Yes, use different addXXX methods to add the filesets

public void addXFileset(Fileset fs) {
...
}

and 

public void addYFileset(Fileset fs) {
...
}

Then you have

<mytask>
   <xfileset ...>
   <yfileset ...>
</mytask>

Have a look at the war task in Ant for an example of this in practice.

Conor


multiple filesets in a task

Posted by JohnA <jo...@arrizza.com>.
I am writing a taskdef that requires two FileSets. I need to distinguish
between them. I am currently using the description= attribute. I do not want
to get into using position i.e. the first fileset vs the second fileset.

Is there a better technique?

John


Re: global properties

Posted by Diane Holt <ho...@yahoo.com>.
--- Craig Longman <cr...@begeek.com> wrote:
> so, assuming these properties:
> 
> db.host=somehost.begeek.com
> db.port=1234
> db.dbname=test_db
> db.uid=dba
> db.pwd=dba

> db.type.pgsql=true
>  OR
> db.type.db2=true

If you're going to pass the type in on the command line -- eg:
  $ ant -Dtype=db2 deploy   # or whatever you call your deployment target
you can reduce your "init" target's <antcall>'s to only one, which has:
  <antcall target="db.${type}"/>
and change the db-pgsql and db-db2 targets to use <propertyfile> to add
the properties they set to the "dbconfig.properties" file (or whatever
you're calling the file that has db.host, etc. in it) instead. Then have
"init" read the file in. Get rid of all the 'depends' and 'if's (and the
props they were if'ing against) and the check-db-config target.

In other words:

dbconfig.properties:

db.host=somehost.begeek.com
db.port=1234
db.name=test_db
db.uid=dba
db.pwd=dba

Targets:
<target name="deploy" depends="dbconfig">
  <echo message="db.host   = ${db.host}"/>
  <echo message="db.port   = ${db.port}"/>
  <echo message="db.name   = ${db.name}"/>
  <echo message="db.uid    = ${db.uid}"/>
  <echo message="db.pwd    = ${db.pwd}"/>
  <echo message="db.url    = ${db.url}"/>
  <echo message="db.driver = ${db.driver}"/>
</target>

<target name="dbconfig">
  <antcall target="db-${type}"/>
  <property file="dbconfig.properties"/>
</target>

<target name="db-db2">
  <propertyfile file="dbconfig.properties">
    <entry key="db.url"
value="jdbc:db2:${db.host}:${db.port}/${db.name}"/>
    <entry key="db.driver" value="COM.ibm.db2.jdbc.net.DB2Driver"/>
  </propertyfile>
</target>

<target name="db-pgsql">
  <propertyfile file="dbconfig.properties">
    <entry key="db.url"
           value="jdbc:postgresql://${db.host}:${db.port}/${db.name}"/>
    <entry key="db.driver" value="org.postgresql.Driver"/>
  </propertyfile>
</target>

$ ant -Dtype=db2 deploy
db-db2:
     [propertyfile] Updating property file: dbconfig.properties

deploy:
     [echo] db.host   = somehost.begeek.com
     [echo] db.port   = 1234
     [echo] db.name   = test_db
     [echo] db.uid    = dba
     [echo] db.pwd    = dba
     [echo] db.url    = jdbc:db2:somehost.begeek.com:1234/test_db
     [echo] db.driver = COM.ibm.db2.jdbc.net.DB2Driver

Note: If your "dbconfig.properties" file is source-controlled, so it ends
up being read-only in your build tree, you'll need to work that out.

Diane

=====
(holtdl@yahoo.com)



__________________________________________________
Terrorist Attacks on U.S. - How can you help?
Donate cash, emergency relief information
http://dailynews.yahoo.com/fc/US/Emergency_Information/

Re: global properties

Posted by Craig Longman <cr...@begeek.com>.
On Thu, 2001-09-20 at 13:37, Diane Holt wrote:
> --- Craig Longman <cr...@begeek.com> wrote:
> > both are being set just to see if it fails.  under normal conditions, i
> > would only set one of them, having more than one set would be cause for
> > an error.
> 
> Under normal conditions, how would one of either use.target1 or
> use.target2 get set? -- command-line define? -- property file? -- set
> within a target in the build-file?

i'm not sure yet.  i had initially just left a target at the top of the
build.xml file that could be modified as the need arose.  but i think it
will probably be converted to a properties file to simplify it.

> > prop1 is just a flag to determine whether the targets have been
> > executed.  it was just a way of having something check if it was already
> > set and if so, assume that the initialization has already been
> > completed.  prop2 just represents a property that i am actually
> > interested in have ONE of the two targets configure.
> 
> I'm not sure what initialization you're doing but, because of the
> immutability of properties, if you set prop2 in both target1 and target2,
> whichever target ran first will be who determined what prop2 will be set
> to, so if all target1 and target2 do is set a particular property, it
> won't matter if both run -- only which is run first (assuming you're no
> longer running target1 and target2 via <antcall>'s).

ok, here is a bit of an explanation:

i'm writing a build file to allow for easy deployment of our html for
our project.  part of the html is a property containing the URL for JDBC
to use to connect to the database.  we need to be able to handle
multiple databases, each of which use different urls to connect.  so,
the basic idea is, the deployer would set the database type (db2/pgsql
for eg) and provide the host,port,db,uid,pwd for the connection.  then,
the build.xml file would figure out the rest, using the preferred
Driver, build the URL, etc.  then use this to replace tokens in the
files that are being deployed.

so, assuming these properties:

db.host=somehost.begeek.com
db.port=1234
db.dbname=test_db
db.uid=dba
db.pwd=dba
db.type.pgsql=true
 OR
db.type.db2=true

then the build.xml:


<target name="default" depends="init">
 ...
</target>

<target name="init">
 <...read in props...>
 <antcall target="db-db2">
 <antcall target="db-pgsql">
</target>

<target name="db-db2" if="db.type.db2" depends="check-db-config">
 <property name="db.config" value="true"/>
 <property name="db.url" value="jdbc:db2:${db.host}:${db.port}/${db.name}"/>
 <property name="db.driver" value="COM.ibm.db2.jdbc.net.DB2Driver"/>
</target>

<target name="db-pgsql" if="db.type.pgsql" depends="check-db-config">
 <property name="db.config" value="true"/>
 <property name="db.url" value="jdbc:postgresql://${db.host}:${db.port}/${db.name}"/>
 <property name="db.driver" value="org.postgresql.Driver"/>
</target>

<target name="check-db-config" if="db.config">
 <fail message="only one db.type property please"/>
</target>


so, there's the basic problem.  the fact that 'antcall' tag handles
properties in a completely different fashion to the 'depends' attribute
means that this won't work.  invoking the db-XXX targets  in the
'depends' attribute of the init tag won't work, as other things get
initialized in that target.  and invoking the db-XXX targets from the
depends in the default target is also undesireable for the folowing
reasons:
  - there is no guaranteed order of execution in the depends list (at
least, its not guaranteed to execute in the order provided)
  - there will be multiple targets like 'default', managing all of them
is painful
  - finally, if they're called from any 'depends' attribute, then the
fact that the check-db-config target will only get called once pretty
much negates the whole point of it.

i guess i just must be doing things that ant isn't really designed to
do.  it seemed like it would be a good tool for it, but this has really
proved to be painful and i'm not exactly sure why.   other than to think
that configuring complicated parameters to setup properties files in a
large install is not the point of it, but i'm not sure thats true
either.  anyway, i like some of the other things about ant, so i will
probably just remove the error/sanity checking and accept the 'hack' of
just using the depends to invoke the db-XXX targets for now.  and then
maybe work on some of the other possibilities i've mentioned in the
'suggestions' thread.

thanks!

     CraigL->Thx();




Re: global properties

Posted by Diane Holt <ho...@yahoo.com>.
--- Craig Longman <cr...@begeek.com> wrote:
> both are being set just to see if it fails.  under normal conditions, i
> would only set one of them, having more than one set would be cause for
> an error.

Under normal conditions, how would one of either use.target1 or
use.target2 get set? -- command-line define? -- property file? -- set
within a target in the build-file?

> prop1 is just a flag to determine whether the targets have been
> executed.  it was just a way of having something check if it was already
> set and if so, assume that the initialization has already been
> completed.  prop2 just represents a property that i am actually
> interested in have ONE of the two targets configure.

I'm not sure what initialization you're doing but, because of the
immutability of properties, if you set prop2 in both target1 and target2,
whichever target ran first will be who determined what prop2 will be set
to, so if all target1 and target2 do is set a particular property, it
won't matter if both run -- only which is run first (assuming you're no
longer running target1 and target2 via <antcall>'s).

> make sense?

Not entirely yet -- but I'm guessing that has something to do with not
seeing how things are intended to normally work.

=====
(holtdl@yahoo.com)



__________________________________________________
Terrorist Attacks on U.S. - How can you help?
Donate cash, emergency relief information
http://dailynews.yahoo.com/fc/US/Emergency_Information/

Re: global properties

Posted by Craig Longman <cr...@begeek.com>.
On Thu, 2001-09-20 at 13:00, Diane Holt wrote:
> Could you explain what it is you're actually trying to do?  Are you trying
> to run only one of either target1 or target2 (ie., if target1 was run,
> don't run target2, and vice-versa)?

i'm trying to ensure that ONLY target1 OR target2 are executed, that's
correct.

> I'm not clear on why you're setting both use.target1 and use.target2 to
> "true" and then if'ing on them in their respective targets -- how would
> the if ever fail?

both are being set just to see if it fails.  under normal conditions, i
would only set one of them, having more than one set would be cause for
an error.

> As for perpetuating a property set during an <antcall> (or <ant>), you can
> use the <propertyfile> task in the called targets to write the properties
> out to a property file, which then gets read in before the other target is
> called (but again, I'm still not clear on what the various properties
> you're setting are really for [eg., why prop1 and prop2 in both target1
> and target2?]).

prop1 is just a flag to determine whether the targets have been
executed.  it was just a way of having something check if it was already
set and if so, assume that the initialization has already been
completed.  prop2 just represents a property that i am actually
interested in have ONE of the two targets configure.

the property file sounds like it might work.  it seems a little heavy
handed just to have a darn property being set.  i guess it might work
though.  i'm also looking at the source to see if i can make a
'inheritChild' option for ant/antcall so that this problem goes away.

make sense?

cheers,

     CraigL->Thx();




Re: global properties

Posted by Diane Holt <ho...@yahoo.com>.
Craig,

Could you explain what it is you're actually trying to do?  Are you trying
to run only one of either target1 or target2 (ie., if target1 was run,
don't run target2, and vice-versa)?

I'm not clear on why you're setting both use.target1 and use.target2 to
"true" and then if'ing on them in their respective targets -- how would
the if ever fail?

As for perpetuating a property set during an <antcall> (or <ant>), you can
use the <propertyfile> task in the called targets to write the properties
out to a property file, which then gets read in before the other target is
called (but again, I'm still not clear on what the various properties
you're setting are really for [eg., why prop1 and prop2 in both target1
and target2?]).

Diane

--- Craig Longman <cr...@begeek.com> wrote:
> On Thu, 2001-09-20 at 07:54, Conor MacNeill wrote:
> > Why not just do without the antcall's altogether - something like
> this, 
> > perhaps
> 
> i had considered doing almost exactly this, and aside from the desire to
> not use the depends in such a way, it was appearing that the antcall was
> just not going to be up to snuff.  my main concern was that you have no
> direct control over the ORDER of the depends.  in this example, the
> default2 assumes the responsibility of the 'init' target, and absolutely
> has to be run before the other targets.
> 
> so, i was doing it this way but it was not appearing to work.  so, i
> tried your suggestion, although i couldn't see any difference.  and
> guess what?  the <fail.../> is never called!  it almost seems like the
> decision to run or not run a target is made before any one of the
> depends is executed.
> 
> any idea why this doesn't do the right thing?
> 
> aside from my real problem with how to make a target called by antcall
> set a property that other targets will be able to see.
> 
> > <project name="test" default="default2">
> > 
> > <target name="default1">
> >          <property name="use.target1" value="true"/>
> >          <property name="use.target2" value="true"/>
> > </target>
> > 
> > <target name="default2" depends="default1, target1, target2">
> >          <echo message="${prop2}"/>
> > </target>
> > 
> > <target name="target1" depends="check" if="use.target1">
> >          <property name="prop1" value="test1a"/>
> >          <property name="prop2" value="test2a"/>
> > </target>
> > 
> > <target name="target2" depends="check" if="use.target2">
> >          <property name="prop1" value="test1b"/>
> >          <property name="prop2" value="test2b"/>
> > </target>
> > 
> > <target name="check" if="prop1">
> >          <fail message="prop1 already set"/>
> > </target>
> > 
> > </project>
> 
> 
> cheers,
> 
>      CraigL->Thx();
> 
> 


=====
(holtdl@yahoo.com)



__________________________________________________
Terrorist Attacks on U.S. - How can you help?
Donate cash, emergency relief information
http://dailynews.yahoo.com/fc/US/Emergency_Information/

Re: global properties

Posted by Craig Longman <cr...@begeek.com>.
On Thu, 2001-09-20 at 07:54, Conor MacNeill wrote:
> Why not just do without the antcall's altogether - something like this, 
> perhaps

i had considered doing almost exactly this, and aside from the desire to
not use the depends in such a way, it was appearing that the antcall was
just not going to be up to snuff.  my main concern was that you have no
direct control over the ORDER of the depends.  in this example, the
default2 assumes the responsibility of the 'init' target, and absolutely
has to be run before the other targets.

so, i was doing it this way but it was not appearing to work.  so, i
tried your suggestion, although i couldn't see any difference.  and
guess what?  the <fail.../> is never called!  it almost seems like the
decision to run or not run a target is made before any one of the
depends is executed.

any idea why this doesn't do the right thing?

aside from my real problem with how to make a target called by antcall
set a property that other targets will be able to see.

> <project name="test" default="default2">
> 
> <target name="default1">
>          <property name="use.target1" value="true"/>
>          <property name="use.target2" value="true"/>
> </target>
> 
> <target name="default2" depends="default1, target1, target2">
>          <echo message="${prop2}"/>
> </target>
> 
> <target name="target1" depends="check" if="use.target1">
>          <property name="prop1" value="test1a"/>
>          <property name="prop2" value="test2a"/>
> </target>
> 
> <target name="target2" depends="check" if="use.target2">
>          <property name="prop1" value="test1b"/>
>          <property name="prop2" value="test2b"/>
> </target>
> 
> <target name="check" if="prop1">
>          <fail message="prop1 already set"/>
> </target>
> 
> </project>


cheers,

     CraigL->Thx();



Re: global properties

Posted by Conor MacNeill <co...@cortexebusiness.com.au>.
Craig Longman wrote:

Craig,

Why not just do without the antcall's altogether - something like this, 
perhaps

<project name="test" default="default2">

<target name="default1">
         <property name="use.target1" value="true"/>
         <property name="use.target2" value="true"/>
</target>

<target name="default2" depends="default1, target1, target2">
         <echo message="${prop2}"/>
</target>

<target name="target1" depends="check" if="use.target1">
         <property name="prop1" value="test1a"/>
         <property name="prop2" value="test2a"/>
</target>

<target name="target2" depends="check" if="use.target2">
         <property name="prop1" value="test1b"/>
         <property name="prop2" value="test2b"/>
</target>

<target name="check" if="prop1">
         <fail message="prop1 already set"/>
</target>

</project>

Conor