Building with ant : dynamic build options? - java

With multiple developers working on the same Tomcat application, I'd like to tell the application to install to a different path, based on the current user and revision control client/view.
So, if Bob is building, the app should be installed in Bob's test environment, maybe /bob1 or something like that. Bob might have several revision control clients/views/workspaces he works with so he could have /bob1, /bob2, /bob3, etc.
The install location is specified in the build.properties file. Is there a way to avoid checking that file out and changing it for each specific user and revision control view?
Can "ant install" take arguments or be configured to consider environment variables for the install target?

I typically use a variation on the default properties answer already given:
<property file="local.properties" />
<property file="default.properties" />
I read the local properties file first and the default one second. Users don't edit the default one (then accidentally check it in), they just define the properties they want to override in the local.properties.

You can override ant properties from the command line.
ant -Dinstall.location=/bob1 install
See Running Ant for more information.

This answer is quite late but I just wanted to put it in for someone who may be in need of of it. The answer pertains to the second part of your question.
"Can "ant install" take arguments or be configured to consider environment variables for the install target?"
Define the environment virable in your build file:
<property environment="env" />
reference the env variable and use it to indicate a path. This is done in my classpath definition inside my build file. It says include a jar named api.jar from the weblogic lib directory. You can access any other path so long as there's an associated environment virable defined for it. For example, you can access Program Files, Documents, Java Home etc if you sent environment variables for them. Here the environment variable defined for weblogic installation directory is BEA_HOME
<fileset dir="${env.BEA_HOME}/wlserver_10.0/server/lib">
<include name="api.jar" />
</fileset>

Defining properties with the -D option at the command line is fine, though it can get tedious if there are many of them frequently. In order to resist the urge to wrap the ant invocation in a bash script, there is the common practise to import property files.
In the main build file you put:
<property file="default.properties" />
Then you have a file named default.properties.sample with a sample configuration. This is being checked into version control. The developers check out default.properties.sample, copy it to default.properties and edit it according to their needs.
You should set an ignore default flag for default.samples in order to prevent it from being checked in accidentally (svn:ignore with subversion).

Related

What's the defference between "-Dorg.gradle.project.env=demo" and "-Denv=demo" in gradle?

Today I'm trying to use the system property in my code .When I enter ./gradlew -Dorg.gradle.project.env=demo test ,the NullPointExcepetion happens,though I println env in script successfully!Then I try another way , entering ./gradlew -Denv=demo test and my code get the env set in command line successfully .So my question is What's the defference between "-Dorg.gradle.project.env=demo" and "-Denv=demo" in gradle?P.s. This link(12.2. Gradle properties and system properties in https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_properties_and_system_properties) told me to use org.gradle.project to set system property.I guess when you use org.gradle.project, you should use another method to get system property ,not using
System.getProperty("env")
I guess when you use org.gradle.project, you should use another method to get system property, not using System.getProperty("env")
You're right. This two syntaxes are different and serve different purposes.
The latter one, -Denv is a standard way of passing system properties in Java world. If you run java -help you'll see:
-D<name>=<value> set a system property
So, when you use it, env system property becomes available via System.getProperty("env") and it's value will be demo.
The first one -Dorg.gradle.project.env is actually a system property too! It's obvious after reading the lines above. However, it sets a system property named org.gradle.project.env, not just env. So, unless your test expect this name, it won't work. And your tests must no expect this name, because they should, generally, be unaware of the build tool.
What Gradle docs says is:
Gradle offers a variety of ways to add properties to your build. With the -D command line option you can pass a system property to the JVM which runs Gradle. The -D option of the gradle command has the same effect as the -D option of the java command.
Gradle can also set project properties when it sees specially-named system properties or environment variables. This feature is very useful when you don’t have admin rights to a continuous integration server and you need to set property values that should not be easily visible, typically for security reasons. In that situation, you can’t use the -P option, and you can’t change the system-level configuration files. The correct strategy is to change the configuration of your continuous integration build job, adding an environment variable setting that matches an expected pattern. This won’t be visible to normal users on the system.
If the environment variable name looks like ORG_GRADLE_PROJECT_prop=somevalue, then Gradle will set a prop property on your project object, with the value of somevalue. Gradle also supports this for system properties, but with a different naming pattern, which looks like org.gradle.project.prop.
Differently saying, Gradle allows you to set project proprties by providing system properties with special names, and that is what you did. You've set a Project's property named env to a value demo by providing a system property with a name org.gradle.project.env. This property is available in you build script via project.env and can be used to tweak builds in various ways.

