Thursday, November 29, 2012

Grails & EJB2, my stumbling points

I have been 'playing' with Grails for a couple years now.  I say 'playing' because I don't get to use Grails for my day job.   My day job revolves around a Point-of-Sale (POS) and Back Office system with Web Start clients written using Swing and the server back-end uses EJB2.1 with Hibernate handling the persistence-layer.  Yeah, I know, nobody still uses EJB 2.1!  I have been pushing for some technical upgrades and hopefully that will happen this year, but that not want I want to talk about.

In the past, when I wanted to create a small work-related Grails project, I took what I saw as the easier way out.  I used the static mappings in the domain object to map tables and columns to fields in the domain object, and this works fine.  Recently, I decided to re-visit one of my small projects with the intention of using Grails as the front-end and using the existing EJBs to get access to server data.  Below is a list of my stumbling points along the way to getting this project working.   Only one of the points is EJB2 related but the others are all valid for a lot of current projects.

My stumbling points:
  1. resources.groovy bean definition: JndiObjectFactoryBean vs SimpleRemoteStatelessProxyFactoryBean
  2. LinkageError - referencing javax.management.MBeanServer
  3. Compile errors after removing Hibernate 
  4. BuildConfig.groovy 
resources.groovy bean definitions:
When I decided to use the existing EJBs within Grails, I did some google searches to find the correct format for defining these beans within the resources.groovy file.  I found some examples that worked great if you were using EJB 3.x.  If you are using EJB 3.x, you reference the JndiObjectFactoryBean and this returns the remote service interface.  If your beans are actually EJB 2.1 and you use the JndiObjectFactory, you get back the 'home' interface, which has no business interface methods included.  Again, the problem is that I am using EJB 2.1.   Another couple google searches turned up Dave Klein's "Grails Integration Strategies" presentation and the answer was there on page 15.  For EJB 2.x, you need to use the SimpleRemoteStatelessProxyFactoryBean in order to get the remote service interface.   Spring's SimpleRemoteStatelessProxyFactoryBean handles retrieving the home interface, calling  PortableRemoteObject.narrow() and then calling create() in order to return a remote service interface for EJB 2.1.

resources.groovy for EJB 2.x

beans = {
    ejbJndi(org.springframework.jndi.JndiTemplate) {
        environment = [
            "java.naming.factory.initial" : "org.jnp.interfaces.NamingInitialContextFactory",
            "java.naming.provider.url" : "jnp://localhost:1099",
            "java.naming.security.principal" : "root",
            "java.naming.security.credentials" : "root"
        ]
    }
    environmentSvc(org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean) {
        jndiName = "ejb/EnvironmentService"
        businessInterface = "com.xxx.server.service.environment.EnvironmentService"
        jndiTemplate = ref("ejbJndi")
    }
    
}


resources.groovy for EJB 3.x

beans = {
    ejbJndi(org.springframework.jndi.JndiTemplate) {
        environment = [
            "java.naming.factory.initial" : "org.jnp.interfaces.NamingInitialContextFactory",
            "java.naming.provider.url" : "jnp://localhost:1099",
            "java.naming.security.principal" : "root",
            "java.naming.security.credentials" : "root"
        ]
    }
    processService(org.springframework.jndi.JndiObjectFactoryBean) {
    jndiName = "ejb/ProcessService"
    jndiTemplate = ref("ejbJndi")
    
}


Linkage Error:
The next step was to compile and run the application, but I kept getting these 'Linkage Errors' shown below. Again, after sufficient google searches, I found a couple different postings with the same issue.   I am using JBoss as my application server and using the JBoss jars within Grails.  This problem appears to be a duplication of classes on the classpath between Tomcat and JBoss in the JMX area. According to the postings, there are (at least) two options:
  1. delete Tomcat and install Jetty, which I did and it worked great!
  2. deploy a war to Tomcat.  Apparently this problem only happens in the development environment and deploying your application as a war side steps this problem.

Below is an example of the LinkageError

c:\dev\groovy\hv>grails run-app
| Compiling 113 source files
Note: C:\Users\mmiller\.grails\2.1.0\projects\hv\plugins\cache-1.0.0\src\java\grails\plugin\cache\web\GenericResponseWrapper.java uses or oerrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
| Running Grails application
| Error Failed to initialize component [StandardServer[-1]] (NOTE: Stack trace has been filtered. Use --verbose to see entire trace.)
org.apache.catalina.LifecycleException: Failed to initialize component [StandardServer[-1]]
        at org.grails.plugins.tomcat.InlineExplodedTomcatServer.doStart(InlineExplodedTomcatServer.groovy:137)
        at org.grails.plugins.tomcat.TomcatServer.start(TomcatServer.groovy:102)
        at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy:176)
        at _GrailsRun_groovy$_run_closure5.doCall(_GrailsRun_groovy:153)
        at _GrailsRun_groovy.runInline(_GrailsRun_groovy:121)
        at _GrailsRun_groovy$_run_closure1.doCall(_GrailsRun_groovy:67)
        at RunApp$_run_closure1.doCall(RunApp.groovy:33)
Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of ) previously initiated loading for a differnt type with name "javax/management/MBeanServer"
        ... 7 more
