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!