Set up Tomcat, Apache and mod_jk cluster

In this article I will go through a common set-up for a small production environment. A single tier, load balanced application server cluster.

Overview

A high level overview of what we will be doing.

  1. Downloading and installing Apache HTTP server and mod_jk
  2. Downloading Tomcat
  3. Downloading Java
  4. Configuring two local Tomcat servers
  5. Clustering the two Tomcat servers
  6. Configuring Apache to use mod_jk to forward request to Tomcat
  7. Deploying application to Tomcat server that tests our set-up

Introduction

What is Apache?

Apache is an HTTP server.

What is mod_jk?

It is an Apache module that allows AJP communication between Apache and a back end application server like Tomcat.

I am running this on Ubuntu 14.04LTS installed on a dual boot PC with Windows 7.

Application Server Cluster

 

Download Apache2

We are going to use Ubuntu’s APT package maintenance system to obtain and install Apache2.

sudo apt-get install apache2

This will install in /etc/apache2

Download and install mod_jk

The mod_jk module is not included in the Apache2 download so must be obtained and installed separately. The installation requires that the mod_jk module is visible to Apache and configured to ensure that Apache knows where to look for it and what to do with the requests you want to proxy.

sudo apt-get install libapache2-mod-jk

This will install in /etc/libapache2-mod-jk also two files have been added to the /etc/apache2/mods-available folder.

Downloading and installing Tomcat 8

At the time of writing this Tomcat 8 does not have a package in APT so you must download the binaries from the tomcat website.

http://tomcat.apache.org/download-80.cgi select the appropriate binary distribution and extract it as follows.

tar xvzf apache-tomcat-8.0.5.tar.gz

We need two copies of the Tomcat server to be load balanced. I created two directories in the /opt/ location: /opt/tomcat-server1/ and /opt/tomcat-server2/ and copied tomcat into each one.

Download and install Java

Download Java from APT as follows:

apt-get install openjdk-7-jdk

and set JAVA_HOME in .bashrc

vim ~/.bashrc
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64

Configure two local Tomcat servers

We will edit only the server.xml of the server2 installation of tomcat. We need to change port numbers to avoid conflicts.

We change the following:

<Server port="9005" shutdown="SHUTDOWN">
<Connector port="9009" protocol="AJP/1.3" redirectPort="9443"/>

and comment out the HTTP Connector as we only want the web application to be accessible through the load balancer.

Here is my server2 Tomcat server.xml configuration.

Configure mod_jk

Load balancing is configured in the workers.properties file, located /etc/libapache2-mod-jk/ where workers represent actual or virtual workers.We will define two actual workers and two virtual workers which map to the Tomcat servers. In the worker.list property I have defined two virtual workers: status and loadbalancer, I will refer to these later in the Apache configuration.

Workers for each server have been defined using values for the server.xml configuration files. I used the port values for the AJP connectors and I have included an lbfactor that sets the preference that the load balancer will show for that server.

Finally we define the virtual workers. The loadbalancer worker is set to type lb and set the workers that represent the Tomcat servers in the balancer_workers properties. The status only needs to be set to type status.

worker.list=loadbalancer,status 

worker.server1.port=8009
worker.server1.host=localhost
worker.server1.type=ajp13 

worker.server2.port=9009
worker.server2.host=localhost
worker.server2.type=ajp13 

worker.server1.lbfactor=1
worker.server2.lbfactor=1 

worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=server1,server2 

worker.status.type=status

Ensure that you remove any other worker configuration that are not being used.

Configure Apache Web Server to forward requests

You will need to add the following to the Apache configurations located in etc/apache2/sites-enabled/000-default.conf

