2/18/2012

How to Create POJO JavaBean Custom Resource in GlassFish

In addition to simple value custom resources, GlassFish also provides decent support for POJO JavaBean custom resources. The steps are very similar to String and primitive custom resources, except that you will need to provide your resource impl class and use a different GlassFish factory class. For example, suppose we need to implement a Person class:


public class Person implements java.io.Serializable {
private String firstName;
private String lastName;
private int age;

public String getFirstName() {
return firstName;
}

public void setFirstName(String s) {
firstName = s;
}

public String getLastName() {
return lastName;
}

public void setLastName(String s) {
lastName = s;
}

public int getAge() {
return age;
}

public void setAge(int i) {
age = i;
}

@Override
public String toString() {
return String.format("Person firstName:%s, lastName:%s, age:%s",
firstName, lastName, age);
}
//TODO override equals and hashCode
}
Compile it and copy Person.class to GlassFish domain lib directory, restart the domain, and create a custom resource of type Person:

$ javac Person.java
$ cp Person.class $GLASSFISH_HOME/domains/domain1/lib/classes/
$ asadmin restart-domain
$ asadmin create-custom-resource --restype=Person --factoryclass=org.glassfish.resources.custom.factory.JavaBeanFactory --property firstName\="Jon":lastName\="Smith":age\=20 resource/person
To list the attributes and properties of the newly-created resource with GlassFish asadmin get command:

$ asadmin get 'resources.custom-resource.resource/person.*'

resources.custom-resource.resource/person.property.age=15
resources.custom-resource.resource/person.property.lastName=Smith
resources.custom-resource.resource/person.property.firstName=Jon
resources.custom-resource.resource/person.enabled=true
resources.custom-resource.resource/person.factory-class=org.glassfish.resources.custom.factory.JavaBeanFactory
resources.custom-resource.resource/person.jndi-name=resource/person
resources.custom-resource.resource/person.object-type=user
resources.custom-resource.resource/person.res-type=Person
Command get executed successfully.
To update the age property of the resource with asadmin set command:

$ asadmin set 'resources.custom-resource.resource/person.property.age'=15

resources.custom-resource.resource/person.property.age=15
Command set executed successfully.
To look up the custom resource, resource/person, from a webapp, or Java EE application:

try {
InitialContext ic = new InitialContext();
Person person = (Person) ic.lookup("resource/person");
} catch (NamingException e) {
throw new RuntimeException(e);
}
You can inject it into Java EE web component or EJB component class such as servlet, filter, web listener, interceptor, or EJB bean class:

@Resource(lookup="resource/person")
private Person person;
A Java SE remote client can also look up the resource:

import javax.naming.*;
/**
* A generic remote client for testing JNDI lookup.
*/
public class TestLookup {
public static void main(String args[]) throws Exception {
InitialContext ic = new InitialContext();
for(String name : args) {
System.out.printf("Looked up jndi name %s, got %s%n",
name, ic.lookup(name));
}
}
}
The following shows how to build and run the remote JNDI client, and the output:

$ javac TestLookup.java
$ java -cp "$GLASSFISH_HOME/modules/*:." TestLookup resource/person

Feb 18, 2012 11:42:12 AM com.sun.enterprise.v3.server.CommonClassLoaderServiceImpl findDerbyClient
INFO: Cannot find javadb client jar file, derby jdbc driver will not be available by default.
Looked up jndi name resource/person, got Person firstName:Jon, lastName:Smith, age:15
Note that both TestLookup.class and Person.class are in current directory and therefore are in the client classpath. Person class also implements java.io.Serializable to make remote access possible.

For more advanced example of GlassFish custom resources, see How to create and look up thread pool resource in GlassFish