1
Nov
2011

Checking JMX with JRuby

I’ve recently been playing around with JRuby and found the switch from MRI to be hassle free. One of the advantages of JRuby is it’s portability. You can use nearly all Ruby code straight away on the JVM without having to do any code changes, you just include the jruby jar in your classpath.

Another advantage is Java interoperability from JRuby (just require ‘java’). I’ve found this useful when using JMX to check certain conditions are in place while performing releases and for general monitoring.

The following script uses JRuby’s Java integration to walk a given ObjectName’s attributes within JMX.

require 'java'

# Return a JMX Connection
def connect_to_jmx service_url, credentials
	jmxUrl = javax.management.remote.JMXServiceURL.new(service_url)

	environment = java.util.HashMap.new
	environment.put(javax.management.remote.JMXConnector.CREDENTIALS, 
                              credentials.to_java(:string))

	jmxCon = javax.management.remote.JMXConnectorFactory.connect(jmxUrl, 
                                                                                              environment)
	return jmxCon.getMBeanServerConnection
end

# Walk the JMX tree and return the attributes.  Optionally limit to a single ObjectName
def walk_tree jmx_connection, limited_to=''
	names = jmx_connection.queryNames(
                                           javax.management.ObjectName.new(limited_to), nil)

	cached = Hash.new([])

	names.each do |name|
	   info = jmx_connection.getMBeanInfo(name)
	   info.getAttributes.each do | mbi|
		   attr = jmx_connection.getAttribute(name, mbi.getName)
		   cached.store(name.getCanonicalName, 
                          cached[name.getCanonicalName] << { mbi.getName  => attr })
	   end     
	end
	
	return cached
end

service_url = 'host:port'
credentials = ['username', 'password']
jmx_connection = connect_to_jmx(service_url, credentials)

results = walk_tree(jmx_connection, 'java.lang:type=OperatingSystem')

results.each do | key, attributes |
  puts ' * ' + key
  attributes.each do | attr |
	puts " ** #{attr.first[0]} :: #{attr.first[1]}"
  end
  puts
end

When invoked against a running JMX instance this will return something similar to:

 
> jruby jmx_walker.rb
 * java.lang:type=OperatingSystem
 ** FreePhysicalMemorySize :: 51955511296
 ** TotalPhysicalMemorySize :: 151873998848
 ** Name :: Linux
 ** Arch :: amd64
 ** Version :: 2.6.18-194.11.4.el5
 ** AvailableProcessors :: 24
 ** SystemLoadAverage :: 0.49

Hopefully this is of use to you, or inspires you to investigate JRuby a bit further. I’d highly recommend it for Java shops who want to take advantage of Ruby’s scripting ability.

4
Mar
2011

A DSL for collections in Java

When writing Java code I often find it laborious to create collections using the java.util.* collection classes. To avoid this, I’ve been using a mini-DSL to reduce my collections code.

import static com.joejag.common.collections.Dsl.*;

// A list
List list = list("abc", "def");
      
// A set
Set set = set("Sleepy", "Sneezy", "Dozy");
      
// A Map
Map map = map(entry("Joe", 28), entry("Gerry", 39));

Here is the underlying code.

package com.joejag.common.collections;


import java.util.*;

public class Dsl {
    public static <T> List<T> list(T... args) {
        return Arrays.asList(args);
    }

    public static <T> Set<T> set(T... args) {
        Set<T> result = new HashSet<T>(args.length);
        result.addAll(Arrays.asList(args));
        return result;
    }

    public static <K, V> Map<K, V> map(Entry<? extends K, ? extends V>... entries) {
        Map<K, V> result = new HashMap<K, V>(entries.length);

        for (Entry<? extends K, ? extends V> entry : entries)
            if (entry.value != null)
                result.put(entry.key, entry.value);

        return result;
    }

    public static <K, V> Entry<K, V> entry(K key, V value) {
        return new Entry<K, V>(key, value);
    }

    public static class Entry<K, V> {
        K key;
        V value;

        public Entry(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }

