Thoughts and Tutorials about Continuous Integration, Application Integration, SOA, IT Architecture, WebSphere and Liferay

Oct 25, 2014

SOAP Exception while installing application to WebSphere with wsadmin

When deploying (larger) applications to WebSphere with wsadmin scripting some times a SOAP Exception occurs. This is due to a low default SOAP timeout. wsadmin uses internally SOAP to communicate with the WebSphere instance.

Exception message:
WASX7017E: Exception received while running file "<your-path>\install_app.py";
exception information:
com.ibm.websphere.management.exception.ConnectorException
[wsadmin] Caused by: [SOAPException: faultCode=SOAP-ENV:Client;
msg=Read timed out; targetException=java.net.SocketTimeoutException:
Read timed out]

Solution:
To increase the timeout locate the soap.client.props file of your locale and remote profile and set the com.ibm.SOAP.requestTimeout to a higher value
#------------------------------------------------------------------------------
# SOAP Request Timeout
#
# - timeout (specified in seconds [default 180], 0 implies no timeout)
#
#------------------------------------------------------------------------------
com.ibm.SOAP.requestTimeout=1800

How to activate access and error logs for WebSphere

Webservers typically provide so called access and error logs for diagnosting incomming http requests.
This logs are activated by default for Apache webserver and IBM HTTP Server.

Java EE application servers do have a web container that also serve http content. However the access and error logs are disabled by default for Websphere.

To active the access and error logs go to
Servers > Server types > WebSphere application servers > <your-server-name> > NCSA access and HTTP error logging

Select "Enable logging service at server start-up" and make sure that "Enable access logging" and "Enable error logging" are selected. Restart the server afterwards.



The NCSA access log format specifies which format is used when logging client information.
  • Common: The log entries contain the requested resource and other some http informations. Example log entry:
    0:0:0:0:0:0:0:1 - - [25/Oct/2014:10:41:08 +0200] "GET /wasPerfTool/dtd/ HTTP/1.1" 200 -
  • Combined: In addition to the common format, the log entries contains the referral, the user agent, and cookie.
    Example log entry:
    0:0:0:0:0:0:0:1 - - [25/Oct/2014:10:48:31 +0200] "GET /wasPerfTool/dtd/ HTTP/1.1" 200 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36" "-"
The error logging level simply defines the detail of the logged information.

Oct 19, 2014

Asynchronous beans and methods in WebSphere

The Java EE specification does NOT allow to (manually) create threads in order to parallelize work.
Manually created threads usually result in warnings like this:

ThreadMonitor W   WSVR0605W: Thread "Default : 0" (<ThreadID>) has been active for xxx milliseconds and may be hung.  There is/are 1 thread(s) in total in the server that may be hung.
Example log entry:
WSVR0605W: Thread "WebContainer : 124" (0000045c) has been active for 666666 milliseconds and may be hung.  There is/are 3 thread(s) in total in the server that may be hung.

The root cause is that the threads are running outside of the Java EE context. The application server has no control over them.

In WebSphere versions < 8 (without Java EE 6) IBM offers the so called Asynchronous Beans to solve this issue. This blog article discribes the usage of Asynchronous Beans in WebSphere 7.

Since WebSphere 8 (Java EE 6) it's possible to use asynchronous method invocation.

Simply add an @Asynchronous annotation to the method.

@Stateless
public class AsyncService {
    @Asynchronous
    public void doAsyncWork(){
         
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Async work done");
    }
}

A sample asynchronous method invocation project for WebSphere Application Server 8.5.5. can be downloaded here. 

The WebSphere administration console allows you to config the basic setups of the underlying thread pool used for the asynchronous handling.
It is also possible to create custom Work Manager instance for a more large-scale setup ("Use custom work manager instance"). The default setup uses the DefaultWorkManager. The DefaultWorkManager is a shared resource, also used for other asynchronous work tasks of the application server (!).
To create a custom (and dedicated) Work Manager go to Resources > Asynchronous beans > Work managers > New ... and create a new Work Manager instance.


Oct 14, 2014

How to use EJB Timers in WebSphere

WebSphere Application Server supports the scheduler interface of Java EE. Each server process has its own embedded derby database to handle the persistent timers. Persistent timers persist through restarts of the application server.

To use the embedded derby timer database now additional configuration is required.
Just simply deploy your EJB Timer Service to the server process (e.g. server1).

The following source code shows a very simple EJB Timer service which prints out a message every 10 seconds. A wrapping ejb timer example project can be downloaded here.

import javax.ejb.Schedule;
import javax.ejb.Stateless;
/*
 *
 * Stateless Bean which prints out time in milliseconds every 10 seconds
 *
 */
@Stateless
public class TimerService {
  
    @Schedule(second="*/10", minute="*",hour="*", persistent=true)
    public void doIt(){
        System.out.println("time: " + System.currentTimeMillis());
    }
}

Setting up an persistent cluster timer requires a WebSphere ND installation - and some additional setup tasks,
If you want to enable persistent
timers in a cluster you need to switch to an external database system like Oracle, DB2 or MqSQL.

First create a JDBC / JNDI Datasource to this external database and then navigate to
Servers > Server Types > WebSphere Application Servers > <server-name> >  EJB timer service settings
and select the newly created datasource as " under "Persistent EJB timer configuration" and "Use internal EJB timer service scheduler instance".