aspose file tools*
The moose likes Ant, Maven and Other Build Tools and the fly likes Modify build xml to replace words in an xml or properties file based on a text file Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Engineering » Ant, Maven and Other Build Tools
Bookmark "Modify build xml to replace words in an xml or properties file based on a text file" Watch "Modify build xml to replace words in an xml or properties file based on a text file" New topic
Author

Modify build xml to replace words in an xml or properties file based on a text file

Marcelo Tataje
Ranch Hand

Joined: Jan 31, 2011
Posts: 64

Hello everybody, sounds confusing isn't it? But I'm facing a requirement in which the application can be deployed in a scenario depending on its IP, PORTS and keystore paths.
To be more clear, my application contains a configurationFile.properties which contains the following:

ip.adress.key = YOUR_IP_ADDRESS_HERE
keystore.config.path = YOUR_KEYSTORE_PATH_HERE
keystore.config.pass = YOUR_KEYSTORE_PASS_HERE
port.number.key = YOUR_PORT_NUMBER_HERE

I want to replace the values of the keys during the build based on a custom text file the programmer can edit, for example myProperties.txt which contains:

your_ip = 200.48.225.10
your_keystore_path = /etc/certs/java.jks
your_keystore_pass = 12345
your_port = 8443

In addition to this I have to include the values in a wsdl file, for instance:



So the idea is to get the values from the text file and set them into the properties files and the xml files during the build. Well, that's the requirement I've been asked for, I think it's possible, maybe using maven-replacer-plugin or an script inside the build xml.

If somebody could help me please, I would really appreciate. Thanks in advance.
Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5823
    
    7

What build tool are you using? Both Ant and Maven have the concept of file filtering. You usually place token of property references in the source file, for example:

ip.adress.key = ${YOUR_IP}
keystore.config.path = ${YOUR_KEYSTORE_PATH}
. . .


then the user provide a properties file which the build script reads:

YOUR_IP=200.48.225.10
YOUR_KEYSTORE_PATH=/etc/certs/java.jks
. . .

For Ant, use the <copy> task with ExpandProperties FilterChain. For Maven, turn on resource filtering.

Or actually, your config file would look like this:



Copying that file would replace the properties with the values.


JBoss In Action
Diwakar Shenoy
Greenhorn

Joined: Feb 01, 2012
Posts: 4

Marcelo,

Here is how you could achieve this using ANT:

1. Create your text properties file: say, ApplicationServer.txt with the server specific information like port, ip etc as key values :
ip.adress.key = YOUR_IP_ADDRESS_HERE
keystore.config.path = YOUR_KEYSTORE_PATH_HERE
keystore.config.pass = YOUR_KEYSTORE_PASS_HERE
port.number.key = YOUR_PORT_NUMBER_HERE

2. Create a template "configurationFile.properties" in some folder in your project say, build with machine parameters :
ip.adress.key = ${ip.adress.key}
keystore.config.path = ${keystore.config.path}
keystore.config.pass = ${keystore.config.pass}
port.number.key = ${port.number.key}

3. create a target in your build file like this. Assuming your files from (1) and (2) are lying in the same folder as your build.xml:

<target name="replaceConfigParamaters">
<filter filtersfile="ApplicationServer.txt"/>
<copy todir="YOUR_DESTINATION_DIRECTORY_FOR_CONFIGURATION_FILE" filtering="true">
<fileset dir="." includes="*.properties"/>
</copy>
</target>


Marcelo Tataje
Ranch Hand

Joined: Jan 31, 2011
Posts: 64

Hello friends,

Thanks for the proposed solution, I've been trying to implement this with ant, but I don't have a build.xml, my project is a multi module project, a Web Service which uses two other projects as libraries, the pom files were made to make the project independent from the IDE. So the structure is:

-----/root directory
----------pom.xml (parent pom)
----------/io-library-project directory
-------------------------pom.xml
----------/transport-library-project directory
-------------------------pom.xml
----------/webservice-project
-------------------------pom.xml

I think the solution will be very similar in case of maven using pom.xml to define the functionality I have problems with. But both of you give me a very good point to start implementing this, thanks!
If you have any example of how could it be using maven, I'll really appreciate it. Thanks for the solutions
Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5823
    
    7

Here is a simple example using the config files you posted:

First, the project directory layout:


configurationFile.properties contents are exactly like what Diwakar posted.
wsdlport.xml is what I posted for the <wsdl:port> XML snippet (plus he rest of that XML file, is there is anything else)

Then the pertinent pom.xml settings:


The configure the Maven Properties plugin to read your properties file. http://haroon.sis.utoronto.ca/zarar/properties-maven-plugin/index.html

That should be it. The filtered files should appear in target/classes. If you want them elsewhere, rearrange the source location of add directives to the Resources plugin.
Marcelo Tataje
Ranch Hand

Joined: Jan 31, 2011
Posts: 64

Peter

Thank you so much, it works perfectly with the read-properties-plugin and I already managed to make the pom.xml read the properties file to set the values of ip, port, paths, etc.

I'm now having an issue with the "filtering" tag. The project contains the source files, the structure of the "src" folder is like this:

PROJECT ROOT
-(dir)library project
-(dir)transport project
-(dir)webservice project
------(dir)src
---------------(dir)main
-----------------------(dir)java
----------------------------(dir)code package
----------------------------config.properties (this is my properties file where I set the variables for pom build)
----------------------------log4j.xml (here I also set variables to stablish the path where logs are stored in xml)
----------------------------soap-handler-resolvers.xml
-----------------------(dir)webapp
---------------------------(dir)META-INF
--------------------------------context.xml
---------------------------(dir)WEB-INF
--------------------------------sun-jaxws.xml
--------------------------------web.xml (here I set a path to define the userfolder in which messages are stored)
--------------------------------(dir)wsdl
-------------------------------------wsdlfile.wsdl (this is the wsdl file copied when I use wsimport, here I set the port, ip and custom name of my service)
---------------(dir)test
---------------(dir)wsdl
--------------------wsdlfile.wsdl (This is the wsdl attached for the users, but I need to replace the values here also)
------pom.xml
-pom.xml

The structure of my web service project is very complex, I don't know how to reflect it but the problem is that when I execute the pom and the build finishes, the target folder generates a classes directory and a war file, inside my classes directory, the values for the properties files and xml files are changed but when I open the war to see the contents, there are some of the properties that are not replaced and stay with the ${port.value} and so on. I think it's because the filtering tag.

My filtering tag inside resource is as follows:



And for the webResources is like this:



I put the src root folder as directory because I want to change ALL the references in all files when building the war, but it doesn't replace all the values and it generates even more files and makes the war size bigger.

I'm looking for some solution to this issue. Thanks in advance for the help to everybody
Marcelo Tataje
Ranch Hand

Joined: Jan 31, 2011
Posts: 64

In addition to the previous post, I wonder if it's a way, command or tag that let pom replace the properties in every single file found, I mean like make a lookup or search and replace in all the files that contains references to variables, I mean, to ensure that every value replaces the variable in every single file when the target directory is generated.

Thanks in advance
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Modify build xml to replace words in an xml or properties file based on a text file