Eclipse: Use environment variable for external jar location

After hours of unsuccessful googling, I ask you:
Situation:
My Eclipse Project uses "nedded.jar" so I added it to the build path. No problem.
C:/dev/development/my_needed/nedded.jar
But the location of "nedded.jar" is relative to the environment variable DEVELOPMENT ( =C:/dev/development/ ) and therefore may change. So, I need my Referenced Library path to be:
%DEVELOPMENT%/my_needed/nedded.jar
I could not find the syntax to accomplish that. Ideas?
EDIT:
Maybe I did not make myself clear enough: This Project is developed by MSVisual Studio(C++) and Eclipse(Java). Both are started from the Console. A prior executed script sets 3 major variables: DEVELOPMENT, RUNTIME, SOURCES to certain, changing paths.
If I then start Eclipse from this shell, the path to my external libs shall be defined by %DEVELOPMENT%\my_needed\nedded.jar.
I have found a half way solution (somewhere): added a new folder --> advanced --> link to alternate location (linked folder).
this adds you an entry in your .project, which I also get, when I checkout my project:
<linkedResources>
<link>
<name>lib/RXTXcomm.jar</name>
<type>1</type>
<locationURI>PARENT-4-PROJECT_LOC/Development/rxtx/RXTXcomm.jar</locationURI>
</link>
</linkedResources>
Nice so far, but it still does not depend on %DEVELOPMENT%. What I need is:
%DEVELOPMENT%/rxtx/RXTXcomm.jar
Hope this is now clearer.
You should declare a variable (Java Build Path -> Add Variable... -> Configure Variable ... -> New) to set the changing path on each system (e.g. FOO_BAR_HOME).
Then you can add the variable to the Libraries section and edit it to point to your library, like:
%FOO_BAR_HOME%/lib/foobar.jar
Take a look at the existing variables for usage.
Alternatively you can place the library inside the project (e.g. subfolder 'lib'). If you add the library from this location ('Add Jars...' NOT 'Add External Jars...') it will be added by relative path.
I was searching for an answer to this as well with ant. Seems you can reference windows environment variables like so
<property environment="env"/>
Provide all environment variables as Ant properties prefixed by "env.". For example, CLASSPATH would be accessible in Ant as ${env.CLASSPATH}.

Property File Outisde of .WAR file

I need to be able to read in a property file, that lives outside of my war. My problem is that a need a solution that will allow me to tell my war file where my property file is located. Can this be done through bashrc variables and windows env variables?
I need to do this because I need to be able to drop the property file in different locations that could be away from the war file.
I am struggling to come up with a solution.
This will very much depends what the property file is for. Some libraries will have have the possibility of setting it on the command-line and others will allow you to explicitly load them in code.
In case of the latter, System.getProperties() can prove helpful, since it allows you to read properties passed to the JVM using the '-D' flag. For example
java -jar -Dfilelocation="yourfilelocation" yourapp.jar
would populate the system property 'filelocation' with the string 'yourfilelocation'. This could then be used in your code to load the property file (or whatever you want to do with it).
Since you are running inside some sort of application server, there are different ways you can accomblish this. For jetty you can put them in start.ini (or simply pass them on the command-line when you start jetty)
where tomcat uses an enviroment variable called JAVA_OPTS, so
JAVA_OPTS='-Dfilelocation=yourfilelocation' start.sh
would set the system property when you start tomcat.
one way is to provide specific location by passing java argument or setting up environment varialble and read it from app to determine the location
and as a fallback (default) app should be announcing to look at
${user.home}/appname/some.peroperties
You could defines a list of possible directories ... and try to read each one ...
I have a solution that read a property file in the file system using a default directory structure.
Eg: c:\properties\code-suit\prd\application.properties
Where:
code-suit is a variable defined by application name;
prd is a environment that I will use
Good luck

Android - use ant to create build configurations that change configuration values

