Bean Environment and Configuration

How are resource-refs linked to the actual resource factory?

In ejb-jar.xml you will have a declaration of a resource-ref like this:
            <resource-ref>
                <res-ref-name>jdbc<SavingsDataSource</res-ref-name>
                <res-type>javax.sql.DataSource</res-type>
                <res-auth>Container</res-auth>
            </resource-ref>
Note this is just a logical reference. The actual datasource instance lives in some Naming Service.

We provide a quick solution where you can define some datasources (in ejb-inprise.xml) and they get autodeployed by the Container in such a way that you can lookup java:comp/env/jdbc namespace to fetch them.

So in ejb-inprise.xml you

1. define the actual datasources

2. need to "bind" the logical declaration to an actual datasource. That is acheived by

          <resource-ref>
            <res-ref-name>jdbc/SavingsDataSource</res-ref-name>
            <jndi-name>datasources/BankingDataSource</jndi-name>
          </resource-ref>
The logical "jdbc/SavingsDataSource" is LinkRef-ed to the actual jndi name of the datasource object "datasources/BankingDataSource". One may find this an overkill but consider the advantage when the datasource objects are really in LDAP. You have to have a level of indirection that the EJB Deployer controls.

Is there a way to do application-wide environment settings ?

Consider for example a set of components that represent a business framework. For example an Order Entry framework would include Customer, Vendor, Product, Purhase Order, Invoice... One can envision various global properties of an application built from such a framework - maxTotalOrder, defaultCurrency... These setings are not per component, but spans several. There is no way to do "application wide" settings with the current EJB1.1 spec. EJB has prescribed the interface between the EJB server/container and the components, but not between the components themselves. Steps have been taken in the J2EE specification to standardize this aspect.

First lets see what environment entries do:

Each EJB queries environment entries that it understands. The Bean Provider wants an environment entry for "defaultCurrency" or "maxTotalOrder", rather than hard-coding these or putting in his own configuration scheme. By choosing to use environment entries, the Bean Provider is giving the Application Assembler (and Deployer) the chance to modify the values of these environment entries.

Now, an application unit potentially consists of components from multiple providers. An environment entry used by Bean A will not make any sense to Bean B. So environment entries are scoped to a particular bean and the lookup of those entries must necessarily be context sensitive.

Without a standardized mechanism putting environment entries at the application scope is only useful in the special case where many of the Beans in the application unit arrive from the same Provider. To cater for this "special case" endangers the simplicity of the model.

If a vendor believes it's market would enjoy such a feature, then it is free to implement this feature in any way it likes, without affecting the underlying deployment descriptor. For example, the Application Assembler's GUI tool could allow the user to click on multiple Beans and change values of common environment entry names. Alternatives to implement application wide settings include using Properties/ResourceBundles in the ejb-jar or in special locations, or serializing a configuration object into the jar and using Beans.instantiate() to retrieve it. Or creating a SessionBean that is accessed by other beans to get the application properties, e.g.

class MyApplicationBean implements SessionBean
{
    public java.util.Properties getProperties()
    {
        // get properties from 'this' bean's environment.
    }

    ... other methods from SessionBean
}
Now the deployer just has to set environment properties on the MyApplicationBean, to which all other beans in the same application come to get their configuration.