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)

Users

Following users will be configured:

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

Networking

Set a static IP:

# system-config-network

Configure eth0 with static IP:

IP: 192.168.1.XX
NETMASK: 255.255.255.0
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/
# ./vmware-install.pl

Users

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

NFS

# 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

Appending:

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

NTPD

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

JDK6

NOTE:
- It seams that JBoss supports JDK6 since 4.3.0-CP03 https://issues.jboss.org/browse/JBPAPP-1272
- 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 http://download.oracle.com/otn/java/jdk/6u29-b11/jdk-6u29-linux-x64.bin

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

JBoss

Go here https://access.redhat.com/ and download JBEAP-4.3.0.GA_CP09/jboss-eap-4.3.0.GA_CP09.zip

To install simply unzip the file

# unzip jboss-eap-4.3.0.GA_CP09.zip
# mv jboss-eap-4.3 /opt/

Setting jboss user base option and environment [optional]:

# nano /home/jboss/.bash_profile
-----------------APPEND------------------
PATH=$HOME/bin:$PATH
export JAVA_HOME="/usr/lib/jvm/jdk1.6.0_29/"
PATH=$JAVA_HOME/bin:$PATH
export GDAL_HOME="/opt/gdal/"
export GDAL_DATA="$GDAL_HOME/share/gdal"
PATH=$GDAL_HOME/bin/:$PATH
export LD_LIBRARY_PATH="$GDAL_HOME/lib/:$LD_LIBRARY_PATH"
export JBOSS_HOME=/opt/jboss-eap-4.3/jboss-as/
PATH=$JBOSS_HOME/bin:$PATH
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:

NOTE:
Here we also set the GEOSERVER_DATA_DIR as external:

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

#gdal
export GDAL_HOME="/opt/gdal/"
export GDAL_DATA="$GDAL_HOME/share/gdal"
#logging
JBOSS_LOG_DIR=/opt/jboss-eap-4.3/jboss-as/server/default/logs/

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 jboss_init_redhat.sh in the bin directory so that the variables match the installation.

 # nano /opt/jboss-eap-4.3/jboss-as/bin/jboss_init_redhat.sh

The script jboss_init_redhat.sh 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.

------------------------------------------------------------------------
 #!/bin/sh
 #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=""
 else
 SUBIT="su - $JBOSS_USER -c "
 fi
 ----------------------------------------------------------

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

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

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

------------------------------------------------------------------------
JBOSS_HOME=${JBOSS_HOME:-"/opt/jboss-eap-4.3/jboss-as/"}
------------------------------------------------------------------------

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

------------------------------------------------------------------------
JBOSS_USER=${JBOSS_USER:-"jboss"}
------------------------------------------------------------------------

JBOSS_CONF
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_CONF=${JBOSS_CONF:-"production"}
 ------------------------------------------------------------------------

JAVAPTH

------------------------------------------------------------------------
JAVAPTH=${JAVAPTH:-"/usr/lib/jvm/jdk1.6.0_29/bin"}
------------------------------------------------------------------------

JBOSS_HOST
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 127.0.0.1.

------------------------------------------------------------------------
#if JBOSS_HOST specified, use -b to bind jboss services to that address
JBOSS_HOST=192.168.1.X
JBOSS_BIND_ADDR=${JBOSS_HOST:+"-b $JBOSS_HOST"}
------------------------------------------------------------------------

Link script into init.d:

Create a symbolic link to jboss_init_redhat.sh 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/jboss_init_redhat.sh /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/jmx-console-users.properties

And set USERNAME and PASSWORD:

USERNAME=PASSWORD

Geoserver

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

# wget http://gridlock.opengeo.org/geoserver/2.1.x/geoserver-2.1.x-latest-war.zip
# unzip /root/geoserver-2.1.x-latest-war.zip
# 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"
        name="geoserver.war"
        parent-first="false"   
        domain="GeoServerDomain"
        top-level-classloader="true"
        parent-domain="Ignored"
        export-all="NON_EMPTY"
        import-all="true">
</classloading>
--------------------------------------------------------------------

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

stax-api-1.0.1.jar
xercesImpl-2.4.0.jar
xml-apis-1.0.b2.jar
xml-apis-xerces-2.7.1.jar
xpp3-1.1.3.4.O.jar

PostgreSQL Ver 9.1

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

# wget http://yum.pgrpms.org/9.1/redhat/rhel-5-x86_64/pgdg-centos91-9.1-4.noarch.rpm
 # 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

PL/pgSQL

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             192.168.1.0/24            md5
 ------------------------------------------------------------

Remember to restart the PostgreSQL service:

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

NOTE:
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:

-------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------
# - 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)
-------------------------------------------------------------------------------

NOTE:
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
NOTE:
 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="org.jboss.tm.XidFactory"
      name="jboss:service=XidFactory">
<!-- <attribute name="Pad">true</attribute> -->
   </mbean>

And uncomment the ‘Pad’ attribute as follow:

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

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

SQL> connect / as BATABASE
Connected.
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
'java:OracleDS'

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 😉

References:

GeoSolutions

http://www.geo-solutions.it

JBoss Installation guide

http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/4.3/html/Installation_Guide/Getting_Started.html

Intallation specifications

http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/4.3/html-single/Release_Notes_CP09/index.html

Compatibility and tested configurations

http://www.jboss.com/products/platforms/application/supportedconfigurations/#JEAP4.3

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.

Notes

Dependencies

  1. xmlstarlet
  2. bash

Usage

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

Example

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)

Enjoy,

Carlo Cancellieri