What I want is a way to have settings that are dependent on build configuration. To give a specific example, my android application connects to a web service. In development, I want the service url to be pulled in from a configurable value. In Test, I want a different value pulled in. In production, yet another value.
So, in code I have something like this:
public class HttpRequestHelper
{
private static String GetServiceUrl(ServiceAction action)
{
return serviceUrl + action.toString();
}
}
By default (when debugging/running through eclipse), I want that url to be http://localhost:1234
In Test I want https://test.mydomain.com
In Production I want https://mydomain.com
I am new to eclipse and ant and it has been a long time since I used java. How do I go about setting this up? What should the build.xml look like? I understand that when I want to build the test/prod versions I will need to use the command line. That's okay. But I don't know how to get this serviceUrl auto-set dependent on the build. I'm not even sure the best place to put this information (a resource, a properties file?). I really want to avoid setting it, building, setting it, building, etc.
As answers mentioned above says, you have to place the URLs in a property file like dev.properties, test.properties, prod.properties etc..
Now only thing that you need to do is making your build intelligent enough to choose a property file depending upon environment.
That can be done by passing a parameter to ANT, something like:
$ ant -file MyBuild.xml -DcurrentEnv=dev (For Development environment)
$ ant -file MyBuild.xml -DcurrentEnv=test (For Test)
$ ant -file MyBuild.xml -DcurrentEnv=prod (For Production)
Inside your build script, this is how you can include your property file:
<target name="jarMe">
<jar destfile="sample.jar" basedir="src" includes="${currentEnv}.properties"/>
</target>
With this in place, whatever name you supply at the time of build, property file with that name will be picked up.
You could try to have a following property file in your build.properties file:
service.url=*
And you could have http://localhost:1234 or https://test.mydomain.com in local.properties for your development and integration testing, and it could be set to https://mydomain.com in default.properties.
By do ing this, you have will get different value for service.url in different build environment. You could use that value to generate a config file, and parse it into your code, or set it to env variable, or just put it into a resource file, and Android will read it for you:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="service-url">##toben_to_be_replaced_during_build_time##</string>
</resources>
I would start by placing the urls into a properties file that you can then place onto the classpath. Make a test and a production properties file. Then depending on the build place the correct file onto the classpath and pull the properties at runtime.
Found a tutorial which goes through all the details of using ant to automate a build system, to create and use build configurations, as well as to build the release project with one command. Here it is: http://www.androidengineer.com/2010/06/using-ant-to-automate-building-android.html
Seems a little long, but it goes through all the steps and details involved.

Does Ant Support File-based Dependencies?

I would like to make an ant dependency where the target file depends on a source file. How do you describe this in ant?
For example, convert this Make target to ant
data.txt: header1.txt body.txt footer.txt
cat header1.txt body.txt footer.txt > data.txt
You might be able to do something like this, but it's starting to sound like scripting. Ant isn't a scripting language. If you have a lot of "if/then/else" logic in mind you're probably doing it wrong.
Please describe "other data". Are we talking about copying files? Is this a devl/test/prod environment issue? In that case, you can certainly pass in a parameter specifying environment name and using conditional tests to decide which set to copy. Read this to see how.
If you're just wanting to bring files in one directory up-to-date with respect to your source tree,
you might use the sync task. Here's a basic example from the docs:
<sync todir="site">
<fileset dir="generated-site"/>
</sync>
overwrites all files in site with
newer files from generated-site,
deletes files from site that are not
present in generated-site.
If you need to determine which resources need update,
in order to carry out a more complex operation than a sync,
you might use the ant-contrib outofdate task. For example
<outofdate property="compile.needed" outputsourcespath="sources.for.recompile">
<sourcefiles>
<fileset dir="${src}" includes="*.c"/>
</sourcefiles>
<mapper type="glob" dir="${src}" from="*.c" to="${obj}/*.o"/>
</outofdate>
will set compile.needed to true if any object files are out-of-date compared to source,
and also set the path sources.for.recompile with a list of just the sources that need recompile -
you can then compile for just those sources.
(The assumption here is that a single file in the build output area is directly related to one source.)
My simple solution right now is to manually add a test for the source/dest file age in my shell script called from exec task in ant.

Categories

Resources