| Error Server failed to start: org.apache.catalina.LifecycleException: Failed to initialize component [StandardServer[-1]]

Compile errors after removing Hibernate:
After getting Jetty installed, I was ready to run the app and get things going. Nope, more errors - now I can't compile because something can not find org.hibernate.cfg.Configuration!   I am working on Grails 2.1.0 and starting in that release, the database migration plugin depends on Hibernate, so if you are going to remove Hibernate, you also need to remove the database migration plugin.   Easy fix - edit BuildConfig.groovy to remove the database migration plugin and re-run.  Below is a copy of both the short error version and the longer version, which used --stacktrace to get a full stacktrace.


c:\dev\groovy\hv>grails run-app
| Uninstalled plugin [tomcat]
| Uninstalled plugin [hibernate]
| Compiling 113 source files.
| Error Fatal error during compilation org.apache.tools.ant.BuildException: java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration
(Use --stacktrace to see the full trace)


c:\dev\groovy\hv>grails --stacktrace run-app
| Compiling 113 source files.
| Error Fatal error during compilation org.apache.tools.ant.BuildException: java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration
(NOTE: Stack trace has been filtered. Use --verbose to see entire trace.)
java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.codehaus.gant.GantBuilder.invokeMethod(GantBuilder.java:99)
        at _GrailsCompile_groovy$_run_closure3_closure8_closure9.doCall(_GrailsCompile_groovy:62)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at _GrailsCompile_groovy$_run_closure3_closure8_closure9.doCall(_GrailsCompile_groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at java_util_concurrent_Callable$call.call(Unknown Source)
        at _GrailsCompile_groovy.withCompilationErrorHandling(_GrailsCompile_groovy:69)
        at _GrailsCompile_groovy.this$4$withCompilationErrorHandling(_GrailsCompile_groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:168)
        at _GrailsCompile_groovy$_run_closure3_closure8.doCall(_GrailsCompile_groovy:61)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at _GrailsCompile_groovy$_run_closure3_closure8.doCall(_GrailsCompile_groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at _GrailsCompile_groovy$_run_closure3.doCall(_GrailsCompile_groovy:58)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy:185)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at java_util_concurrent_Callable$call.call(Unknown Source)
        at org.codehaus.gant.GantBinding.withTargetEvent(GantBinding.groovy:90)
        at org.codehaus.gant.GantBinding.this$4$withTargetEvent(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy:185)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.processClosure(GantMetaClass.java:81)
        at org.codehaus.gant.GantMetaClass.processArgument(GantMetaClass.java:95)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:128)
        at _GrailsCompile_groovy$_run_closure2.doCall(_GrailsCompile_groovy:45)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy:185)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at java_util_concurrent_Callable$call.call(Unknown Source)
        at org.codehaus.gant.GantBinding.withTargetEvent(GantBinding.groovy:90)
        at org.codehaus.gant.GantBinding.this$4$withTargetEvent(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy:185)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:168)
        at _GrailsPackage_groovy$_run_closure2_closure9.doCall(_GrailsPackage_groovy:45)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at _GrailsPackage_groovy$_run_closure2_closure9.doCall(_GrailsPackage_groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at _GrailsPackage_groovy$_run_closure2.doCall(_GrailsPackage_groovy:44)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy:185)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at java_util_concurrent_Callable$call.call(Unknown Source)
        at org.codehaus.gant.GantBinding.withTargetEvent(GantBinding.groovy:90)
        at org.codehaus.gant.GantBinding.this$4$withTargetEvent(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy:185)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.processClosure(GantMetaClass.java:81)
        at org.codehaus.gant.GantMetaClass.processArgument(GantMetaClass.java:95)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:128)
        at RunApp$_run_closure1.doCall(RunApp.groovy:28)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantMetaClass.invokeMethod(GantMetaClass.java:133)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy:185)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16_closure18.doCall(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at java_util_concurrent_Callable$call.call(Unknown Source)
        at org.codehaus.gant.GantBinding.withTargetEvent(GantBinding.groovy:90)
        at org.codehaus.gant.GantBinding.this$4$withTargetEvent(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy:185)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at org.codehaus.gant.GantBinding$_initializeGantBinding_closure5_closure16.doCall(GantBinding.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at java_util_concurrent_Callable$call.call(Unknown Source)
        at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at gant.Gant$_dispatch_closure7.doCall(Gant.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at java_util_concurrent_Callable$call.call(Unknown Source)
        at gant.Gant.withBuildListeners(Gant.groovy:427)
        at gant.Gant.this$2$withBuildListeners(Gant.groovy)
        at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
        at gant.Gant.dispatch(Gant.groovy:415)
        at gant.Gant.this$2$dispatch(Gant.groovy)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at gant.Gant.invokeMethod(Gant.groovy)
        at gant.Gant.executeTargets(Gant.groovy:591)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at gant.Gant.executeTargets(Gant.groovy:590)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
        at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
Caused by: java.lang.ClassNotFoundException: org.hibernate.cfg.Configuration
        ... 123 more
| Error Fatal error during compilation org.apache.tools.ant.BuildException: java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration



Minor mention:
Starting in Grails 2.x,  BuildConfig.groovy plays a bigger role in dependency resolution.  I read in some forum postings that modifying BuildConfig.groovy was now the preferred way of handling plugins rather than using the command line 'grails install-plugin ' or 'grails uninstall-plugin '.   My problem was that I was starting with a Grails project that was originally created with Grails 1.3.7 and BuildConfig.groovy had not been updated with all the plugins.  I had to use a combination of the command line (grails uninstall-plugin)  plus edits to BuildConfig.groovy to resolve my problems.  

Final Thoughts:
The problems documented above were mainly my fault and not that of Grails!  I am just documenting them to possibly help anyone trying the same type of integration.  Maybe this will save them some time and frustration!

Hope this helps!

Tuesday, August 28, 2012

Resolving the "Not all jars signed with same certificate" issue

Almost a year ago I wrote posting on how to resolve the "Not all jars signed with the same certificate" problem encountered from time to time with signed Web Start applications.   My solution at that time was to use a short Groovy script to show each jar and a list of the certificates the jar was signed with.  For those familiar with Groovy, that's still my suggestion.

Recently one of our customer service folks was fighting this same problem at a customer site.  To make matters worse, they were not familiar with Groovy, so using my previous script was not an option.   I decided to bite the bullet and write the Java equivalent.

Below is my Java-equivalent of the Groovy script.  The code is saved as the JarSigners project at GitHub.


package util;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

/**
 *  Show which jars are signed with which code signing certificates
 */
public class JarSigners {

 private String folderName;
 private Map> map;
 private Set certs;
 
 public JarSigners(String folderName) {
  this.folderName = folderName;
  map = new HashMap>();
  certs = new HashSet();
 }
 
 public void listJarSigners() throws ZipException, IOException {
  File dir = new File(folderName);
  FilenameFilter filter = new FilenameFilter() {
      public boolean accept(File dir, String name) {
          return name.endsWith(".jar");
      }
  };
  String[] files = dir.list(filter);
  System.out.println("Found "+files.length+" files in folder: "+folderName);
  for (String fileName : files) {
   checkJarForCertificate(fileName);
  }
  System.out.println("Certificates used to sign the jars: "+certs);
  if (certs.size() > 1) {
   System.out.println("WARNING: More that one certificate shows up in the jars!");
  }
  System.out.println("Details jar->certificate: "+map);
 }
 
 private void checkJarForCertificate(String fileName) throws ZipException, IOException {
  File jar = new File(folderName, fileName);
  ZipFile zip = new ZipFile(jar);
  //System.out.println("Processing "+fileName);
  for (Enumeration entries = zip.entries(); entries.hasMoreElements();) {
         // Get the entry name
         String zipEntryName = ((ZipEntry)entries.nextElement()).getName();
         if (zipEntryName.endsWith(".RSA")) {
          if (!certs.contains(zipEntryName)) {
           certs.add(zipEntryName);
          }
          if (map.containsKey(fileName)) {
           List list = map.get(zipEntryName);
           list.add(zipEntryName);
          } else {
           List list = new ArrayList();
           list.add(zipEntryName);
           map.put(fileName, list);
          }
         }
     }
  zip.close();
  
 }

 /**
  * @param args
  * @throws IOException 
  * @throws ZipException 
  */
 public static void main(String[] args) throws ZipException, IOException {
  if (args.length != 1) {
   System.out.println("Invalid invocation: you must pass a folder name");
   return;
  }
  JarSigners js = new JarSigners(args[0]);
  js.listJarSigners();
  System.out.println("Done!");
 }

}


Hope this helps!

Thursday, August 23, 2012

Auto-completion for email addresses in Swing


Recently we added the ability to send Electronic Receipts from our Point-of-Sale product at work.   One of the requirements was to enhance the user interface around the capture of email addresses.   We were just using a standard JTextField to capture the value.  Specifically, we were looking to make the entry of the email address easier by way of auto-completion, much like a lot of ajax-enabled fields in web applications.


I didn't want to re-invent the wheel and felt certain that I could something to get me started with the help of Google!   After a couple searches, I found a great starting point for the new code.  Samuel Sjöberg's auto-completion was extremely close to what I wanted.   Rather than auto-completing a person's name, I wanted to provide auto-completion for the part of the email address after the "@".    I also modified the code a bit to read the auto-completion candidates from a properties file.  This allows you to provide a properties file containing some of the most common email addresses.   Below is a copy of a sample properties file.

#################################################################################
# Commonly used Email Addresses                            
#                                                          
# This file will be read when the component starts up      
# and used to create an ArrayList of names to be used 
# for auto-completion of email addresses entered into 
# fields that assign the EmailAddressAutoCompletionDocument                      # to the field.  
#
# For better performance, put the most commonly used/encountered
# email addresses at the top of the list.
#
#################################################################################

 hotmail=hotmail.com
 gmail=gmail.com
 yahoo=yahoo.com
 verizon=verizon.net
 comcast=comcast.net
 aol=aol.com
 outlook=outlook.com
 mail=mail.com
 bigstring=bigstring.com
 shortmail=shortmail.com
 lycos=lycos.com
 excite=excite.com
 zoho=zohomail.com
 zzn=zzn.com

Below is the interesting part of the auto-completion of the email address field. First, I included a check for a max length of 255 to prevent too much data for our database columns. Next, we check for an "@" sign entered.  If no @ sign, add the text.  There is also a check to prevent a second @ from being added to the field.  Once we get past that, its time to call the completion service looking for a match on the email address. If a match is found, we add the rest of the string to the text box and select the part of the address that wasn't actually entered by the user.

 public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
        if (str == null || str.length() == 0) {
            return;
        }

        // check for max length first
        if (str == null || ((str.length() + getLength() > maxLength) && maxLength > 0))
   return;
        
        String text = getText(0, offs);        // Current text.
        int atSignIdx = text.indexOf(AT_SIGN); // 1st @ sign
        if (atSignIdx != -1 && offs > atSignIdx) {
         String fullText = text+str;
         //prevent entry of 2nd @ sign
         if (fullText.indexOf(AT_SIGN, atSignIdx+1) != -1) {
          return;
         }
         String address = fullText.substring(fullText.indexOf(AT_SIGN)+1);
         String completion = complete(address);
         int length = offs + str.length();
         if (completion != null && text.length() > 0) {
                super.insertString(offs, completion.substring(address.length()-1), a);
                documentOwner.select(length, getLength());
         } else {
          super.insertString(offs, str, a);
         }
        } else {
            super.insertString(offs, str, a);
        }
    }

I also added automatic validation of the full address by providing a regular expression to match against and then assigned a KeyListener to help implement the validation with color coding.   As the user types an email address, the foreground color is red and then when the email address is complete, either through auto-completion of the address portion or just typing, the foreground color is changed to green for a valid address.

Thanks to Samuel for posting his code.  My updated version can be found at GitHub.

Hope this helps!

Monday, August 13, 2012

Book Review: MongoDB in Action

Overview
 I am a big fan of Manning Publications books and so when it came time to do some personal research on NoSQL, I started with the Manning website to what books they had that covered the topic.  I didn't really have any specific requirements, like document model vs key value pairs vs graph database.  I just wanted something fairly current and covering one of the main players in the area.

I found this book on the website and the publication date (2012) helped ensure that I was getting was something current and not a couple years old.  The other nice surprise was the size of the book.  For anyone that's read an 'In Action' book from Manning, you know they generally tend to be fairly large, on the scale of 300-400 page or more.   This book weighs in at 278 pages and that includes 5 appendices!

Contents
The book is broken down into 3 parts:

  1. Getting Started, which covers about 50 pages talking about MongoDB at a high-level, the core server, tools, replication, the JavaScript shell and writing programs and using drivers to interact with the database.
  2. Application Development in MongoDB covers principles of schema design, MongoDB databases, collections, Mongo's query language, updates atomic operations and deletes.
  3. MongoDB Mastery covers index and query optimization, replication, sharding and deployment. 
Summary
An excellent book by Kyle Banker and yet another excellent book from the folks at Manning Publications.  I blew through the first two parts of the book, eager to learn more about NoSQL and MongoDB.  The author does an excellent job explaining concepts within MongoDB and backs up his statements with the reasons why things are done the way they are.

It took a bit longer for me to get through part 3 of the book, no fault of the author or book.  Since this was really my own personal research and there is no way I will be implementing MongoDB or NoSQL at my day job, other than maybe some small personal tools/utilities, the topics of replication and sharding just didn't have the same appeal as learning about the core server, the query language and schema design!

Overall, I would recommend this book to anyone interested in learning about MongoDB.




Monday, July 16, 2012

GDK vs JDK

A lot of folks new to Groovy quickly ask the question, "What's is the GDK?" or "What's the difference between the GDK and the JDK?"

If you take a look thru the GDK documentation, you will see that the GDK acts like an extension to the Java JDK.  New methods are added to the GDK help remove the ceremony and allow Groovy code to be short and concise.  Think of it as a big decorator pattern!   Slight clarification: the JDK is used to build the GDK and referenced by the GDK but it is NOT part of the GDK and not shipped with the GDK.

Maybe a picture will help.  You can see some of the new GDK methods added to the Java classes below.


Hope this helps!

Saturday, July 14, 2012

JBoss AS7 JNDI & EJB 3.1 Naming changes

As a result of the "feature train" continuing to march on and us not keeping our software stack up-to-date, our team finds ourselves in the un-enviable position of having to migrate:

  • JBoss 4.2.3 to AS 7.1.x (currently looking at 7.1.1)
  • EJB 2.1 to EJB 3.1
  • Hibernate 2 to Hibernate 3 or 4
in quick fashion.  I mean, who wants to ship a new release with 8-10 year old software, not me!

The following is the result of some research I did while looking at upgrading from JBoss 4.2.3 with EJB 2.1 to AS 7.1.x with EJB 3.1.  I am sure there will be more posts related to this migration in the near future, but this one is related to changes in the JNDI naming area.

In the past/current
In our current code, the JNDI naming has been very simple:
  1. We concatenated "ejb/" with the name of the remote Session Bean interface in the deployment descriptor to indicate the name that the service should be bound to.
  2. In the code, we use the following code to handle the JNDI lookup.  The really nice part was that the same code could be used by remote clients AND on the server, within the container.
Current Code

Hashtable properties = new Hashtable();
properties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
properties.put("java.naming.provider.url", "jnp://localhost:1099");
Context ctx = new InitialContext(properties);
Object ref = ctx.lookup(jndiName);


AS7 and EJB 3.1
The EJB 3.1 spec has made some changes to mandate portable JNDI names for EJBs and you inherit this in AS 7.1.1.   The other tricky thing I found was that I could no longer use the exact same lookup code from our remote clients and the server.

AS 7 now has two options for remote EJB invocation.  The information you need can be found in the JBoss docs, it just didn't hit me over the head!  After struggling with this issue for a couple days, I decided to create a small program to help make the differences (hopefully) very clear.  Below is the program that I created to invoke a stateless session bean from a remote client.   I deployed the "ejb-remote" sample from the 7.1 Quick Start samples.  The code attempts to load the remote service using both remote methods.  The expectation is that for the first set of lookups, the first lookup is successful and the second, using the "ejb:/" naming format fails.  Then I add the Context.URL_PKG_PREFIXES property with a value of "org.jboss.ejb.client.naming" to the jndi properties passed to the InitialContext constructor and repeat the lookups.  Now, both lookups should be successful.  I have included all the JNDI properties in the code rather than relying on a copy of "jboss-ejb-client.properties" or "jndi.properties" being picked up from the classpath. 
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import java.util.Hashtable;

public class EJBClient {

     private static String[] JNDINAME = {
          "jboss-as-ejb-remote-app/CalculatorBean!org.jboss.as.quickstarts.ejb.remote.stateless.RemoteCalculator", 
          "ejb:/jboss-as-ejb-remote-app/CalculatorBean!org.jboss.as.quickstarts.ejb.remote.stateless.RemoteCalculator" 
     };
     
     private Hashtable jndiProps;
     
     public EJBClient() {
       // setup 'base' jndi properties - no jboss-ejb-client.properties being picked up from classpath!
       jndiProps = new Hashtable();
          jndiProps.put("java.naming.factory.initial","org.jboss.naming.remote.client.InitialContextFactory");
          jndiProps.put(InitialContext.PROVIDER_URL, "remote://localhost:4447");
          jndiProps.put("jboss.naming.client.ejb.context", true);
        
          // needed for remote access - remember to run add-user.bat
          jndiProps.put(Context.SECURITY_PRINCIPAL, "client");
          jndiProps.put(Context.SECURITY_CREDENTIALS, "password");
     }
     
    public void doLookups() {
         // the 'exported' namespace
         for (int i = 0; i < JNDINAME.length; i++) {
               lookup(JNDINAME[i]);
          }
         
        
         // This is an important property to set if you want to do EJB invocations via the remote-naming project
        jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        
        // now with the ejb
        for (int i = 0; i < JNDINAME.length; i++) {
               lookup(JNDINAME[i]);
          }
    }
    
    private void lookup(String name) {
         System.out.println("Lookup name="+name);
         
         Context ctx = null;
        try {
               ctx = new InitialContext(jndiProps);
               Object ref = ctx.lookup(name);
               System.out.println("...Successful");
          } catch (NamingException e) {
               System.out.println("...Failed");
               //System.out.println(e.getMessage());
               e.printStackTrace();
          } finally {
               if (ctx != null) {
                    try {
                         ctx.close();
                    } catch (NamingException e) {}
               }
          }
    }
    
    public static void main(String[] args) throws Exception {
         EJBClient client = new EJBClient();
         client.doLookups();
         
         System.out.println("Done!");
    }
    
}

AS7 on the server-side
Now the easy part, doing the JNDI lookups on the server are very similar to the old way, except that you still need to format the JNDI name according to the new specs and the naming factory is no longer the jnp version!

Hashtable jndiProps = new Hashtable();
    jndiProps.put("java.naming.factory.initial", "org.jboss.as.naming.InitialContextFactory");
    ctx = new InitialContext(jndiProps);
    Object ref = ctx.lookup(jndiName);

Conclusion
As I said earlier, the information was/is in the JBoss documentation, but I probably read past it several times.  What I was looking for was an example showing loading the EJBs from both the client and the server.

Hope this helps!

Sunday, March 25, 2012

Ajax Examples upgraded to Grails 2.0.0

Overview
A little over a year ago, I wrote a blog posting providing a complete set of working code showing ajax examples for each of the Grails tags that supports Ajax.   Now, I finally found time to upgrade that code to Grails 2.0.0 (from Grails 1.3.7).   There are plenty of article out there helping point users in the right direction when upgrading to Grails 2.0.0 and most of them are helpful.  Seems like no one wants to RTFM, we just want to get at it!  My recommendation is RTFM, and checkout some of the helpful postings out there, especially when the upgrade includes as many changes and new features as Grails 2.0.0.

I have to confess, I tried to just "get at it" with my ajax application and Grails 2.0.0 and it got me part of the way there.  To finish the job, I needed to read the excellent documentation produced by the Grails team and also the documentation accompanying some of the plugins.

Steps for my upgrade
In order to get my application running under Grails 2.0, I needed 5 basic steps:

  1. Run the 'grails upgrade' against my project.
  2. Upgrade database to use H2 - instructions under Persistence here
  3. Install plugins: prototype and resources plugin.
  4. Modify the main.gsp layout to accommodate the plugins (resource, prototype).
  5. Modify Config.groovy to set the java script library to prototype.
Step 1
This step is required for any application being upgraded from an earlier version of Grails.  I am not going to say anything else about this step.

Step 2
Follow Peter Ledbrook's instructions on upgrading the persistence layer to use H2 database instead of the HSQLDB.  If you want to continue to use HSQLDB, there are instructions for that too!

Step 3
I consider myself 'javascript-challenged', so I decided to stick with the prototype library for javascript for this upgrade rather than attempting to use jQuery, which is the new default library.  If all goes well and I get some free time, maybe I will upgrade the application to use jQuery too, but for now, I am sticking with prototype - less changes too!

Make sure the plugins are installed, and then verify that they all got installed successfully (last statement).

grails install-plugin resources
grails install-plugin prototype
grails list-plugins -installed

Step 4
One of the tricky parts here was including plugin="prototype" on the javascript tag in the header section of this page.  Below is a copy of my layout\main.gsp.  (Be careful using cut/paste on the page below, I had problems with the syntax highligher or blogger (not sure which) adjusting my  html tags as it sees fit).  Best option, grab the code from GitHub. Also be sure to understand the changes needed for the Resources Plugin.
  
 
        <g:layoutTitle default="Grails" />
        
        
        
        
        
           function showSpinner(visible) {
              $('spinner').style.display = visible ? "inline" : "none";
           }
           Ajax.Responders.register({
           onLoading: function() {
                 showSpinner(true);
           },
           onComplete: function() {
             if(!Ajax.activeRequestCount) showSpinner(false);
           }
           });
        
        
    
     
        



        

      
Step 5
Update Config.groovy to define prototype as the javascript library to use.

... 
grails.views.javascript.library = "prototype"
...
The project has been updated  and now available on GitHub.

Hope this helps!

Monday, January 30, 2012

Book Review: Programming Concurrency on the JVM

Overview
Programming concurrency is a tough task to get right, just ask Venkat, he'll tell you so!  I attended a presentation by Dr. Venkat Subramaniam on this very subject, Concurrency on the JVM, at my local Java user group a couple months ago and he really caught my attention.  The presentation was a condensed version of the book, and needless to say, I bought the book to help fill in all the details.

Not only is Venkat a 'subject matter expert',  but his presentation kept everyone engaged and laughing!

Contents:
The book is broken down in 5 parts, with 10 chapters total, at just over 250 pages.  The main sections of the book are:

  • Strategies for Concurrency - this discusses the impact of multi-core machines and the three design approaches that are discussed throughout the rest of the book, Shared Mutability, Isolated Mutability and Pure Immutability.

  • Modern Java/JDK Concurrency - covers the Java 1.5+ concurrency features and talks about how to use the newer concurrency classes, like ExecutorService, CountDownLatch, Locks and Fork/Join to solve concurrency problems.

  • Software Transactional Memory - covers Software Transactional Memory (STM), popularized by Clojure, which places access to memory within transactions.  STM is one option for getting away from the 'Synchronize and Suffer' model as Venkat call it.  The intention is to make threaded code more deterministic.   Using the JDK concurrency tools, there is no way to be sure you code is correct because it doesn't always fail when/where you need it to.   By putting the memory access inside transactions, the transaction manager helps resolve the conflicts without explicit locking.

  • Actor-based Concurrency - covers actor design approaches as another option for concurrency design without using synchronization.  This section exercises actors from the Akka library from Scala, Actors from the Groovy library GPars, and mixing Actors and STM as a possible solution.

  • Epilogue - is a short recap of the topics presented previously and points out the scenarios when each of the solutions would be appropriate.
The book lays out a couple example problems and then develops solutions for these problems across a range of JVM languages (Java, Groovy, Scala, Clojure and JRuby).   The examples are short and concise,   enough to help you to get started prototyping against your own concurrency issues.

Summary
This is a good book to get you started on some of these newer concurrency concepts and libraries.  It was an easy read, and I completed the reading fairly quickly, as opposed to the "Java Concurrency in Practice" book, which I started and stopped twice and still have not completed yet!

I would recommend this book to anyone looking to improve their programming skills in the concurrency area.  The book provides you with some alternatives to the old standby of ' Synchronize and Suffer' model.
My last recommendation, if you get the opportunity, attend one of Venkat's presentations, you won't be sorry!

Thursday, January 19, 2012

Passing parameters into Groovy script using Binding class

I recently saw a question posted on the Groovy/Grails group on LinkedIn asking about ways to pass in parameters to a Groovy script.  There were several responses pointing to the CliBuilder class which is certainly one way to handle the problem.   I had just finished reading an article by Ken Kousen in the November issue of GroovyMag  where Ken mentioned another option: using the Binding class.

The example below shows a couple ways of setting variables in the binding, getting the variable values from the binding and how to capture standard output from the script.  The one tricky part is the question "When is something in the Binding and when not?"  The answer is: when it's not defined, it is in the binding!  In the example below, variable c is placed in the binding, but since it is def'd in the script, the value for that variable comes from the local variable rather than the binding.
// setup binding
def binding = new Binding()
binding.a = 1
binding.setVariable('b', 2)
binding.c = 3
println binding.variables

// setup to capture standard out
def content = new StringWriter()
binding.out = new PrintWriter(content)

// evaluate the script
def ret = new GroovyShell(binding).evaluate('''
def c = 9
println 'a='+a
println 'b='+b
println 'c='+c 
retVal = a+b+c
a=3
b=2
c=1
''')

// validate the values
assert binding.a == 3
assert binding.getVariable('b') == 2
assert binding.c == 3 // binding does NOT apply to def'd variable
assert binding.retVal == 12 // local def of c applied NOT the binding!

println 'retVal='+binding.retVal
println binding.variables
println content.toString()
Output
[a:1, b:2, c:3]
retVal=12
[a:3, b:2, c:3, out:java.io.PrintWriter@1e0799a, retVal:12]
a=1
b=2
c=9

Hope this helps!

Tuesday, January 17, 2012

Book Review: SQL Antipatterns Avoiding the Pitfalls of Database Programming

Overview
This is book for software developers that are either new to database programming (SQL) or those that may not have had any formal database education and may have learned 'on-the-job'.

The book is bit longer, approximately 300 pages, than some of the other titles I've read from The Pragmatic Programmers shelf, but it is a very easy read.  The chapters all follow a similar format: Object, Antipattern, How to Recognize the Antipattern, Legitimate Uses of the Antipattern and Solution.  Each chapter the author leads you through a problem that needs correcting within the scope of the database.   Next the antipattern is laid out for you and the author shows the disadvantages of using the antipattern.   Tips are provided to help identify the antipattern and he also suggests some possible legitimate uses of the antipattern.  Finally, the author describes better solutions to the problem presented; ones without the disadvantages discussed previously and solutions that are considered 'best practices' and that will provide better database performance.


Contents
The book is broken down into 4 main sections:

  • Logical Database Design Antipatterns - planning database tables, columns and relationships
  • Physical Database Design Antipatterns - defining tables, indexes and choosing  datatypes
  • Query Antipatterns - SQL command usage, for example, SELECT, UPDATE and DELETE
  • Application Development Antipatterns - correct usage within the scope of a language
Some of that antipatterns described may make you laugh and wonder, "Who the heck would do something like that?" while others you may have run into previously and some might even hit very close to home from your work or personal projects.

There is also an appendix that covers the Rules of Normalization.  I had heard of terms like Normalization, First Normal Form, and Second Normal Form before, but never actually read any explanations. The appendix includes discussions on normalization and first normal form through fifth normal form with examples to help clarify the topics. 

Summary
This is a very good book for software developers just starting to 'cut their teeth' with databases and SQL.  It also serves as a good refresher for those with a bit more database experience.  In my case, I fall into the later scenario.  You can view it as a book of short stories, showing what not to do in these cases.