Wednesday, December 23, 2009

Start Apache as service in Linux (Fedora)

The Apache HTTP server is installed by default in all Linux distributions and it is configured to run as service. I usually prefer to install Apache from source instead of using the default one. After installing Apache I want to run that instance as service so that it can be restarted automatically whenever machine is rebooted. This can be achieved easily by modifying /etc/rc.d/init.d/httpd file, which is configured to run the Apache installed with OS.

Comment the following section, though it is not required but I prefer to keep all configuration at one place


if [ -f /etc/sysconfig/httpd ]; then
        . /etc/sysconfig/httpd
fi
Modify the following lines-
apachectl=/usr/sbin/apachectl
httpd=${HTTPD-/usr/sbin/httpd}
prog=httpd
pidfile=${PIDFILE-/var/run/httpd/httpd.pid}
to point towards your Apache installation
apachectl=/opt/apps/httpd-2.2.14/bin/apachectl
httpd=${HTTPD-/opt/apps/httpd-2.2.14/bin/httpd}
prog=httpd
pidfile=${PIDFILE-/opt/apps/httpd-2.2.14/logs/httpd.pid}
Now your custom Apache instance will be started by OS instead of the default one.

Thursday, December 10, 2009

Send XML data over web service

Occasionally I am being asked a common question, "How to send XML data over web service?". In Java (in fact in any programming language) XML is just a string (sequence of characters). So sending XML as request parameter or receiving it in response is just like handling any other string data.

For the following XML data from web service client and server-

XML from client
<name>vinod</name>

XML from server
<greeting>Hello! vinod</greeting>

This is the web service (JAX-WS) request and response-
REQUEST
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:xmlData xmlns:ns2="http://vinodsingh.com">
            <data>&lt;name&gt;vinod&lt;/name&gt;</data>
        </ns2:xmlData>
    </S:Body>
</S:Envelope>

RESPONSE
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:xmlDataResponse xmlns:ns2="http://vinodsingh.com">
            <return>&lt;greeting>Hello! vinod&lt;/greeting></return>
        </ns2:xmlDataResponse>
    </S:Body>
</S:Envelope>

The above example clearly shows that JAX-WS runtime handles XML strings pretty well. The source code available here includes an example of sending bigger XML data.

Tuesday, December 01, 2009

JTA Transactions with Atomkios in Tomcat

Tomcat is the leading Java Servlet container. Many of our applications do not need full blown Java EE Application Server and a Servlet container like Tomcat is more than enough to run them even in production. Some of our applications need JTA transactions capabilities, which are not provided by Tomcat out of the box. There are very few open source JTA implementations. JOTM used to be most popular among them, unfortunately its development is dead for last several years though it seems to getting revived lately at its new home. Atomikos is another JTA implementation, which was open sourced (Transactions Essentials) when JOTM went into hibernation.

Integrating Atomikos with Tomcat is fairly easy, it can be done by following simple steps given below-

Create a configuration file for Atomikos at $TOMCAT_HOME/lib/transactions.properties location with contents like below-

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.automatic_resource_registration=true
com.atomikos.icatch.output_dir=../work
com.atomikos.icatch.log_base_dir=../work
com.atomikos.icatch.enable_logging=true
com.atomikos.icatch.console_log_level=INFO

Define a DataSource in $TOMCAT_HOME/conf/context.xml as shown below-

<Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory" />

<Resource name="jdbc/pgDS"
                auth="Container"
                type="com.atomikos.jdbc.AtomikosDataSourceBean"
                factory="com.vinodsingh.atomikos.tomcat.DataSourceBeanFactory"
                uniqueResourceName="jdbc/pgDS"
                xaDataSourceClassName="org.postgresql.xa.PGXADataSource"
                xaProperties.serverName="localhost"
                xaProperties.portNumber="5432"
                xaProperties.databaseName="test"
                xaProperties.user="test"
                xaProperties.password="test"
                maxPoolSize="3"
                minPoolSize="1" />

Copy following files to $TOMCAT_HOME/lib directory-
  • JDBC driver of the Database being used.
  • JTA API (jta-1.1.jar).
  • Atomikos Essentials (transactions-essentials-all-3.5.9.jar), name may change according to the version being used.
  • Tomcat integration jars available at Atomikos' site or atomikos-tomcat.jar built from the source code attached with this post.
All these changes will make UserTransaction object available in Tomcat's JNDI tree and it can be used in same way as we do in any regular Java EE application server. An example of using UserTransaction is shown in following code snippet-
public String insertRecord(String value) {
    UserTransaction utx = null;
    try {
        utx = ServiceLocator.getTrasactionManager();
        utx.begin();
        // Do transactional work
        pgDAO.insertRecord(value);

        // commit the transaction
        utx.commit();
    } catch (Exception e) {
        try {
            if (utx != null)
                utx.rollback();

            String msg = "Oops! Transaction is rolled back due to an exception";
            log.error(msg, e);
            return msg;
        } catch (Exception e1) {
            log.error("Failed to rollback the transaction", e1);
            return "Failed to rollback the transaction" + e1.getMessage();
        }
    }
    return "Transaction succeded";
}
To see transactions in action compile the attached source code, deploy the generated jta.war on Tomcat and open http://localhost:8080/jta/ URL in your browser. Thats all it takes to integrate Atomikos JTA transactions in Tomcat.

Note:-
  1. Though Atomikos' documentation about Tomcat 6 integration talks about configuring AtomikosLifecycleListener in $TOMCAT_HOME/conf/server.xml as well. But Atomikos seems to work well inside Tomcat without that configuration.
  2. Here I have slightly modified the code for Tomcat integration from what is available at Atomikos website, more details about the same will follow in upcoming posts.

Source code for this post is available here.