0

we are using Glassfish, where we set JNDI resource of type Map, we define some Bean factory and after that we are able to access(JNDI lookup) this map in our code.

I would like to do the same for embedded Tomcat testing with Spring Boot, but I don'n know how. Everywhere they are just referencing how to add JNDI datasource not some Hashmap. I tried something like this, but my guess is it is completely wrong.

public TomcatEmbeddedServletContainerFactory tomcatFactory() {
     return new TomcatEmbeddedServletContainerFactory() {

        @Override
        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                Tomcat tomcat) {
            tomcat.enableNaming();
            return super.getTomcatEmbeddedServletContainer(tomcat);
        }
            @Override
            protected void postProcessContext(Context context) {
                ContextResource resource = new ContextResource();
                resource.setName("jndiname");
                resource.setType(Map.class.getName());
                // for testing only
                resource.setProperty("testproperty", "10");

                context.getNamingResources().addResource(resource);
            }
        };
    }


    @Bean(destroyMethod="")
    public Map jndiDataSource() throws IllegalArgumentException, NamingException {
        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
        bean.setJndiName("jndiname");
        bean.setProxyInterface(Map.class);
        bean.setLookupOnStartup(false);
        bean.setResourceRef(true);
        bean.afterPropertiesSet();
        return (Map)bean.getObject();
    }

I'm don't know where to pass in the Object factory. Is it possible at all with the embedded Tomcat?

Jan Galinski
  • 11,768
  • 8
  • 54
  • 77
Zveratko
  • 2,663
  • 6
  • 35
  • 64

1 Answers1

0

The first thing to do is to create an ObjectFactory implementation that can return a Map:

public class MapObjectFactory implements ObjectFactory {

    @Override
    public Object getObjectInstance(Object obj, Name name,
            javax.naming.Context nameCtx, Hashtable<?, ?> environment)
            throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        // Configure the map as appropriate
        return map;
    }   
}

You then configure the ObjectFactory using the factory property on the ContextResource:

@Override
protected void postProcessContext(Context context) {
    ContextResource resource = new ContextResource();
    resource.setName("foo/myMap");
    resource.setType(Map.class.getName());
    resource.setProperty("factory", MapObjectFactory.class.getName());
    context.getNamingResources().addResource(resource);
}
Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • Unfortunately I'm still getting _Name [myName] is not bound in this Context. Unable to find [myName]_. Maybe it is connected somehow with my usage of Embedded Tomcat – Zveratko Feb 18 '15 at 07:24
  • I found [this](http://stackoverflow.com/a/27825078/2944265), but the hack is not working for me – Zveratko Feb 18 '15 at 08:20
  • I thought the problem is that I did my lookup in @Configuration, but even if I removed that and not using anymore the lookup there, it still fails afterwards during runtime, same error:( – Zveratko Feb 18 '15 at 08:44
  • If you're using the exact same name to bind the resource and to look it up then it won't work. Resources are automatically bound into `java:comp/env/` so `resource.setName("foo/myMap")` would require `java:comp/env/foo/myMap` to be used when retrieving it from JNDI. – Andy Wilkinson Feb 18 '15 at 09:05
  • Is it Tomcat specific? We are calling just ` Context ic = new InitialContext(); obj = ic.lookup(CONFIG_JNDI);` and it works fine on Glassfish. Maybe Glassfish maps the JNDI names also to root or something will try to find somehing in docs. – Zveratko Feb 18 '15 at 09:28
  • With java:comp/env/ it works, unfortunately I can not change the lookup code, but at least I know what was the problem. – Zveratko Feb 18 '15 at 11:07