CORS Support for JavaEE Web Applications

If you’re planning to make your RESTful resource accessible to other domains then you’ll probably want to enable CORS. There are lots of tutorials and open source projects that provide CORS support for Java EE.

CORS Filter

One of those open source project is this little gem called CORS Filter. Its really easy to use. Once you’ve added the 2 JAR (cors-filter.jar, java-property-utils.jar) files to your application, you now need to now configure the CORS filter into your web application.

Lets say you are trying enable CORS for you JAX-RS application rooted at /api (viz. the value of @ApplicationPath), then all you have to do is add the following to your web.xml file

<filter>
   <filter-name>CORS</filter-name>
   <filter-class>
      com.thetransactioncompany.cors.CORSFilter
   </filter-class>
</filter>

<filter-mapping>
   <filter-name>CORS</filter-name>
   <url-pattern>/api/*</url-pattern>
</filter-mapping>

The filter is now configured to add CORS headers to all outgoing responses made to <application_context>/api. There are a host of tweaks to let you tailor the filter to your heart’s content including limiting the origin, tagging request, aging for preflight caches, etc.

During one of my recent projects, I find that I have to explicitly add web.xml just so that I could configure this CORS filter (note: adding the web.xml did not come up in earlier/previous projects because of JSF. This particular project did not use JSF). So I started a little project to use annotation to configure the CORS filter.

@CORS Annotation

My project contains only a single public API/annotation, that is @CORS. Say you decide to CORS enable /api, just annotate any class like so

@CORS({"/api/*"})
public class AClass { …

Here are the list of some of the attributes in @CORS

Attribute Remarks
value, urlPatterns Behaves like @WebFilter#urlPatterns. Use this to configure one or more URL path
initParams This is used to configure the CORS filter. Configurations can be found here.
asyncSupported Enable this for asynchronous operations. This value has to be set to true if the the any of the Servlet and web resources that the CORS filter is rooting supports async. Default value is false.
debugServlet Enable the debug Servlet to display the mappings. Specify a url for the Servlet eg “/cors-debug”.



Implicit Mode – URL Mappings

Another way of using @CORS is to let the annotation figure out what URL patterns should be CORS enable by annotating either a Servlet, JAX-RS application config (@ApplicationPath) or resource (@Path). In the implicit mode, you do not specify the URL mapping in @CORS.

The following example

@CORS
@ApplicationPath("api")
public class AppConfig extends Application { …

will add /api/* to CORS filter. The following table describes how URL paths are determined when using @CORS in implicit mode

Servlet Mapping @CORS
/customer/* /customer/*
/customer /customer
*.do Not mapped
JAX-RS
@ApplicationPath(“api”) /api/*
@Path(“/customer”) /customer
– If resource have any sub resources viz. @Path annotated on any of the method /customer/*
@Path(“/customer/{id}”) /customer/*

Here is another JAX-RS example with sub one sub resource.

@CORS
@RequestScoped
@Path("/customer")
public class CustomerResource {
   …
   @GET
   public Response get() { …

   @Path("{cid}")
   public Response get(@PathParam("cid") String id) {…

The URL that will be enabled for CORS will be /api/customer/* because there is a sub resource (@Path(“{cid}”)) in CustomerResource class.

For JAX-RS you have the option of annotating individual resources or the JAX-RS application config class. In the former’s case, then you are CORS enabling individual resources as in the CustomerResource example from above. You do not need to annotate the application config class. The @CORS annotation will automatically located the application config class and prefix your resource with the path from @ApplicationPath.

If you are annotating the application config class, then it means that you are enabling the entire JAX-RS application eg. /api/*.

Implicit Mode – Asynchronous Operations

One other feature that @CORS support is auto async configuration; by this I mean if a Servlet or JAX-RS resource have either @WebServlet(asyncSupported=…) set to true or injects @Suspended AsyncResponse into a method annotated with any HTTP methods (eg. @GET, @POST), then the deployed CORS filter will support asynchronous operations.

For this to work, you have to annotate either the Servlet or RESTful resource class with @CORS.

If you’re keen to try out this utility, besides downloading cors-filter.jar and java-property-utils.jar, you also have to download cors-filter-annotation.jar. Add the 3 JARS to into your web application.

Till next time.

Screencast: Creating a Hybrid Mobile Application with Ionic and Cordova

p { font-size: 1.3em; }

I’ve just published a new screencast on how to create hybrid mobile application using the Ionic framework. This screencast is a remake of an older version.

This remakes includes infinite scrolling, integration with 2 Cordova plugins as well as customizing the generated Android ‘shell’.

The source code and the APK is available here.

Till next time.

A Cordova Plugin for Getting the Phone Number on Your Android Phone

Something that I put together while working on a project. There is one available. There is even a nice blog by the author.

My plugin is almost exactly the same as Simon’s. The only difference is that mine is about 3 years late. I did this because I wanted to learn about Cordova plugin development and also to use try out Android Studio.

You can get the details of the plugin here.

BTW the plugin will not work if the phone number is not available on your phone. Go to Settings | About device | Status | My phone number to see if the number is available before you use.

Till next time

MongoDB Realm for Glassfish

Saving user’s login and password into RDBMS is an extremely popular way for JavaEE applications to authenticate against. Most, if not all JEE application servers support JDBC realm out of the box.  Setting up a JDBC realm is quite easy. Here is one for Glassfish.

I’ve always wanted to use NoSQL database, and MongoDB in particular as a security realm. One big advantage, for me at least, Mongo have over its JDBC counterpart is that I don’t have to setup the group table with composite key. I found 2 implementation of MongoDB realm for Glassfish in github; see this and this. I’ll be adding my implementation to this lists.

How Glassfish Security Realm Works?

Before we use my MongoDB realm, lets take a look at how Glassfish handles security.

pic4 (Click to enlarge)

Glassfish uses 2 components (or classes) to collect user’s credentials and authenticate users. To collect your username and password, Glassfish delegates that to Java Authentication and Authorization Service or JAAS. The Mongo JAAS (pronounce as Jazz) module is configured in $DOMAIN_DIR/config/login.conf file. You can see this on the top right corner in the above diagram. A JAAS entry consist of the name (mongodbRealm), also know as the JAAS context, and a FQCN of the login module (at.oneminutedistraction.mongodbrealm.MongoDBRealmLoginModule). See this document for an explanation of the required keyword.

The second step is to configure Glassfish so that it recognizes our MongoDB realm and to associated that with the login module. This is typically done in the admin console which we’ll look at later in this blog. For the time being, lets look at the actual configuration file. The domain.xml holds all information about a Glassfish domain. Again, you can find this file under $DOMAIN_DIR/config directory. A auth-realm defines a security realm. It defines 3 pieces of critical information; see the middle portion of the above figure

  • classname attribute – a FQCN of the the class that implements this security realm. In our case this will be at.oneminutedistraction.mongodbrealm.MongoDBRealm.
  • name attribute – a unique name for this realm (mongodb-realm here). This name will be referenced by our web application that uses this realm
  • jaas-context property – the value of this property is the name of the MongoDB login module ( in login.conf file). This property associates the realm with the login module defined in . 

Now to use this realm in your web application, simply specify the realm name (mongodb-realm) in your web.xml.

Configuring MongoDB Realm

Step 1 – Copy JARs to Domain Directory

To use MongoDB realm, download the following 2 files

  • MongoDBRealm – the compiled JAR (JavaSE 8) is available here. If you prefer to build it yourself, the source is available here.
  • MongoDB Java driver – available here

Copy the 2 JARs into $DOMAIN_DIR/lib directory.

Step 2 – Add JAAS Entry to login.conf File

Edit $DOMAIN_DIR/config/login.conf file and add the following lines to the end of the file

mongodbRealm {
   at.oneminutedistraction.mongodbrealm.MongoDBRealmLoginModule required;
}

I’ve called the JAAS context as mongodbRealm. You can use any name you like just as long as its unique within the login.conf. Make a note of this name as we’ll need it when for creating the realm.

Step 3 – Configure MongoDB Realm in Glassfish

Start up Glassfish version 4.1 and must be running on JavaSE 8. Please make sure that Glassfish is using the same domain as in step 1 and 2 above. If you’re not sure, you can start Glassfish like so

asadmin start-domain -–domaindir /path/to/domain/dir domainname

Open up the admin console. This is usually localhost:4848

pic0(Click to enlarge)

and expand server-config, security as shown in the above figure. Next click on the Realm node.

pic5 (Click to enlarge)

You should see a table with all the preconfigured realms. Click on the New to create a new realm.

pic1 (Click to enlarge)

Define the MongoDB realm using the following values

  • Name – mongodb-realm
  • Class Name – at.oneminutedistraction.mongodbrealm.MongoDBRealm
  • Add the following properties: name = jaas-context, value = mongodbReam. The value must correspond to the entry name in login.conf.

This will create the auth-realm entry in domain.xml. Click OK should instantiate the realm. Besides setting the jaas-context property, the following is an exhaustive list of parameters that you can set to configure MongoDB realm

  • mongodbRealm.db – the name of MongoDB database name. The default name is mongodbRealm
  • mongodbRealm.collection – the collection name. The default name is users
  • jaas-context – the JAAS context. The default value is mongodbRealm
  • mongodbRealm.clientFactory – this is the FQCN of the class that creates MongoClient instance of the realm. The default factory is at.oneminutedistraction.mongodbrealm.DefaultMongoClientFactory. There will be an explanation later that describes how you can implement your own client factory
  • mongodbRealm.server – if you are using the default client factory, then this parameter specifies the list of servers that the MongoClient connects to. This is a list of space separated server:port numbers; for example localhost<space>myserver:1234<space>myotherserver connects to localhost, myotherserver and myserver at port 1234. The default value of this is localhost
  • mongodbRealm.passwordManager – this is the FQCN that performs the password encryption. The default password manager class is at.oneminutedistraction.mongodbrealm.SHA256PasswordManager. We will explain how you can create your own password manager class to perform your password encryption
  • mongodbRealm.algorithm – If you are using SHA256PasswordManager, you can set the value of this to either SHA-256 or SHA-512 which uses the respective hash algorithm for hashing user passwords. The default is SHA-256

Username, password and group information are stored in a JSON structure shown below

{ username: "fred",
password: "999f36dd648c74f52972745be2ee94c4b53c48639debbf310bfd5d5fc84ee4f6",
groups: [ "bedrock", "flintstones", "cartoon" ] }

There are 3 properties for each JSON document that describes a user; the username is the login name, the password is the SHA-256 hashed password (assuming I’m using the default password manager) and groups which holds an array of group names. All values are String. Property names viz. username, password and groups are not configurable.

The following code snippet shows how the above JSON is created using MongoDB’s Java API

BasicDBList groups = new BasicDBList();
groups.addAll(Arrays.asList(new String[]{"bedrock", "flintstones", "cartoon"}));
BasicDBObject fred = new BasicDBObject("user", "fred")
      .append("password", "999f3…d5d5fc84ee4f6")
      .append("groups", groups);

We can finally configure our web application to use the realm.

pic3 (Click to enlarge)

When you are configuring container security for your web application, set the name of Realm Name to mongodb-realm.

Customizing MongoDB Realm

To accommodate the various MongoDB and password requirements, there are 2 interfaces you can implement. The first of these is MongoClientFactory.  The purpose of this interface is to allow you to have control over the creation of the MongoClient instance.The interface has the following methods

  • void init(Properties prop) – This method is called when the factory in initialized. A Properties object is passed into the implementation. The property values comes from the values that you enter when you are creating the realm (see image above with New Realm header).
  • MongoClient create() – This method creates the MongoClient instance using the properties from init(). Put your code to create MongoClient in here.

The second interface, PasswordManager, deals with password encryption and validation. It has the following methods

  • void init(Properities prop) – Similar to MongoClientFactory
  • String encrypt(String password) – Returns an encrypted version of the parameter
  • boolean isValid(String encrypted, String password) – This method validates a password by testing the encrypted parameter against the password parameter

Once you’ve implemented either one or both of the above interfaces, bundle them in a JAR and drop them into $DOMAIN_DIR/lib directory. Now set the following two properties to the FQCN of you implementation  when you are configuring MongoDB;

mongodbRealm.clientFactory
mongodbRealm.passwordManager

 

On a separate note, its heartening to see that Glassfish application server now has commercial conterpart in the form of Payara. Its a drop in replacement for Glassfish and it’s build off Glassfish sources. Disclaimer: I’m not associated with Payara in any form save for the fact that I downloaded their application server this morning. There is even a cute Mario like Youtube video introducing it.

Till next time.

AngularJS Workshop Kit

I’ve recently had the opportunity to give a 3 hour AngularJS workshop. We build a (yet) another weather application with AngularJS, ui-router and Angular Animate. The workshop covers the following core concepts

  • Structuring an Angular application (ng-app)
  • Dependency injection
  • What can you inject
  • Controllers (ng-controller)
  • Model View View-Model
  • Loops as in ng-repeat
  • Applying classes (ng-class)
  • Conditional display (ng-if)
  • Animations (.ng-enter, .ng-leave)
  • Filtering expressions
  • Abstraction with service
  • Partial views ($stateProvider, $urlRouterProvider)
  • Navigation between views (#/hashtag, $state)
  • Parameterizing routes ($stateParams)
  • Consuming RESTful web services ($http and promise)

The workshop is available for download at http://bit.ly/angularjs_workshop. The workshop consists of the following items

  • A presentation; the workshop is broken up into 6 distinct steps, each step introducing core concepts. The slides with the ‘Men at work’ image is the workshop
  • Promotion material
  • Prerequisite – what the participants should know before attending the workshop
  • angularworkshop zip – snapshots of the 6 steps
  • A completed weather application

I’ll *probably* do a screencast of the workshop sometime in the future.

If you’re a programming/hackers (in the good sense of the word) club, Java User Group, open source community and you’re in Singapore and you want to run the workshop for your event, drop me a note. If I’m free I’ll be glad to run a workshop for you (free!). Make sure you have ample supply of Coke and chips!

Till next time.

Evolution of Locks and Locking

Harry-Houdini-007 From time immemorial, Java (both the language and the platform) have supported threads. With threading, you’ll need a way to prevent 2 or more threads from stomping over each other. So the earliest version of Java included the synchronized keyword. The following is a contrived example of a shared shopping list; thread safety is maintained using the synchronized

public class ShoppingList { 
   private final List list = new LinkedList<>();
   public synchronized void add(final String item) { 
      list.add(item); 
   }
   public synchronized int count() { 
      return (list.size()); 
   }
}

The synchronized keywords will try to acquire the lock/monitor of the object before entering the methods. If you want to confine the critical region to a smaller area, as oppose to the entire method, then use

synchronized(this) { … }

instead.

JavaSE 5 introduces Lock and CAS APIs into the platform. With the new Lock API, instead of using synchronized you can do the following

public class ShoppingList {
   private final Lock lock = new ReentrantLock();
   private final List list = new LinkedList<>();
   public void add(final String item) {
      lock.lock();
      try {
         list.add(item);
      } finally {

         lock.unlock();
      }
   }
   public int count() {
      lock.lock();
      try {
         return (list.size());
    
} finally { 
         lock.unlock();  
      }      

      return (-1);
   }
}

The advantage of Lock over synchronized is that

  • You can use different lock semantics. The above example I’ve used an exclusive lock  I can also use ReadWriteLock.
  • Flexibility because now you can pass the lock from one thread to another thread or hold a lock over multiple invocation (may not be a good idea)
  • Specify how long to wait for lock by specifying a timeout in tryLock() when acquiring a lock
  • Create multiple conditions for a lock
  • Etc.

One of the MAJOR feature that is missing from Lock is that it does not automatically release the lock. So as a safety precaution, Lock are almost always used inside a try/finally block to ensure that locks are released before we exit the method.

JavaSE 7 introduces the try-with-resource syntax. The idea of the try-with-resource is that resources such as IO streams, ResultSet , etc are automatically closed when they exit the try block. All these resources have to do is to implement the AutoClosable interface.

We can use try-with-resource to automatically release the lock as we exit the try block. There are many ways to implement this. I’m going to go with the simplest

public class AutoUnlock implements AutoClosable {
   private final Lock lock;
   public AutoUnlock(Lock l) {
      lock = l;
   }
   @Override
   public void close() throws Exception {
      lock.unlock(); 

   }
}

Now to use if we can rewrite our ShoppingList as follows

public class ShoppingList {
   private final Lock lock = new ReentrantLock();
   private final List list = new LinkedList<>();
   public void add(final String item) {
      lock.lock();
      try (AutoUnlock ul = new AutoUnlock(lock)) {
         list.add(item);
      } catch (Exception ex) { }
   }
   public int count() {
      lock.lock();
      try (AutoUnlock ul = new AutoUnlock(lock)) {
         return (list.size());
      } catch (Exception ex) { }
      return (-1);
   }
}

Conceptually this is code is very similar to the version with try/finally. The only difference here is that here the unlock is hidden in close().

JavaSE 8 introduces Lambda. Using Lambda, we can now remove the lock()/unlock() combo from all the methods and put them into guards (consider acquiring a lock as a pre condition). Here is a rewrite of ShoppingList

public class ShoppingList {
   private final Lock lock = new ReentrantLock();
   private final List<String> list = new LinkedList<>();
   public void add(final String item) {
      list.add(item);
   }
   public int count() {
      return (list.size());
   } 
   public void guard(final Runnable r) {
      lock.lock();
      try (AutoUnlock ul = new AutoUnlock(lock)) {
         r.run();
      } catch (Exception ex) { }
   }
   public <T> Optional<T> guard(final Callable<T> c) {
      lock.lock();
      try (AutoUnlock ul = new AutoUnlock(lock)) {
         return (Optional.of(c.call()));
      } catch (Exception ex) { }
      return (Optional.empty());
   }
}

With this approach, you can now decide if you prefer the threadsafe or the regular method.

shoppingList.guard(() –> { shoppingList.addItem(“harry”); });

Till next time

Screencast: Part 2 – JavaEE 7, Mongo, REST, Mobile

In the second part screencast, we will take the data news item stored in the Mongo database and expose that as RESTful reesources. When a request arrives it can specify the following 2 parameters in the query string

  • oid – this is the object id of the document/record. This tells the REST resource to start returning the records from the specified oid. If the oid is missing then we will start from the very first record.
  • batchSize – the number of records to return.

To allow the application server to potentially process a large number of records per request, we handle the retrieving and processing of the news items asynchronously. This is very similar in spirit to async Servlets; however unlike async Servlets, in async JAX-RS you need to provide a thread. This is where the concurrency utilities comes in.

Using @Suspended annotation, we get an instance of AsyncResponse. The AsyncResponse object is passed to a Runnable (our task) which is then dispatched to the ManagedScheduleExecutorSerivce. When the Runnable completes, it calls AsyncResponse.resume() to resume the suspended request.

 

 

The NetBeans project for part 2 is available here. You can find part 1 of this series here.

Till next time.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: