this night I just wanted to write a quick grails plugin to access my BinBase database system.
Since I'm a smart developer I start with a simple spring dsl file and write a test.
// Place your Spring DSL code here
beans = {
jndiBinBaseTemplate(org.springframework.jndi.JndiTemplate) {
environment = [
"java.naming.factory.initial": "org.jnp.interfaces.NamingContextFactory",
"java.naming.factory.url.pkgs": "org.jboss.naming:org.jnp.interfaces",
"java.naming.provider.url": "localhost:1099"
]
}
/**
* connection to the cluster configuration
*/
clusterConfigService(SimpleRemoteStatelessSessionProxyFactoryBean) { bean ->
businessInterface = "edu.ucdavis.genomics.metabolomics.binbase.cluster.ejb.delegate.ClusterConfigService"
jndiName = "clusterservice/ClusterConfigServiceBean/remote"
jndiTemplate = ref(jndiBinBaseTemplate)
}
}
and the test code is simple enough
class BinBaseSchedulingServiceTests extends GroovyTestCase {
ClusterConfigService clusterConfigService
protected void setUp() {
super.setUp()
}
protected void tearDown() {
super.tearDown()
}
public void testTest(){
assertTrue(clusterConfigService.username != null)
}
}
the variable 'ClusterConfigService' is an stateless session bean in a jboss container and I know it works...
except grails is complaining:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clusterConfigService': Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [clusterservice/ClusterConfigServiceBean/remote] not bound; 0 bindings: []
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1412)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.codehaus.groovy.grails.commons.spring.ReloadAwareAutowireCapableBeanFactory.doCreateBean(ReloadAwareAutowireCapableBeanFactory.java:135)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at
....lots and lots of more...
Caused by: javax.naming.NameNotFoundException: Name [clusterservice/ClusterConfigServiceBean/remote] not bound; 0 bindings: []
at org.springframework.mock.jndi.SimpleNamingContext.lookup(SimpleNamingContext.java:132)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
at org.springframework.ejb.access.AbstractRemoteSlsbInvokerInterceptor.lookup(AbstractRemoteSlsbInvokerInterceptor.java:100)
at org.springframework.ejb.access.AbstractSlsbInvokerInterceptor.refreshHome(AbstractSlsbInvokerInterceptor.java:122)
at
...lots and lots of more...
[23:59:35,938] [ERROR] [main] [StackTrace] [Sanitizing stacktrace:]
javax.naming.NameNotFoundException: Name [clusterservice/ClusterConfigServiceBean/remote] not bound; 0 bindings: []
at org.springframework.mock.jndi.SimpleNamingContext.lookup(SimpleNamingContext.java:132)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
mhm doesn't make much sense. Reason for the failure is that grails decides to mock the access, which is normally ok. But in our case really really not desired.
After all we want to access the application server context!
But it keeps jumping to the 'org.springframework.mock.jndi.SimpleNamingContext' mocking context.
So the only solution is this slightly dirty hack...
/***
* we do not need mocking in this plugin...
*/
if (org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder) {
org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder.deactivate()
}
and promptly it passes.
Since we only want to change this for test cases, we add yet another conditon and our resources.groovy file ends up looking like
import org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean
import grails.util.GrailsUtil
import org.codehaus.groovy.grails.commons.GrailsApplication
/** *
* we do not need mocking in this plugin...
*/
if (GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_TEST)) {
println "warning disabling mocking context!!! to make remote ejb's work"
if (org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder) {
org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder.deactivate()
}
}
// Place your Spring DSL code here
beans = {
jndiBinBaseTemplate(org.springframework.jndi.JndiTemplate) {
environment = [
"java.naming.factory.initial": "org.jnp.interfaces.NamingContextFactory",
"java.naming.factory.url.pkgs": "org.jboss.naming:org.jnp.interfaces",
"java.naming.provider.url": "eros.fiehnlab.ucdavis.edu:1099"
]
}
/**
* connection to the cluster configuration
*/
clusterConfigService(SimpleRemoteStatelessSessionProxyFactoryBean) { bean ->
businessInterface = "edu.ucdavis.genomics.metabolomics.binbase.cluster.ejb.delegate.ClusterConfigService"
jndiName = "clusterservice/ClusterConfigServiceBean/remote"
jndiTemplate = ref(jndiBinBaseTemplate)
}
}