| The Ground Rules

## Environment Properties

> Environment properties and how they are used by the application are described in detail in the Environment Properties lesson. This section describes how a service provider should handle environment properties.

> #### Initialization

> When a program uses the constructors from the `InitialContext` class or its subclasses, it supplies an optional environment parameter. The JNDI class libraries merge the contents of this parameter with other sources of environment properties (see the Environment Properties lesson) and give the result to the service provider. More precisely, the JNDI gives the result to `InitialContextFactory.getInitialContext()`, which in turns creates the context implementation and supplies the resulting environment properties as a parameter. The context implementation does not have to worry about where the properties came from or with consulting the various sources. The JNDI class libraries will fetch and merge the properties before giving them to the underlying context implementation.

> #### Ownership

> Typically, the context implementation needs to remember the contents of the environment beyond initialization of the context implementation. At a minimum, the context implementation needs the environment for processing `Context.getEnvironment()`. Like all other parameters received by a context implementation, the environment properties are owned by the caller and not by the context implementation. Therefore the context implementation needs to make a copy of the environment.

> A common pattern in the context implementation's constructor is one that clones the environment, illustrated as follows.

> >     if (inEnv != null) {
> >         myEnv = (Hashtable)inEnv.clone();
> >     } else {
> >         myEnv = new Hashtable();
> >     }

> #### Inheritance

> A `Context` instance is said to be derived from another `Context` instance if the latter was involved in the creation of the former. For example, if you obtain `Context` instance B by performing a `Context.lookup()` on `Context` instance A, then instance B is derived from instance A. Similarly, if you list a context and obtain a bunch of other `Context` instances, those other instances are derived from the listed context.

> A `Context` instance inherits its environment from the context from which it was derived, even across naming system boundaries. Following are the three places where a context implementation should pass on its environment.

> - When a context implementation creates a `Context` instance, it should pass the parent `Context` instance's environment to the newly created `Context` instance. This can be done by cloning the environment or by using a copy-on-write policy so that each context's environment maintains its independence.
> - When a context implementation invokes any of the following methods, it should pass the context's environment.
>   - `NamingManager.getObjectInstance(Object, Name, Context, Hashtable)`
>   - `DirectoryManager.getObjectInstance(Object, Name, Context, Hashtable, Attributes)`
>   - `NamingManager.getStateToBind(Object, Name, Context, Hashtable)`
>   - `DirectoryManager.getStateToBind(Object, Name, Context, Hashtable, Attributes)`
>   - `ControlFactory.getControlInstance(Control, Context, Hashtable)`
>   The factory, or `Context` instance derived from the factory, resulting from these calls is responsible for cloning the environment as needed.
> - When a context implementation that supports federation reaches its naming system boundary, it constructs a `CannotProceedException` that pinpoints how far it has gotten and then invokes `NamingManager.getContinuationContext()` or `DirectoryManager.getContinuationDirContext()`. The context implementation should invoke `CannotProceedException.setEnvironment()` with the context's environment. Doing this passes the context's environment to the continuation context in the nns (next naming system). The context in the nns is responsible for cloning the environment as needed.
> Note that inheritance occurs at the point at which the derived `Context` instance is created. Inheritance does not mean sharing. Each `Context` instance must maintain its own environment in such a way that any changes to its environment do not affect the environment of other `Context` instances.

> #### Applicability

> Possibly not all of the environment properties passed to a context will apply to that context implementation. The implementation is responsible for selecting and using those properties that apply to it and for maintaining and ignoring the ones that don't. The context is responsible for passing all properties, including those that it does not use, to `Context` instances derived from it. This allows the application to set up in one place the environment properties for all of the context implementations with which it will be interacting, instead of just those for the initial context.

> #### Provider Resource Files

> The JNDI SPI methods listed previously (`getObjectInstance()`, `getStateToBind()`, and `getControlInstance()`) not only use the properties found in the environment parameter, but also the context implementation's provider resource file. The JNDI locates the provider resource file by using the `Context` parameter. The name of the provider resource file is

> > [prefix/]`jndiprovider.properties`

> where prefix is the package name of the `Context` parameter and each period character (".") is converted to a forward slash character ("/"). For example, suppose that the `Context` parameter is an instance of the class `com.sun.jndi.ldap.LdapCtx`. Its provider resource file will named `com/sun/jndi/ldap/jndiprovider.properties`.

> The JNDI SPI methods consult the provider resource file when determining the values of the following properties:

> >     java.naming.factory.object
> >     java.naming.factory.state
> >     java.naming.factory.control
> >     java.naming.factory.url.pkgs

> These values are appended to the values found in the environment parameter.

> Properties other than these may be set in the provider resource file at the service provider's discretion. These additional properties are ignored by the JNDI but might be used by the service provider. If your provider uses additional properties from the provider resource file, then you should document them clearly.

> #### Provider-Specific Properties

> The Environment Properties lesson discusses the different categories of environment properties. Provider-specific environment properties are used only by a specific service provider. Before you define a provider-specific environment property, you should ensure that it must be provider-specific and cannot be service- or feature-specific. See the Environment Properties lesson for information on how to categorize environment properties.

> When defining a provider-specific property, you should prefix it with the package name of your service provider. For example, if your context implementation has the class name `com.sun.jndi.ldap.LdapCtx`, then its provider-specific properties should have the prefix `"com.sun.jndi.ldap."`.

| The Ground Rules