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

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.

Related

Micronaut + Maven - Environment variables

I am working on a Micronaut + Maven project.
I need to parametrize some values of my application.yml such as passwords and connection strings, to avoid committing them.
I know values can be parametrized this way:
secret-value: '${SECRET_VALUE}'
But i cant find any other way to set SECRET_VALUE except setting bash value in .bashrc or .profile or .envoirment script files.
I would like to use a .env file somehow, in order to commit a .env.example file in git repo.
Any thoughts?
According to maven-resource-plugin documentation :
https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
You could add a filter file in the filters tag of your pom file.
See we can separate "your.name" from the POM by specifying a filter file my-filter-values.properties containing: in the documentation above.
I may have lost the focus of the question.
the solution was simply create a .env file with required values, then run application using something like
dotenv run ./mvnw mn:run.
regarding #yunandtidus solution:
That is good only for "fixed" variables, such as application name, as pom values are shared between environments (assuming that we have an application-dev.yml and an application-prod.yml).
Keep in mind that, unlike .env, pom.xml must be committed, as any application.yml you have.

Adding environment variables to Spring's application.properties

I want to run two Amazon S3's SDK information from the application.properties, but instead of putting it in the file, I want to add them when running ./mvnw spring-boot:run. I saw something like this could be done:
./mvnw spring-boot:run -Dspring-boot.run.arguments="--srp.storage.s3.access-key=FOOBARFOOBAR,--srp.storage.s3.secret-key=foobarfoobarfoobarfoobarfoobar"
I tried running the command above with quotes around the arguments and with/without whitespace between them. Also, I tried leaving blank values in the properties files as well as removing them at all.
# srp.storage.s3.access-key=
# srp.storage.s3.secret-key=
srp.storage.s3.access-key=
srp.storage.s3.secret-key=
I have a class annotated with #ConfigurationProperties("srp.storage"). The results of these attempts varied from application failing to start because no property was found by the class, to actually running but taking no effect. The variations of the command that caused the server not to start was not specifying any property in application.properties and attempting to run the command with and without quotes and no whitespace. The scenario that it ran but did not take effect was putting whitespace.
I know about running it using the built JAR file, but I want to be able, if possible, to run it like that just to prevent building every time I change something.
Also attempted to specify placeholder as shown here, but again no success. Can I even do what I want using ./mvnw? Or must it be with a JAR file?
srp.storage.s3.access-key=${access-key}
srp.storage.s3.secret-key=${secret-key}
./mvnw spring-boot:run -Dspring-boot.run.arguments="--access-key=FOOBARFOOBAR,--secret-key=foobarfoobarfoobarfoobarfoobar"
Solved using environment variables. That's good enough for me.
It goes without saying you can choose any name you want for the property in Spring's file and variable, just remember that in Linux environments you must set the variable names all capital letters and use underscore.
In .bashrc or .zshrc or similar, add:
export AWS_S3_ACCESS_KEY=FOOBARFOOBAR
export AWS_S3_SECRET_KEY=foobarfoobarfoobarfoobarfoobar
And as shown before, in the application.properties file, add;
srp.storage.s3.access-key=${AWS_S3_ACCESS_KEY}
srp.storage.s3.secret-key=${AWS_S3_SECRET_KEY}
And start normally. Much better.
If you are using gradle and have bootRun task available then you can configure the task to read the args passed while running the task.
Add the following to your build file.
bootRun {
if (project.hasProperty('params')) {
args project.params.split(",")
}
}
Then you can run the following command.
.\gradlew.bat bootRun -Pparams=--demo.prop=commandlinearg
I had a field annotated as the following
#Value("${demo.prop}")
private String prop;

Micronaut PropertySource for multiple configuration files

I have a micronaut project where I want to have an unnversioned configuration file for private data (like database connections and so on)
This information have to be loaded through #Property annotation, but since there will be more than one .yml (there will also be at least an application.yml) y want to be able to provide file's path to #Properties to be able to differentiate where to look for property.
Since it's my first micronaut project I'm a bit lost with this stuff but taking springboot as an example, what I want to do is something like:
#PropertySource("classpath:configprops.properties")
But after reading micronaut documentation(https://docs.micronaut.io/latest/guide/index.html#configurationProperties) I found myself unable to do this (except from something like just reading the plain file which I guess would not be micronaut compliant)
I do it by passing jvm arguments.
For example, If I am running it on my local machine using gradle:run, I add following to build.grade
run.jvmArgs('-Dmicronaut.environments=dev', "-Dmicronaut.config.files=${System.getProperty("user.home")}/auth-config.groovy")
For my jar deployment, I have made a deploy.sh file as follows :
#!/bin/bash
fuser -k 8181/tcp
nohup java -Xmx512m -Dmicronaut.environments=staging -Dmicronaut.config.files=<path-to-config>/config.groovy -jar application-0.1-all.jar > application.log 2>&1 &
Also note that I am passing different environment names, this helps you to include development environment config directly in code if you want.
Like
application-[environment_name].groovy
application-[environment_name].yml
application-[environment_name].properties
This will help new contributors on your project to speedup the process project setup, I generally also include note in my application-dev.groovy file
DEVELOPER NOTE:
***** DO NOT COMMIT ANY CHANGE IN THIS FILE IF YOU MAKE ANY
*******************************************************
***** CREATE <config.groovy> file in your <HOME> folder and copy paste content of this file
***** Override properties as required
*******************************************************

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.

Building with ant : dynamic build options?

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).

Categories

Resources