    public static void main(String args[]) {
        List<String> list = list("abc", "def");
        System.out.println(list);

        Set<String> set = set("Sleepy", "Sneezy", "Dozy");
        System.out.println(set);

        Map<String, Integer> map = map(entry("Joe", 28), entry("Gerry", 39));
        System.out.println(map);
    }
}

I’ve noticed that the Google Collections project has morphed into Guava which has great reusable code for collections and a lot of other common Java tasks.

28
Feb
2011

Creating a simple Java RESTful service using Jersey and Maven

There has been a lot of interest in Resource Orientated Architecture (ROA) online which has resulted in an explosion of excellent libraries that make it simple to use this architectural style.

The example in this article uses Java, Maven and a JAX-RS library called Jersey to create a very simple orders system.

Our order consists of a reference number and a customer name. The system has three entry points:

  • HTTP PUT to create an order
  • HTTP GET to see the details of an order
  • HTTP GET to see all the existing orders

Download the full source of this article here.

To make it simple to get it up and running I’ve added configuration for Jetty to run on port 9090. You can compile the source code and run a web server to use it by issuing this single Maven command:

mvn jetty:run

I recommend that you use curl to test your RESTful web services as it is easy to change the HTTP verb that you are using. You can manipulate the orders system using these curl commands.

# Add a new order for Bob with ID 1
curl -X PUT http://localhost:9090/orders-server/orders/1?customer_name=bob 

# Check the status of the order
curl -X GET http://localhost:9090/orders-server/orders/1 

# See all the orders in the system
curl -X GET http://localhost:9090/orders-server/orders/list

Note: HTTP GET is the default verb used by curl, I’ve explicitly listed GET in the examples to make it clear which verb is in use.

The code

To use Jersey you need to add a servlet to your web.xml and create a resource implementation class.

web.xml

The WEB-INF/web.xml fragment sets up the Jersey Servlet with a parameter listing the package to search for RESTful classes.

<servlet>
   <servlet-name>Jersey Web Application</servlet-name>
   <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
   <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>         
      <!-- Important bit -->
      <param-value>com.joejag.code.orders.restservices</param-value>          
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>

This reads any classes in the com.joejag.code.orders.restservices and looks for annotations declaring resources.

The Java class

On the implementation class you can see the @Path annotation on the class signature indicating the resource we are handling. This is used by Jersey to configure the URL used to interact with the resource.

Each method has a sub-path declared, an HTTP verb to respond from and the response type to produce. The method parameters are bound by using either part of the path (with @PathParam) or a separate query parameter (with @QueryParam).

 
package com.joejag.code.orders.restservices;

import java.util.Map;
import java.util.TreeMap;

import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;

@Path("orders")
public class OrdersService
{
   // Stores state simply in a static collection class.
   private static Map<String, String> orders = new TreeMap<String, String>();

   @Path("/{order}")
   @PUT
   @Produces("text/html")
   public String create(@PathParam("order") String order, 
                                    @QueryParam("customer_name") String customerName)
   {
      orders.put(order, customerName);
      return "Added order #" + order;
   }

   @Path("/{order}")
   @GET
   @Produces("text/html")
   public String find(@PathParam("order") String order)
   {
      if (orders.containsKey(order))
         return "<h2>Details on Order #" + order + 
                    "</h2><p>Customer name: " + orders.get(order);

      throw new WebApplicationException(Response.Status.NOT_FOUND);
   }

   @Path("/list")
   @GET
   @Produces("text/html")
   public String list()
   {
      String header = "<h2>All Orders</h2>\n";

      header += "<ul>";
      for (Map.Entry<String, String> order : orders.entrySet())
         header += "\n<li>#" + order.getKey() + " for " + order.getValue() + "</li>";

      header += "\n</ul>";

      return header;
   }
}

Download the full source of this article here.

Where to learn more

There are a number of great articles on how to develop JAX-RS REST applications. I recommend you start with the Jersey guide for Java applications:

If you are using Ruby then take a look at the wonderful Sinatra project.

23
Nov
2009

New language features in Java 7

I’m just back from the Devoxx conference in Antwerp. An update was given on the new language changes that will be in Java 7. The JDK currently has a release date of September 2010.

Here are 7 of the new features that have been completed:

