DanutClapa
DanutClapa

Reputation: 642

Simple-JNDI VS SimpleNamingContextBuilder with EmbeddedDatabaseBuilder and already existing Data Source

Does anyone knows to configure a EmbeddedDatabaseBuilder Datasource with Simple-JNDI? I have a DataSource for testing purposes that I am building like this:

    public DataSource dataSource() {
    EmbeddedDatabase datasource = new EmbeddedDatabaseBuilder()
            .setType(HSQL)
            .setSeparator(";")
            .addScript("classpath:/tables-definitions.sql")
            .build();
    return datasource;
}

And I want to bind this to a JNDI name with Simple-JNDI. Do you know how to do this?

Upvotes: 0

Views: 2140

Answers (2)

Swavek L
Swavek L

Reputation: 21

This helped me too. I was transitioning from Spring 5 to 6 and couldn't use springframework-mock.jar anymore because it contained classes which were moved into springframework-test.jar. Specifically MockHttpServletRequest and so SimpleNamingContextBuilder was no longer available. This worked for me.

        Hashtable<String, String> env = new Hashtable<>();
    try {
        Properties properties = new Properties();
        properties.load(ResourceHelper.getFileResourceStream("/jndi.properties"));
        Set<Map.Entry<Object, Object>> entries = properties.entrySet();
        for (Map.Entry<Object, Object> entry : entries) {
            env.put(entry.getKey().toString(), entry.getValue().toString());
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    InitialContext initialContext = new InitialContext(env);
    Context subcontext = initialContext.createSubcontext("java:comp");
    Context envSubcontext = subcontext.createSubcontext("env");

    initialContext.bind("java:comp/env/sqlDataStoreDS", testSqlDataSource);

Upvotes: 0

DanutClapa
DanutClapa

Reputation: 642

Finally I found the answer how to use Simple-JNDI to bind to a jndi name a data source that you already have, in general for testing purposes.

Just an observation if you try to use SimpleNamingContextBuilder:

  • SimpleNamingContextBuilder is deprecated in spring 5.2 and above in favour of Simple-JNDI
  • Unfortunately I did not find a great source of documentation for Simple-JNDI which make things for more advanced stuff a bit cumbersome.
  • Also SimpleNamingContextBuilder does not work with JTA only with JPA - it does not cover all the naming needs for JTA

Now, how to bind a JNDI name with Simple-JNDI to a data source:

  • you need to set Context.INITIAL_CONTEXT_FACTORY to the factory class that you want to do the job for you, in my case I choose org.osjava.sj.memory.MemoryContextFactory - if you look into the location of this class in Simple-JNDI library, you will find more options there, depending of your needs

    System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.osjava.sj.memory.MemoryContextFactory");
    

Then you create a Hashtable and add all the properties you need to set as you set them through properties.

    Hashtable env = new Hashtable();
    env.put("org.osjava.sj.jndi.shared", "true");

Then you bind the DS to JNDI name as you would do it in old plain way:

  • create the initial context with the properties from the Hashtable

  • create the sub-context

  • then bind the data source to JNDI name/context:

    InitialContext ic = new InitialContext(env);
    ic.createSubcontext("java:/comp/env/jdbc");
    ic.bind("java:/comp/env/jdbc/"+dataSourceJndiname, datasource);
    

Upvotes: 2

Related Questions