Replace variables into a text file using bash

Hi all,
today I was looking around to see the easiest way to replace variables into a text file with no success so I decided to write a very simple tool to make it possible.

The problem:

We have a text file (xml, txt, csv, etc) and we want to replace some sections using incoming variables.

Example file:

Text to use as template for user:
name: $NAME
code: $CODE
tel: $TEL

Now we want to replace those variables (imagine we are using a very long file with many different variables…)

So let’s build the variable file:

Example variables file:

NAME="Mario, Rossi"

Now we want to build the file to obtain:

Resulting FILE:

 Text to use as template for user:
 name: Mario, Rossi
 code: 523456
 tel: 555001890

Now we could use the simple proposed script to do the job.

The script:
 if [ $# -ne 3 ]; then
   echo "USAGE:
         ./$0 template.txt destination.txt variables.txt"
   exit 1
echo "#!/bin/bash
cat > $2 << EOF
`cat $1`
EOF " > $2;
chmod +x $2;
# load variables into env
. $3
# actually replace variables

It is intentionally simple (no checks) but works 😉

How to use it:

./ template.txt out.txt variables.txt


 This is an extensible way to produce configurable files.
 Undefined variables (into the variable file) will not be replaced.
 Undefined variables (into the template file) will not be used.
 You could also use environment variables into the template.

Carlo Cancellieri


Copy a VMWare Virtual Machine

this post is to show you how to use the script which can be downloaded here:

This script is intended to be an easy way to copy/clone a VMWare Virtual Machine changing in one shot:

  1. The name showed into the VMWare menu
  2. The virtual disk file names
  3. The folder file name


Using VMWare GUI interface in fact you will not be able to change the disk and file name of the VM to clone:

How to use

The script is really simple (and limited) you should use it with careful, following these simple steps:

  • Go into the VMWare server (player) administration interface and stop the VM you want to clone
  • Login on the shell of the machine where the VM is running.
  • Go to the folder where the VM is stored, this is usually:
$ cd /var/lib/vmware/Virtual\ Machines/
  NOTE: This folder contains spaces this is not standard
  • Perform a backup of the VM to clone, place it to a better (without spaces) location 😉
    I use /opt/vm/
$ cp virtualMachine_folder /opt/vm/ -Rpav
  NOTE: The script will not work properly with folder containing spaces
  • Run the script as following
./ UbuntuFolder32Bit Ubuntu32Bit Cloned_Folder32Bit Cloned_32Bit


  1. UbuntuFolder32Bit is the relative path of the folder where the VM is stored
  2. Ubuntu32Bit is the name of the VM to clone
  3. Cloned_Folder32Bit is the relative path used for the new cloned VM
  4. Cloned_32Bit will be the name of the cloned VM


To get a cloned copy of the ActiveMQ VM (to quickly rise up a VM to use as failover broker) run:

./ ActiveMQ ActiveMQ ActiveMQ_failover ActiveMQ_failover

Now import the newly created VM into the VMWare server (or player) and check about its configuration:


Note: the name of the VM and the configuration file are aligned.

Future plans:

1. Mount virtual disk to change IP and hostname
2. Add checks to make it more simple and safe

Carlo Cancellieri

How to configure a cluster of services using Apache httpd:

How to configure a cluster of services using Apache httpd:

This is a small how to to help you to configure a proxy with load balancer to distribute requests between multiple instances of tomcat (slaves), running the same service.

 This is done using the proxy_ajp module.

Stop you httpd daemon:

 /etc/init.d/httpd stop

If you do not want to stop it at the end of this how to configuration run:

/etc/init.d/httpd reload

Backup the default proxy_ajp configuration:

mv  /etc/httpd/conf.d/proxy_ajp.conf  /etc/httpd/conf.d/proxy_ajp.conf.old

Edit a new one:

nano /etc/httpd/conf.d/frontend.conf
<VirtualHost *:80>
LoadModule proxy_ajp_module modules/
<IfModule mod_proxy_ajp.c>
    ProxyRequests Off
    ProxyTimeout 300
    ProxyPreserveHost On
    ProxyVia On
    <Proxy balancer://cluster>
               BalancerMember ajp://XXX.XXX.XXX.XXX:8008 route=jvm0
               BalancerMember ajp://XXX.XXX.XXX.XXX:8009 route=jvm1
               ProxySet lbmethod=bytraffic
               # ProxySet lbmethod=bybusyness
    <Location /balancer-manager>
       SetHandler balancer-manager
       AuthType basic
       AuthName "GeoSolutions"
       AuthUserFile "/etc/httpd/passwd/passwords"
       # Anonymous *
       Require valid-user
    <Location /my_service>
       Order allow,deny
       Allow from all
       ProxyPass balancer://cluster/my_service stickysession=JSESSIONID

Detailed description:

In this configuration we have configured 2 different instances of tomcat using the ajp connector (on ports 8009, 8008).

The Proxy node contains all the BalancerMember of the cluster. Each BalancerMember points to a tomcat instance using the ajp protocol (through its route: see below).

 <Proxy balancer://cluster>
               BalancerMember ajp://XXX.XXX.XXX.XXX:8008 route=jvm0
               BalancerMember ajp://XXX.XXX.XXX.XXX:8009 route=jvm1
               ProxySet lbmethod=bytraffic
               # ProxySet lbmethod=bybusyness

The traffic is routed bytraffic but you may chose a different algorithm (see Proxy doc).

Note also that we have configured a route for each slave, all of the above settings should be done into the ${CATALINA_BASE}/conf/server.xml file of each tomcat slave instance:

Set the ajp connector port:

 <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>

Set the route name into the Engine node:

<!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">         
    <Engine defaultHost="localhost" name="Catalina" jvmRoute="jvm0">

The incoming requests is redirect from the proxy to the load balancer by:

<Location /my_service>
       Order allow,deny
       Allow from all
       ProxyPass balancer://cluster/my_service stickysession=JSESSIONID

Note that we also have attached the stickysession to the proxy pass option, this is needed to be able to use authentication in my_service application, further requests will be redirected to the same slave used to perform login (otherwise you’ll have to perform login to each request or, at least randomly).

The following section is optional and is configured to show you how to configure also a basic authentication on your service. This is useful to check the configuration using your browser:

    <Location /balancer-manager>
       SetHandler balancer-manager
       AuthType basic
       AuthName "My_auth_name"
       AuthUserFile "/etc/httpd/passwd/passwords"
       # Anonymous *
       Require valid-user

Point your browser to http://localhost/balancer-manager to see the manager.

To configure a basic authentication account:

Create a password file:

# mkdir /etc/httpd/passwd
# touch /etc/httpd/passwd/passwords

Create the user:

# htpasswd -c /etc/httpd/passwd/passwords USER
Password: PASSWORD

Start the daemon:

# /etc/init.d/httpd start

or using chkconfig:

# chkconfig --add httpd
# chkconfig httpd on


  • Each request to http://localhost/ is redirected to one of your tomcat instances depending on the incoming traffic and accordingly to the chosen lbmethod.
  • Session id is preserved thanks to the sticky session option so you will be redirect to the same slave you logged in.
  • You are able to check the status of each Balancer Member using your browser (protected by authentication)


Carlo Cancellieri

Setup javaplugin for firefox under Ubuntu

the following steps can be used to setup javaplugin in firefox under [K|U]buntu.

TESTED ON:  firefox 9.1 on Kbuntu 10 [success]

Check which is your Ubuntu version:

$ cat /etc/lsb-release

Add new repository (for java sun):

add-apt-repository 'deb lucid partner'

Install required packages:

# apt-get purge openjdk-6-jre openjdk-6-jre-headles
# apt-get update
# apt-get install sun-java6-plugin sun-java6-fonts

Keep updated the java alternative: [optionally]

# update-alternatives --config java

Create alternative for java plugin:

# update-alternatives --install /etc/alternatives/ javaplugin /usr/lib/jvm/java-6-sun/jre/lib/amd64/ 1

Link new libraries to firefox:

# ln -sf /etc/alternatives/ /usr/lib/mozilla/plugins/
# ln -sf /usr/lib/jvm/java-6-sun/jre/lib/amd64/ /usr/lib/mozilla/plugins/

Restart Firefox and go to:


To check if it works… that’s it!
Carlo Cancellieri


GeoServer on JBoss

Hi all,
currently I’m working @ GeoSolutions on the integration of the GeoServer on an existing JBoss installation.

To be able to easily perform tests I configured all on a 64Bit CentOS 5.7 Virtual Machine on VMWare.

Note also that to use JBoss you need to acquire a license so I used a Jboss 30 days trial which can be freely downloaded from the JBoss site. Looking at this page, you could use the 4.2.1 from the JBoss community site

VM Minimum requirements

  • CPU 2
  • RAM (3Gb – if JBoss is set using 1.5Gb for Heap)


Following users will be configured:

  1. root / PASSWORD
  2. jboss / (no login)
  3. postgres / postgres


Set a static IP:

# system-config-network

Configure eth0 with static IP:

IP: 192.168.1.XX
GATEWAY: 192.168.1.X

Edit also DNS settings:

DNS1: 192.168.1.X
DNS2: x.x.x.x
DNS3: x.x.x.x

Set firewall using:

# system-config-securitylevel

Not needed for our purposes so disable it.

VMWare tools

Install VMWare tools as following:

# mount /dev/hdc /media/
# tar -xvf /media/VMwareTools-7.7.6-203138.tar.gz -C .
# cd vmware-tools-distrib/
# ./


# useradd -r jboss -s /bin/false -m -G adm,users -d /home/jboss


# yum install nfs-utils portmap

Due to the small size of the VM configured (only 4Gb) I mounted an external share to be able to handle data. To do so, edit the fstab file:

# nano /etc/fstab


192.168.1.XX:/media/share/    /media/share        nfs rw,exec,auto,users,rsize=8192,wsize=8192,timeo=14,intr    0 0

Where 192.168.1.XX is the IP of the target NAS and /media/share/ is the shared directory (mounted in the same path locally).

Now create directory, change permissions and mount the share:

# mkdir /media/share
# chgrp users /media/share
# mount /media/share


# yum install ntp
# /etc/init.d/ntpd start
# chkconfig ntpd on


- It seams that JBoss supports JDK6 since 4.3.0-CP03
- JBPAPP-4172 Attempting to install the IBM JDK 1.5 on 64-bit Red Hat Enterprise Linux 5 results in broken links to Java binaries. This prevents the application server from starting. The workaround for this issue is to use the Sun JDK 1.6 instead.

So we can use the JDK6.
Let’s download it (you need to accept the license):

# wget

Run the binary:

# sh jdk-6u29-linux-x64.bin
# mkdir -p /usr/lib/jvm/

Move into java home:

# mv jdk1.6.0_29 /usr/lib/jvm/jdk1.6.0_29

Update alternatives:

# update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_29/bin/java 1
# update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_29/bin/javac 1
# update-alternatives --config java
# update-alternatives --config javac


Go here and download JBEAP-4.3.0.GA_CP09/

To install simply unzip the file

# unzip
# mv jboss-eap-4.3 /opt/

Setting jboss user base option and environment [optional]:

# nano /home/jboss/.bash_profile
export JAVA_HOME="/usr/lib/jvm/jdk1.6.0_29/"
export GDAL_HOME="/opt/gdal/"
export GDAL_DATA="$GDAL_HOME/share/gdal"
export JBOSS_HOME=/opt/jboss-eap-4.3/jboss-as/
export PATH
export GEOSERVER_DATA_DIR="/opt/data/geoserver/"

Change permissions:

# chown -R jboss.jboss /opt/jboss-eap-4.3/

Memory settings can be adjusted by updating JAVA_OPTS settings in the file JBOSS_DIST/jboss-as/server/production/run.conf with these recommended values:

Here we also set the GEOSERVER_DATA_DIR as external:

# nano /opt/jboss-eap-4.3/jboss-as/server/production/run.conf
# 16Jan2012 Added in append
export GEOSERVER_DATA_DIR="/opt/data/geoserver/"

export GDAL_HOME="/opt/gdal/"
export GDAL_DATA="$GDAL_HOME/share/gdal"

JAVA_OPTS="$JAVA_OPTS -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC-XX:NewSize=48m -DGEOSERVER_DATA_DIR=$GEOSERVER_DATA_DIR -Djboss.server.log.dir=$JBOSS_LOG_DIR”

Edit in the bin directory so that the variables match the installation.

 # nano /opt/jboss-eap-4.3/jboss-as/bin/

The script in the bin directory is the script used to launch the server as a service. Append the following lines to the beginning of this script so that the first four lines below the initial comments look like those below.

 #chkconfig: 2345 85 15
 #description: JBoss Enterprise Application Platform
 #processname: jboss

These lines are needed by the chkconfig command.
Note that the chkconfig option specifies the runlevel, start priority, and stop priority. 2345 specifies the server will start only in runlevels 2, 3, 4, and 5.

Change also:

 if [ "$JBOSS_USER" = "RUNASIS" ]; then
 SUBIT="su - $JBOSS_USER -c "

Appending ‘-s /bin/sh’ to command:

 if [ "$JBOSS_USER" = "RUNASIS" ]; then
 ## CHANGED on 16Jan2012
 #  SUBIT="su - $JBOSS_USER -c "
 SUBIT="su - $JBOSS_USER -s /bin/sh -c "

This is the path of the JBoss Enterprise Application Platform’s jboss-as directory. This value must be set here.


This is the user created previously for running the JBoss Enterprise Application Platform.  The example sets it to the user name of jboss:


This is the name of the server configuration that the server will be using.
The example sets it to default. The profiles available to use are contained in the /jboss-as/server/ directory.




JBOSS_HOST must be specified when binding the JBoss Enterprise Application Platform server to a specific IP address. This must be done before JBOSS_HOST is used by JBOSS_BIND_ADDR.

This must be configured to make the server available on the network. The default configuration binds the server to the IP address of

#if JBOSS_HOST specified, use -b to bind jboss services to that address

Link script into init.d:

Create a symbolic link to in the directory /etc/init.d/. The name of the target of the symbolic link is the name of the new service.

 # ln -s /opt/jboss-eap-4.3/jboss-as/bin/ /etc/init.d/jboss_eap

Activate Service
Use the command chkconfig with the –add parameter to add the new service to the system configuration.

 #chkconfig --add jboss_eap

Configure Startup and Shutdown Behavior
Use the command chkconfig with the on parameter to start the service at boot time, and stop it gracefully when the server hosting the application server is shut down or restarted.

 #chkconfig jboss_eap on

Enable JMX console:

Be sure to enable JMX section: (<application-policy name = “jmx-console”>)

#nano /opt/jboss-eap-4.3/jboss-as/server/production/conf/login-config.xml

Edit the file:

#nano /opt/jboss-eap-4.3/jboss-as/server/production/conf/props/




The used GeoServer is a nightly build in version: 2.1.x (SNAPHOT)

# wget
# unzip /root/
# unzip geoserver.war -d /opt/jboss-eap-4.3/jboss-as/server/production/deploy/geoserver.war
# chown jboss.jboss /opt/jboss-eap-4.3/jboss-as/server/production/deploy/geoserver.war
# mkdir /opt/data/geoserver
# chown jboss.jboss /opt/data/geoserver

Remove GeoWebCache [Optional]:

# rm `find /opt/jboss-eap-4.3/jboss-as/server/production/deploy/geoserver.war/WEB-INF/lib/ -name *gwc*` -f
# /etc/init.d/jboss_eap restart

ClassLoader isolation [Optional]:

GeoServer do not require (for this version of JBoss class loader isolation) anyway it should be done as following:

# nano /opt/jboss-eap-4.3/jboss-as/server/production/deploy/geoserver.war/WEB-INF/jboss-classloading.xml
<classloading xmlns="urn:jboss:classloading:1.0"

For JBoss 5 and above, remember to remove following libs: (As specified in the GeoSolutions blog post)


PostgreSQL Ver 9.1

To install PostgreSQL server 9 we need to add some deps:

# wget
 # rpm -i pgdg-centos91-9.1-4.noarch.rpm
 # yum install postgresql91-contrib.x86_64 postgis91.x86_64 postgresql91-server postgresql91-contrib.x86_64 proj geos php-pear php-devel


You you are ready to initialize the database files and start postgresql.

 $ service postgresql-9.1 initdb
 $ service postgresql-9.1 start

Now you can change to the postgres user and begin installing the functions for GIS. You have to start with defining the language.

$ su - postgres
$ psql
# create language plpgsql;
# ALTER USER postgres with encrypted password 'postgres';
# q

Now you can create your database and add the GIS functions calls to it.

 $ createdb geos
 $ psql -d geos -f /usr/pgsql-9.1/share/contrib/postgis-1.5/postgis.sql
 $ psql -d geos -f /usr/pgsql-9.1/share/contrib/postgis-1.5/spatial_ref_sys.sql

Edit the file:

$ nano /var/lib/pgsql/9.1/data/pg_hba.conf

set ‘local’ and ‘host’ as follow:

 local   all             all                                     md5
 # IPv4 local connections:
 host    all             all               md5

Remember to restart the PostgreSQL service:

$ exit
# /etc/init.d/postgresql-9.1 restart

This is a really general purpose (and not really safe) set-up, please ref to PostgreSQL documentation to understand how to refine modified params.

Edit also this file:

$ nano /var/lib/pgsql/9.1/data/postgresql.conf

as following:

# - Connection Settings -
#listen_addresses = 'localhost'         # what IP address(es) to listen on;
listen_addresses = '*'
                                       # comma-separated list of addresses;
                                       # defaults to 'localhost', '*' = all
                                       # (change requires restart)
port = 5432                             # (change requires restart)
max_connections = 100                   # (change requires restart)

This is a really general purpose set-up, please ref to PostgreSQL documentation to understand how to refine modified params.

Setup Postgresql JDBC datasource:

Now you can configure a JBoss datasource to connect to the configured database using a connection pool:

# mv /opt/jboss-eap-4.3/jboss-as/server/production/deploy/geoserver.war/WEB-INF/lib/postgresql-8.4-701.jdbc3.jar /opt/jboss-eap-4.3/jboss-as/server/production/lib/
# cp /opt/jboss-eap-4.3/jboss-as/docs/examples/jca/postgres-ds.xml /opt/jboss-eap-4.3/jboss-as/server/production/deploy/

Edit the file setting username, password, database, url and port of the running PostgreSQL server:

# nano /opt/jboss-eap-4.3/jboss-as/server/production/deploy/postgres-ds.xml
 You may also want to set the queries to check the connection.

Setup Oracle JDBC datasource:

# cp ojdbc14.jar /opt/jboss-eap-4.3/jboss-as/server/production/lib/
# cp /opt/jboss-eap-4.3/jboss-as/docs/examples/jca/oracle-ds.xml /opt/jboss-eap-4.3/jboss-as/server/production/deploy/oracle-ds.xml

Change connection parameters setting username, pass, url, sid and port::

# nano /opt/jboss-eap-4.3/jboss-as/server/production/deploy/oracle-ds.xml

Edit the file:

# nano /opt/jboss-eap-4.3/jboss-as/server/production/conf/jboss-service.xml

Search for:

<!-- The configurable Xid factory.  For use with Oracle, set pad to true -->
   <mbean code=""
<!-- <attribute name="Pad">true</attribute> -->

And uncomment the ‘Pad’ attribute as follow:

<!-- The configurable Xid factory.  For use with Oracle, set pad to true -->
   <mbean code=""
      <attribute name="Pad">true</attribute>

Is assumed that you’ve created a user with all the sufficient privileges.

SQL> connect / as BATABASE
SQL> create user jboss identified by password;
User created.
SQL> grant DATABASE to jboss;
Grant succeeded.

Copy the file to the deploy directory. You should get the following output.

11:33:45,174 INFO  [WrapperDataSourceService] Bound connection factory for resource adapter
for ConnectionManager 'jboss.jca:name=OracleDS,service=DataSourceBinding to JNDI name

If you use the JNDIView service from the JMX console as before, you should see the name java:/OracleDS listed.

That’s it!

If you need more info or if you want to install native libraries and extensions for the configured GeoServer, please contact me 😉



JBoss Installation guide

Intallation specifications

Compatibility and tested configurations

Import a Spring project into eclipse using maven


Hi,  here is a little How-To which i use to remind which are the needed (and very well tested) options to use in my maven projects 😉

The Eclipse plug-in specs can be found HERE

To include the plug-in into a maven project all you need to do is to add the following plugin node:

 <!-- eclipse ide integration -->

To use the plugin run:

mvn eclipse:clean eclipse:eclipse

To get the version into the project name use:


When you specify the above maven eclipse plugin option the eclipse project name will use the version specified into the pom file (${project.version}).

Sometime you may encounter a project build path problem. To solve, read below.

By default the org.eclipse.jdt.core.javanature nature plus the needed WTP natures are added.
Natures added using this property replace the default list.


List of eclipse project natures to be added to the default ones:


This is the result:

 <!-- eclipse ide integration -->

Now we could build the project. I usually use the following command which also imports javadocs and sources to make development more comfortable:

mvn eclipse:clean eclipse:eclipse -DdownloadSources=true  -DdownloadJavadocs=true -Declipse.addVersionToProjectName=true

Have fun with Spring and maven 😉

How to easily change the version in a complex maven project

In this post I’d like share the work I performed in GeoSolutions to change the version in a complex maven project (GeoBatch for instance).

If you are working on huge and modular maven project you may need to recursively update the version of the project in all of the pom.xml files.
This can be done using a very simple bash script, (patch are really appreciate) which can downloaded here.



  1. xmlstarlet
  2. bash


USAGE: src/bash/changeVersion {-n|-b|-c} <BASE_DIR> <NEW_VERSION>
-n dry run
-b run (perform backup)
-c run (no backup)
0 if success
1 if fails


To update the project located in /works/MY_PROJECT from the previous version to the new version (for example 1.1-SNAPSHOT) do:

$./changeVersion -n /works/MY_PROJECT/ 1.1-SNAPSHOT

This will print all the found pom.xml file recursively after the update. Note that -n options mean that changes are not actually applied to the project.

To do so use -b or -c (use it with carefully)


Carlo Cancellieri