JkMount /status status
JkMount /* loadbalancer

Verify the installation

To test that all has been configured correctly we need to deploy an application. A sample application that has been used for years to test such configurations is called the ClusterJSP sample application. You can find it by googling in or from the JBoss site.

Now deploy the war to the webapps folder on both servers and start each server using the start-up script /opt/tomcat-server1/bin/startup.sh.

Go to http://localhost/clusterjsp/HaJsp.jsp and you should see the page show HttpSession information.

Cluster - HA JSP Sample

Now lets look at the mod_jk status page: http://localhost/status. You will see that this page shows information about the load balancer workers and the workers it is balancing.

Workers

If everything is working you will see the worker error state show OK or OK/IDLE if they are not currently balancing load.

Things to try out

Enable sticky sessions: Configure jvmRoute in the server.xml configuration.

Further reading

Loadbalancing with mod_jk and Apache

Working with mod_jk

Connecting Apache’s Web Server to Multiple Instances of Tomcat

Java EE revisits the Factory Pattern

The factory pattern is a creational design pattern whose intent is to provide an interface for creating families of related or dependent objects without specifying their concrete classes. The creational logic is encapsulated within the factory which either provides a method for its creation or delegates the creation of the object to a subclass. The client is not aware of the different implementations of the interface or class. The client only needs to know the factory to use to get an instance of one of the implementations of the interface. Clients are decoupled from the creation of the objects.

Often the factory pattern is implemented as a singleton or a static class as only one instance of the factory is required. This centralizes the object creation.

CDI Framework

In Java EE we can take advantage of the CDI framework to create objects without knowing the details of their creation. The decoupling occurs as a result of the way Java EE implements inversion of control. The most important benefit this conveys is the decoupling of higher-level-classes from lower level classes. This decoupling allows the implementation of the concrete class to change without affecting the client: reducing coupling and increasing flexibility.

The CDI framework itself is an implementation of the factory pattern. The container creates the qualifying object during application start up and injects it into any injection point that matches the injection criterion. The client does not need to know anything about the concrete implementation of the object, not even the name of the concrete class is known to the client.

public class CoffeeMachine implements DrinksMachine {
    // Implementation code
}

Use it like so:

@Inject
DrinksMachine drinksMachine;

Here, the container creates an instance of the CoffeeMachine concrete class, it is selected based on its interface DrinksMachine and injected wherever the container finds a qualifying injection point. This is the simplest way to use the CDI implementation of the factory pattern. However its not the most flexible.

Disambiguation

What happens if we have more than one concrete implementation of the DrinksMachine interface?

public class CoffeeMachine implements DrinksMachine {
    // Implementation code
}

public class SoftDrinksMachine implements DrinksMachine {
    // Implementation code
}

Which implementation should be injected? SoftDrinksMachine or CoffeeMachine?

@Inject
DrinksMachine drinksMachine;

The container does not know and so deployment will fail with an “ambiguous dependencies” error.

Qualifiers

So how does the container distinguish between concrete implementations? Java EE gives us a new tool: Qualifiers. Qualifiers are custom annotations that mark the concrete class and the point where you want the container to inject the object.

Returning to our Drinks machine and the two concrete classes of the same type CoffeeMachine and SoftDrinksMachine we would distinguish them by the use of two qualifier annotations:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface SoftDrink
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Coffee

We create one qualifier name SoftDrink. This will annotate the SoftDrinksMachine concrete class and Coffee will annotate the CoffeeMachine class.

The @Target annotation restricts where we can use these qualifiers to mark injection points, in this case on method and field injection points. The annotation with retention policy RUNTIME ensures that the annotation is available to the JVM through runtime.

The possible values for Target are: TYPE, METHOD, FIELD, PARAMETER.

The two concrete implementations of the DrinksMachine interface are annotated appropriately. The CoffeeMachine class is annotated @Coffee while the SoftDrinksMachine class is annotated @SoftDrink.

@Coffee
public class CoffeeMachine implements DrinksMachine {
    // Implementation code
}
@SoftDrink
public class SoftDrinksMachine implements DrinksMachine {
    // Implementation code
}

Now you annotate the injection points. Use the qualifier @SoftDrink to denote where you want the container to inject the SoftDrinksMachine class and the qualifier @Coffee where you want the container to inject the CoffeeDrinkMachine. Now we have made it clear to the container where our concrete implementations should be injected and deployment will succeed.

@Inject @SoftDrink
DrinksMachine softDrinksMachine;
@Inject @Coffee
DrinksMachine coffeeDrinksMachine;

We have seen how Java EE’s CDI framework is an implementation of the factory pattern, how it hides the concrete implementation of an object and allows the creation to be decoupled from its use. We have seen how qualifiers are used to select the required implementation without the need to know anything about the objects creation.

It is important to remember that the CDI framework will only instantiate POJOs that meet all of the conditions of the managed beans specification JSR 299. But what if the object you want to inject doesn’t, does that mean we cannot take advantage of the CDI framework’s injection capabilities for classes that don’t comply. No it doesn’t. Java EE provides us with a solution. Lets dive deeper and look at how we can use the CDI framework to inject ANY class of ANY type into an injection point.

Producer Methods

Java EE has a feature called producer methods. These methods provide a way to instantiate and therefore make available for injection objects that don’t conform to the managed bean specifications such as objects which require a constructor parameter for proper instantiation. Objects whose value might change at runtime and objects whose creation requires some customised initialization can also be produced ready for injection via a producer method.

Lets have a look at a producer method which produces a List populated with Books objects.

@Produces
@Library
public List<Book> getLibrary(){
    // Generate a List of books called 'library'
    return library;
}

A list of Book objects will be injected into the injection point annotated @Library.

Use it like so:

@Inject @Library
List<Books> library;

An important feature of the producer method is its scope. This will determine when the method is invoked and for how long the object it produces will live.

By default the producer method scope is @DependentScoped. This means that it inherits the scope of its client.

We can extend this example further by giving it a wider scope. If we annotate the producer method @RequestScoped it will be invoked only once for each HTTP request in which it participate, lasting for the duration of the request.

@RequestScoped
@Produces
@Library
public List<Book> getLibrary(){
    // Generate a List of books called 'library'
    return library;
}

Possible scopes are:

RequestScoped – HTTP Request Scope
SessionScoped – HTTP Session Scope
ApplicationScoped – Shared across users
ConversationScoped – Interactions with JSF
DependentScoped – Default, inherits from client

  • The Good: easy to implement, no boilerplate code, works magically, any object can be made injectable, Automatic per class configuration
  • The Bad: named annotation is not type safe
  • and the ugly: object creation hidden, hard to follow execution flow, IDE should help

Context Dependency Injection

The Java EE programming model has been simplified substantially since J2EE. Annotations have replaced the XML description files, convention over configuration have replaced the tedious manual configuration and dependency injection hides the creation and look up of resources.

Resources are created and injected at injection points marked by annotations such as @Inject. All you need is a POJO that meets all of the conditions of the managed beans specification JSR 299 and depending on the annotation used it will become an EJB, servlet, singleton or RESTful web service.

The object is injected by the container and is determine by type. However using an interface as a type can confuse the container if there is more than one concrete implementation. It doesn’t know which object to inject. This confusion can be resolved by the use of a qualifier annotation that marks the concrete implementation you want to implement. We will see how this annotation is used with @Producer in the implementation of the factory pattern. Beans or objects that you want to inject that do not conform to JSR299 use the @Producer annotation to make them injectable.

JSR 299 Managed bean specification

It is not a nonstatic inner class.

It is a concrete class or is annotated @Decorator.

It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in ejb-jar.xml.

It has an appropriate constructor. That is, one of the following is the case:

The class has a constructor with no parameters.

The class declares a constructor annotated @Inject.

No special declaration, such as an annotation, is required to define a managed bean.
To enable CDI you must have a beans.xml file in your project (under the META-INF or WEB-INF).

The beginning of Design Patterns

The beginning

Did they just appear overnight? Where did they come from? In fact design patterns have a long history starting way before computing, in architecture. That’s the construction type of architecture. But it wasn’t really until the GOF wrote their seminal book Design patterns, that the concept of design patterns was cemented in the world of Java. The book introduces a list of design patterns categorised under three titles: creational, behavioural and structural.

Design patterns are solutions to problems already solved. They represent the collective wisdom of developers and provide us with a common vocabulary. By implementing solutions that are proven to work we avoid reinventing the wheel and can focus our efforts on solving the other problems we will face as we develop our application. However, we need to take care not to overuse design patterns. Unnecessary use of patterns tends to overcomplicate code making it hard to maintain and a poor design pattern knowledge leads to the inappropriate implementation of patterns to problems that they were not designed to solve. It is very much the case that: If the only tool you have is a hammer, then you will see every problem as a nail.

The book’s authors are Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides.

Java 8 Streams: .filter and predicate negation

Recently there was an interesting discussion on the use of predicate negation in the .filter method on a stream by members of the LJC mailing list, so I thought it would be worth summarising it in a blog post. The discussion was about ways to use .filter and to negate the predicate.

Code for this post is available in my github account.

This is perhaps how you might think about doing, but here are some alternative ways.

Stream.of(1, 2, 3, 4, 5, 6, 7)
      .filter(((Predicate) c -> c % 2 == 0).negate())

Answer 1: Write a predicate utility method

You can simplify this by writing a utility method that performs the negation.

public static <R> Predicate<R> not(Predicate<R> predicate) {
      return predicate.negate();
}

Which results in much neater code.

Stream.of(1, 2, 3, 4, 5, 6, 7)
      .filter(not(c -> c % 2 == 0))

View source on github

Answer 2: Use an identity function to convert the method reference to a Predicate

We use a utility method to convert a method reference to a predicate.

public static <T> Predicate<T> predicate(Predicate<T> predicate) {
      return predicate;
}

although the code is not as neat.

Stream.of("Cat", "", "Dog")
      .filter(predicate(String::isEmpty).negate())

References: Heinz’s Lambda Reduction Principle

Answer 3: Use the not (!) operator

Use the familiar not operator.

Stream.of(1, 2, 3, 4, 5, 6, 7)
      .filter((c -> c % 2 != 0))

Stream.of("Cat", "", "Dog")
      .filter(str -> !str.isEmpty())

The code is much simpler and immediately familiar.

It is argued that method references are often harder to read and are trickier when refactoring than simple lambdas and that that mixing lambdas and method references in a Stream chain is confusing to the reader. Reference: Java SE 8 Best Practices

When you use a method reference and want the IDE to create the method, IntelliJ creates this as a static method with the object as the first argument. Using the not operator avoids this.

Here are some useful references:

Cross-platform mobile developement

So what problems does cross-platform development actually solve. well they are two-fold.

 

  • To have the capability of complete (or near complete) mobile platform coverage by developing the application once to run on multiple platforms. To kill two (or multiple birds) with one stone.

killing two birds 1

  • And secondly to reduce language selection to a subset of the languages normally used to develop mobile applications and ideally to just one.

langiage choose

The financial implication of successful cross-platform development are obvious in terms of human resources and clearly make this kind of development very attractive to businesses and their clients.

Two Approaches

There are two broad approaches to developing for multiple platforms. The Hybrid approach, used by the GWT, where the code is developed in one language only (in the case of gwit it is Java) and then translated to HTML5, CSS and javascript. These apps run the same code on every platform and render views in the webview of the native device. Access to device features such as the camera and contacts leverage JSNI (JavaScript native interface), perhaps using Cordova.
 1001.sdt-apache-cordova html5 logo-sencha
The alternative approach is to cross-compile your code base to the native code of the target device by translating to the native language. Weather that be Swift/Objective-c for iOS or Java on Anroid or C# on windows phone.
 swift-ogjava androidobjective-cvisualcsharp_2
We are gong to look at three frameworks that levarage these methods but in quite unique ways.

Tabris

tabbris websiteTabris falls into the Hybrid category of cross-platform development. Like GWT it uses Java to describe the views and widgets available to the application and Java EE technology to create an application on the server. However unlike gwit it does not translate the UI into HTML5 and JavaScript but rather into JSON representations of the UI element. The native client effectively acts as a player for the applications UI. It access the application by calling a URL that provides the JSON representation of the UI element. Then the client will render the UI from the JSON message using native components. For iOS those components are Cocoa Touch widgets and Java based widgets for Andriod.
tabris-100000feet
On the server side a war file is deployed to a web server where it registers a servlet that becomes the entry point of the application. The JSON UI messages are then served to the client.
You require a commercial license to use their framework.
OK so lets see how this works from a code perspective. The Tabris UI framework is responsible for creating the Page and
tabris code example ui 2 Action objects which are added to the UI Configuration object. in this example two configurations will be created and added to the UIConfiguration. The first is a PageConfiguration which defines a top level page with id ‘all-dvds’ .This page will have a title and an image. The second configuration is an ActionConfiguration that defines a search action. This is then rendered with the native look and feel.
areas IOS Native Screen Shot

Codename One

codename one websiteNow lets have a look at a framework that compiles java code to the native language of the target device. Codename one comes as a plug-in for eclipse, netbeans and intillij. Using their API you build your app’s UI and code its business logic. The interesting part comes when you want to compile and deploy the app code.
For apps written to directly target an Android, J2ME & Blackberry device the standard Java code is executed as is. While apps coded in Java 5 are translated to JDK 1.3 cldc subset for execution on J2ME and Blackberry. For target iOS devices the java  code is translated to C code and for the Windows phone it is translated to c#.
 codename-toolchain
Now the really interesting part here is that to compile to native code you select the target device from the plugin menu, this bundles the app and sends the code off to thier remote build servers where it uses a virtual mac or pc to perform the necessary actions to compile the code.
This removes the need to own a mac and pc machine. When the app is compiled and is ready you are presented on screen with a QR code that when scanned by your device will download and install the app.
condename one code exampleNow lets see some code. For those of you who know Swing or even GWT, for that matter, this code will be immediately understandable. Page components are created and action listeners are attached as anonymous classes. In the example we create a button and add it as a component to the form.  Then we add an action listener to the button.
When the button is click a dialog box pops up showing the message.
They published a blog article a few months ago saying that they are working on java 8 for the next plugin release. So we should see code like this in the future.condename one code example java 8
You require a commercial license to use their framework.

Oracle mobile application Framework

maf websiteAnd finally lets take a look at Oracle’s offering. They have taken a very different approach to the other two. You write your business logic and the code that reacts to user interactions and accesses backend functions. This code is then deployed on a lightweight native JVM on each device. The JVM is bound to the webview and device features.
The UI components are defined in XML, HTML 5 or can be served as HTML webpages. Devices maf architecturefeature’s interactions leverage Apache cordova and are rendered in the native webview.
However you must use either Eclipse or JDeveloper.
MAF flow controlLets look at how a MAF app is developed. The flow between pages is defined with the help of a GUI that visually represents the pages and their inter-relationships, here showGraph specifies the transition type, you then must write the actual logic for each page.
The device’s features are accessed via an instance of the DeviceManager. maf - accessing contactsHere we create a new contact and added it to the contacts via the devicemanager. Your app is deployed as a platform specific deployment.
And a commercial license is required to use the framework.
The slides to the complete JavaOne presentation that I did with Murat can be downloaded from slide share: Mobile Java with GWT: Still “Write Once, Run Everywhere”

RabbitMQ cluster on a single machine

If you are having problems setting up a cluster on a single machine then the following post might help answer some questions.

I assume that you have already set up RabbitMQ on your local machine (rabbit@localhost) and want to know how to add two more nodes and cluster them.

These instructions relate to the installation on a MacBook Pro running OS X Yosemite.

As you already have an installation of RabbitMQ all you need to do is instantiate instances on new nodes. The following command will instantiate an instance of Rabbit on a node called hare@localhost.

    RABBITMQ_NODE_PORT=5674 
        RABBITMQ_NODENAME=hare@localhost 
        rabbitmq-server &amp;

Ensure the port number is different to the port currently in use.

A sticking point are the ports bound by Rabbit to plug-ins. You might see the following error:

BOOT FAILED
===========

Error description:
 {could_not_start,rabbitmq_mqtt,
    {{shutdown,
      {failed_to_start_child,'rabbit_mqtt_listener_sup_:::1883',
         {shutdown,
            {failed_to_start_child,tcp_listener,
              {cannot_listen,{0,0,0,0,0,0,0,0},1883,eaddrinuse}}}}},
     {rabbit_mqtt,start,[normal,[]]}}}

This means that the Rabbit MQTT for the currently running node is using port 1883.

BOOT FAILED
===========

Error description:
 {could_not_start,rabbitmq_stomp,
    {{shutdown,
        {failed_to_start_child,'rabbit_stomp_listener_sup_:::61613',
           {shutdown,
              {failed_to_start_child,tcp_listener,
         {cannot_listen,{0,0,0,0,0,0,0,0},61613,eaddrinuse}}}}},
     {rabbit_stomp,start,[normal,[]]}}}

This means that the Rabbit STOMP for the currently running node is using port 61613.

To resolve this conflict add an argument to RABBITMQ_SERVER_START_ARGS specifying a new port for the plug-in.

A list of installed plug-in is shown in the RabbitMQ web interface in the overview tab under ports and contexts.

The following shows how to configure ports for the Rabbit management and Rabbit MQTT

RABBITMQ_NODE_PORT=5674 
    RABBITMQ_NODENAME=hare@localhost 
    RABBITMQ_SERVER_START_ARGS="
        -rabbitmq_management listener [{port,15674}] 
        -rabbitmq_mqtt tcp_listeners [1884]" 
    rabbitmq-server &amp;

 

Now add the node to the cluster. Stop the instance, join it to another node and start.

rabbitmqctl -n hare@localhost stop_app

rabbitmqctl -n hare@localhost join_cluster rabbit@localhost

rabbitmqctl -n hare@localhost start_app

 

Resources