Add JNDI configuration implementation.

Description

Add a Configuration implementation that uses JNDI.

Web applications frequently provide configuration information in <env-entry> in web.xml, or externally in a server context such as Tomcat. These context environment parameters are typically made available via JNDI. See Tomcat JNDI Resources HOW-TO for an explanation, and for more information see Make per-context JNDI variable available to Tomcat in Eclipse and Eclipse: Overriding JNDI Resource in Tomcat.

The implementation can be based on strings, and will probably use something like:

See Java Tutorial Trail: Java Naming and Directory Interface for more information on JNDI.

We might also want to provide a Csar provider that includes a fallback JNDI -> system properties -> environment variables automatically. We could furnish other providers with different fallback combinations.

Environment

None

Activity

Show:
Garret Wilson
November 11, 2018, 4:59 AM
Edited

Oh, you're saying that if we're not running in a container (such as the EE container Tomcat provides), we may not have a JNDI implementation installed/configured.

So for testing you'll want to look around for a fake or mock version of JNDI, I would imagine. I just did a search for test jndi implementation and got several interesting links, like:

I frankly haven't looked deeply into how InitialContext works, nor how it gets hooked up to the underlying implementation. But look what the message is telling you:

Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial

Then read the InitialContext docs. They say:

The initial context implementation is determined at runtime. The default policy uses the environment property "java.naming.factory.initial", which contains the class name of the initial context factory.

Read those docs; they have lots of good info. The quote I gave sounds to me like you just create an initial context factory (look that class up), and put its class name in the "java.naming.factory.initial" environment property. And you could mock this initial context factory.

Those API docs also say:

This default policy of locating the initial context and URL context factories may be overridden by calling NamingManager.setInitialContextFactoryBuilder().

And sure enough, the following answer looks like a complete solution using stub implementations and NamingManager.setInitialContextFactoryBuilder(): https://stackoverflow.com/a/21733896/421049

To understand how it all works, look at the source code for InitialContext.getURLOrDefaultInitCtx(String name) and InitialContext.getDefaultInitCtx(). That leads you to {{javax.naming.spi.NamingManager.getInitialContext(Hashtable<?,?> env)}}—and look, there's your error message! Now with a little more exploration you can see that you can either set an initial context factory manually, or specify an environment variable with the name of the factory class—exactly as the documentation indicated.

Garret Wilson
November 16, 2018, 9:45 PM

The pull request looks really good.

Now, , we might want to think about some …-provider project(s) that we can create that one could use that would set up this configuration automatically _just by adding the dependency_—wouldn't that be cool?

Here are a couple off the top of my head:

  • confound-jndi-provider - This will include a registered ConcernProvider that service provider that returns a ConfigurationConcern that creates a JndiConfiguration. So just by including this dependency a program or library can use Confound.getConfiguration() and it will work with JNDI.

  • confound-jndi-system-provider - This is the same thing except the ConfigurationConcern will return a JNDI configuration that falls back to Confound.getSystemConfiguration() (which is configuration that uses system properties and itself will fall back to environment variables).

That's the two that come up off the top of my head. We want to make available providers that will be useful. What do you think?

Magno Nascimento
November 18, 2018, 9:05 AM
Edited

Sure, they look really good, but I'm concerned about these provider classes, for the file implementations we used PropertyFileFormat for loading them, but what should we do for this type of configuration?

Garret Wilson
November 19, 2018, 2:10 AM

I'm not sure what you mean. There's nothing to "load" for a JndiConfiguration. That's why you didn't load anything for the test. You just created a JndiConfiguration.

You'll probably want to review how service loaders work. Let me know if we need to have a meeting about it.

Garret Wilson
November 19, 2018, 2:11 AM

Maybe part of the confusion is that Csar has its own service loaders, and the file-based configuration has a separate server loader just for adding new file format support. Perhaps you were confusing the two. Here we would just create a Csar service loader.

Assignee

Magno Nascimento

Reporter

Garret Wilson

Labels

None

Fix versions

Priority

Critical
Configure