javaee Posts

A Simple HTTPS Configuration Example on Apache Tomcat 6

This idea comes suddenly on my head while i was reading a question on Kaskus’ programmer forum about how to setup a https connection on Apache Tomcat, thats why today im trying to write a simple how-to example on creating a simple HTTPS connection using Apache Tomcat 6. Who knows perhaps someone would find it useful.

Let’s start with creating a simple certificate file using keytool.exe

C:\Program Files\Java\jdk1.6.0_19\bin>keytool.exe -genkey -alias tomcat -keyalg RSA -keystore edw.jks

after you insert your keystore password (i entered “secret” as my password) and several simple questions such as “What is your first and last name?”, it would create a file.

What you need to do next is to link your certificate to Tomcat’s server.xml configuration. This is what i add to my server.xml configuration.

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" keystoreFile="D:\edw.jks" 
               keystorePass="secret" />
<!-- keystorePass use the same password -->

And i also add this to my web.xml file, located under my tomcat’s conf folder

	<security-constraint>
		<web-resource-collection>
			<web-resource-name>Automatic SLL Forwarding</web-resource-name>
			<url-pattern>/*</url-pattern>
		</web-resource-collection>
		<user-data-constraint>
			<transport-guarantee>CONFIDENTIAL</transport-guarantee>
		</user-data-constraint>
	</security-constraint>

This is what my page will look like,

Hope it would help others, cheers (B)

Creating A New WebSphere Instance

Im planning to create more than 1 WebSphere instance on my box, im using a CentOS for development, and IBM AIX for production. On this example i have an instance named “AppSrv01” and trying to create a new WebSphere instance “AppSrvTeller”. Btw, im using WAS 6.1 on my box.

Okay here we go,
first is executing manageprofiles.sh to create a new profiles, when im executing manageprofiles.sh -help -create, it will print

The following command line arguments are required for this mode.
Command-line arguments are case sensitive.
-create: Creates a new profile. Specify -help -create -templatePath <path> to get template-specific help information.
-templatePath: The fully qualified path name of the profile template that is located on the file system. The following example selects a template: -templatePath <app_server_home>/profileTemplates/<Template_name>
-profileName: The name of the profile.
-profilePath: The intended location of the profile in the file system.

The following command line arguments are optional, and have no default values.
Command-line arguments are case sensitive.
-isDefault: Make this profile the default target of commands that do not use their profile parameter.
-omitAction: Omit optional features.

you just provide the needed parameters, well in my case i’ll show you what i write on my console

[root@localhost bin]# uname -a
Linux localhost.localdomain 2.6.18-128.el5 #1 SMP Wed Jan 21 10:44:23 EST 2009 i686 i686 i386 GNU/Linux
[root@localhost bin]# pwd
/opt/IBM/WebSphere/AppServer/bin
[root@localhost bin]# sh manageprofiles.sh -create -profileName AppSrvTeller -templatePath /opt/IBM/WebSphere/AppServer/profileTemplates/default/ -profilePath /opt/IBM/WebSphere/AppServer/profiles/AppSrvTeller
INSTCONFSUCCESS: Success: Profile AppSrvTeller now exists. Please consult /opt/IBM/WebSphere/AppServer/profiles/AppSrvTeller/logs/AboutThisProfile.txt for more information about this profile.

Hope it can help others (H)

How to Set Timezone on WebSphere Application Server

It’s actually quite easy, but a little tricky. This is how i do it,

1. Start the administrative console.
2. In the topology tree, expand Servers and click Application Servers.
3. Click the name of the application server for which you want to set the time zone.
4. On the application server page, click Process Definition.
Process Definition
5. On the Process Definition page, click Java Virtual Machine.
6. On the Java Virtual Machine page, click Custom Properties.
7. On the Custom Properties page, click New.
8. Specify user.timezone in the Name field and timezone in the Value field, where timezone is the supported value for your time zone.
9. Click Apply.
10. Save the configuration

In this example, i’m setting my timezone as Asia/Jakarta

user.timezone=Asia/Jakarta  

Timezone Success

Have fun with WebSphere (*)

Clustering and Session Replication Using Glassfish 3.1

Sometimes we need to replicate sessions between clustered environment to make sure session failovers. In this tutorial im trying to clustered 2 Glassfish instances located in the same computer, create a simple webapps and try to see whether session in instance 1 replicated to instance 2. I dont know why but Glassfish 3.0 seems doesnt support clustering so im using Glassfish version 3.1 instead.

Lets start by starting Glassfish, go to /bin and start it from command promt by typing asadmin start-domain domain1.

After it started, go to Glassfish console from your browser. Glassfish console URL will be http://localhost:4848/. Login and start creating a cluster from Clusters menu.

Start your cluster,

congratulation, you have started your cluster. Lets see details from each instances,

it shows your instance’s http port.

To test our session replication, i create a simple web application using Netbeans 6.9.
First is a simple jsp file, index.jsp

<%@page import="java.util.Enumeration"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Session Form</h1>

        <%
                    if (request.getParameter("sessionName") != null && request.getParameter("sessionValue") != null) {
                        HttpSession httpSession = request.getSession();
                        httpSession.setAttribute(request.getParameter("sessionName"), request.getParameter("sessionValue"));
                    }
        %>

        <form action="index.jsp" method="POST">

            your session name : <input type="text" name="sessionName" /> <br />
            your session value : <input type="text" name="sessionValue" /> <br />
            <input type="submit" />

        </form>

        <h1>Your Sessions</h1>

        <%
                    Enumeration sessionNames = session.getAttributeNames();
                    while (sessionNames.hasMoreElements()) {
                        String mySessionName = sessionNames.nextElement().toString();
                        String mySession = request.getSession().getAttribute(mySessionName).toString();
                        out.print(mySessionName+ " --> "+mySession + " <br />");
                    }
        %>

    </body>
</html>

And the most important is the web.xml configuration,

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <distributable id="sessionDistribute" />
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Build it into a war app and deploy it to our clustered environment, always make sure the Availability option checked as enabled.

After you launch it, input some value to jsp page in instance1 and save it. It will save your values to a session.

open instance2’s jsp page and check whether your instance1’s session is there.

As you can see, your sessions from instance 1 is replicated and available from instance 2.

Have fun using Glassfish. 🙂

A Client Server Application using Spring HTTP Invoker

Right now, im trying to create a simple client-server application using spring HTTP invoker. One major advantage using Spring Http Invoker is that instead of the custom serialization found in Hessian and Burlap, HTTP invoker uses Java serialization — just like RMI. Applications can rely on full serialization power, as long as all transferred objects properly follow Java serialization rules (implementing the java.io.Serializable marker interface and properly defining serialVersionUID if necessary).

Because of the nature of HTTP invoker (which is available only in Spring), both the client side and the server side need to be based on Spring — and on Java in the first place because of the use of Java serialization. In contrast to Hessian and Burlap, there is no option for cross-platform remoting. HTTP invoker is clearly dedicated to powerful and seamless Java-to-Java remoting.

Okay, let me show you my client side’s code, first is a very simple bean.

package com.edw.bean;

import java.io.Serializable;
import java.math.BigDecimal;

public class BeanBego implements Serializable {
    private String nama;
    private int usia;
    private double gaji;
    private float x;
    private float y;
    private BigDecimal z;

    public String getNama() {
        return nama;
    }

    public void setNama(String nama) {
        this.nama = nama;
    }

    public int getUsia() {
        return usia;
    }

    // other setters and getters

next is an interface to connect with the server side application.

package com.edw.service;

public interface TestService {

    void doNothing();

    String doSomething(String something);
    String doSomething(Object something);
}

and this is my client’s side Spring configuration. Take a look at line 6, it is my server side’s application location. And on line 7, is my interface class.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean id="testHttpInvoker" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
        <property name="serviceUrl" value="http://localhost:8084/SpringHttpInvokerServer/testService.service"/>
        <property name="serviceInterface" value="com.edw.service.TestService"/>
    </bean>
</beans>

and this is my application’s main class,

package com.edw.spring.main;

import com.edw.bean.BeanBego;
import com.edw.service.TestService;
import java.math.BigDecimal;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    private Logger logger = Logger.getLogger(this.getClass());

    public Main() throws Exception {
    }

    private void execute() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        TestService testService = (TestService) applicationContext.getBean("testHttpInvoker");

        BeanBego beanBego = new BeanBego();
        beanBego.setGaji(2000000000d);
        beanBego.setUsia(500);
        beanBego.setX(500000000f);
        beanBego.setY(6000000f);
        beanBego.setZ(new BigDecimal(Double.MAX_VALUE));

        String testString = "";
        for (int i = 0; i < 2000; i++) {
            testString += " " + i + " pepe ";
        }

        beanBego.setNama(testString);

        logger.debug(testService.doSomething(beanBego));
    }

    public static void main(String[] args) throws Exception {
        Main main = new Main();
        main.execute();
    }
}

and now lets create the server side’s application, btw im using Apache Tomcat as my web server, first i copy my BeanBego class and TestService interface from client’s side to the server side. After that, i create the implementation of TestService interface,

package com.edw.service;

import com.edw.bean.BeanBego;
import org.apache.log4j.Logger;

public class TestServiceImpl implements TestService {

    private Logger logger = Logger.getLogger(this.getClass());

    public void doNothing() {
        logger.debug("im doing nothing");
    }

    public String doSomething(String something) {
        logger.debug("im doing something");
        return "connect successfully";
    }

    public String doSomething(Object something) {
        logger.debug("im doing something");

        if(something instanceof BeanBego)
            return ((BeanBego)something).getGaji()+"";
        return "not a BeanBego instance";
    }
   
}

next step is registering your class to your main Spring configuration, remember to named it “remoting-servlet.xml”.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <bean id="testService" class="com.edw.service.TestServiceImpl"/>

    <bean id="testHttpInvoker" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service">
            <ref bean="testService"/>
        </property>
        <property name="serviceInterface">
            <value>com.edw.service.TestService</value>
        </property>
    </bean>
    
    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/testService.service">testHttpInvoker</prop>
            </props>
        </property>
    </bean>

</beans>

and register your remoting-servlet.xml on your web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
			/WEB-INF/remoting-servlet.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>remoting</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>remoting</servlet-name>
        <url-pattern>*.service</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

try to deploy it on your app-server. After that, try to execute your client side’s application. This is what happen on my server’s console

RemoteInvocationTraceInterceptor] DEBUG org.springframework.remoting.support.RemoteInvocationTraceInterceptor:73 - Incoming HttpInvokerServiceExporter remote call: com.edw.service.TestService.doSomething
[TestServiceImpl] DEBUG com.edw.service.TestServiceImpl:26 - im doing something
[RemoteInvocationTraceInterceptor] DEBUG org.springframework.remoting.support.RemoteInvocationTraceInterceptor:79 - Finished processing of HttpInvokerServiceExporter remote call: com.edw.service.TestService.doSomething
[DispatcherServlet] DEBUG org.springframework.web.servlet.DispatcherServlet:909 - Null ModelAndView returned to DispatcherServlet with name 'remoting': assuming HandlerAdapter completed request handling
[DispatcherServlet] DEBUG org.springframework.web.servlet.DispatcherServlet:591 - Successfully completed request

and this on my client’s console

[JdkDynamicAopProxy] DEBUG org.springframework.aop.framework.JdkDynamicAopProxy:113 - Creating JDK dynamic proxy: target source is EmptyTargetSource: no target class, static
[DefaultListableBeanFactory] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory:411 - Finished creating instance of bean 'testHttpInvoker'
[DefaultListableBeanFactory] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory:214 - Returning cached instance of singleton bean 'testHttpInvoker'
[SimpleHttpInvokerRequestExecutor] DEBUG org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor:133 - Sending HTTP invoker request for service at [http://localhost:8084/SpringHttpInvokerServer/testService.service], with size 21766
[Main] DEBUG com.edw.spring.main.Main:41 - 2.0E9

this is my project structure, btw ignore the jasypt.jar and commons-lang.jar on my project classpath, im not using them on this project.
my Netbeans 6.9 Client side's project structure

my Netbeans 6.9 Server side's project structure

If you are looking about a good Spring book, i would highly recommend “Professional Java Development with the Spring Framework”, Published by Wiley Publishing, Inc. FYI im using Spring 2.5.6

Have fun coding it, (H)