  • Language support for collections ( Postponed to Java 8 )
  • Automatic Resource Management
  • Improved Type Inference for Generic Instance Creation (diamond)
  • Underscores in numeric literals
  • Strings in switch
  • Binary literals
  • Simplified Varargs Method Invocation

There is a lot more to Java 7 then just these language changes. I’ll be exploring the rest of the release in future posts. One of the big debates is currently around Closures, which are a separate JSR.

Language support for collections

This has been postponed to Java 8! You could use my simple alternative until then.

Java will be getting first class language support for creating collections. The style change means that collections can be created like they are in Ruby, Perl etc.

Instead of:

List<String> list = new ArrayList<String>();
list.add("item");
String item = list.get(0);
		
Set<String> set = new HashSet<String>();
set.add("item");
		
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("key", 1);
int value = map.get("key");

You will be able to use:

List<String> list = ["item"];
String item = list[0];
		
Set<String> set = {"item"};
		
Map<String, Integer> map = {"key" : 1};
int value = map["key"];

These collections are immutable.

Automatic Resource Management

Some resources in Java need to be closed manually like InputStream, Writers, Sockets, Sql classes. This language feature allows the try statement itself to declare one of more resources. These resources are scoped to the try block and are closed automatically.

This:

BufferedReader br = new BufferedReader(new FileReader(path));
try {
   return br.readLine();
} finally {
   br.close();
}

becomes:

try (BufferedReader br = new BufferedReader(new FileReader(path)) {
   return br.readLine();
}

You can declare more than one resource to close:

try (
   InputStream in = new FileInputStream(src); 
   OutputStream out = new FileOutputStream(dest)) 
{
 // code
}

To support this behaviour all closable classes will be retro-fitted to implement a Closable interface.

Improved Type Inference for Generic Instance Creation (diamond)

This is a particular annoyance which is best served with an example:

Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

becomes:

Map<String, List<String>> anagrams = new HashMap<>();

This is called the diamond operator: <> which infers the type from the reference declaration.

Underscores in numeric literals

Long numbers are hard to read. You can now split them up using an underscore in ints and longs:

int one_million = 1_000_000;

Strings in switch

Currently you can only use numbers or enums in switch statements. String has been added as a candidate:

String s = ...
switch(s) {
 case "quux":
    processQuux(s);
    // fall-through

  case "foo":
  case "bar":
    processFooOrBar(s);
    break;

  case "baz":
     processBaz(s);
    // fall-through

  default:
    processDefault(s);
    break;
}

Binary literals

Java code, due to its C heritage, has traditionally forced programmers to represent numbers in only decimal, octal, or hexadecimal.

As quite a few domains are bit orientated, this restriction can introduce errors. You can now create binary numbers using an 0b prefix.

int binary = 0b1001_1001;

Simplified Varargs Method Invocation

When a programmer tries to invoke a *varargs* (variable arity) method with a non-reifiable varargs type, the compiler currently generates an “unsafe operation” warning. JDK 7 moves the warning from the call site to the method declaration. This will enable API designers to use varargs due to the reduction of warnings reported.

This one is slightly more involved so you are better off looking at the proposal.

3
Aug
2009

Automatically resolving jars for the Java classpath

When you use the Java classpath (pre java 1.6) you have to manually list each jar on your classpath such as:

java -cp lib/database.jar:lib/commons.jar:/lib/log.jar com.joejag.Main

On Java 1.6 a little known feature is that you can now use wildcards, so the above command becomes:

java -cp lib/*.jar com.joejag.Main

I still have to use an earlier version of Java for some applications I handle. To save having to list all the jars manually I use the following bash script which allows you to automatically list all the jars in a directory:

java -cp `find lib -name *.jar -exec printf :{} ';'` com.joejag.Main