Using resource environment providers in WebSphere Application Server

Most of the time in Web applications, environment-specific variables are either stored as key value pairs in properties files, or as env-entries in the web.xml file. The drawback here is the need to modify either of these files if any of these variables need to change, potentially introducing errors -- especially in a clustered environment where the files are distributed across multiple nodes. Using a resource environment provider in IBM® WebSphere® Application Server helps avoid the need to alter deployed files to change any environment-dependent variables (and thus avoid making changes to the deployed application). This article explains how to use the resource environment provider, and how to manage application- or environment-dependent variables through the administrative control in WebSphere Application Server V6.x.

Share:

Hara Totapally (hgtotapa@us.ibm.com), Senior IT Specialist, IBM India Software Lab Services and Solutions

Author photoHara Totapally is a Senior IT Specialist at IBM Costa Mesa, California, and can be reached at hgtotapa@us.ibm.com.



01 November 2006

Also available in Chinese

Introduction

Generally speaking, deploying a typical Web application usually consists of deploying a single .ear (or .war) file, first in an integration test environment, then in a test environment, and finally in the production environment. Environment-specific variables, important for executing the application properly at each stage in the deployment process, can be stored either as key value pairs in properties, as env-entries in web.xml, or as lookup values in a relational database. Whether storing these application variables in a relational database is a good idea or not is subject to some debate. However, storing the application variables in properties files (or in deployment descriptors) requires that you modify the properties files (or the deployment descriptors) after they have already been deployed to tailor these variables for each particular environment, or write scripts to use different sets of files during application packaging time. In all cases, these files are necessarily different across different environments.

While making changes to the deployed files (properties files or web.xml) after deployment can be error prone (making changes in a multi-node clustered system can be even more error prone), whether or not this procedure is acceptable depends on your organization's guidelines. Regardless, as an alternative to this generally undesirable practice, you can use the resource environment provider to avoid and eliminate the problems mentioned above: by configuring such application dependent variables as resource environment entries, you can administer them using the WebSphere Application Server administrative console -- without having to resort to modifying deployed files.

This article explains how to create a resource environment provider, referenceable objects, and custom properties, plus how to administer the custom properties in the WebSphere Application Server administrative console, and how to access these properties in the application.

This article assumes a good understanding of Java™ programming, WebSphere Application Server V6 administration, and J2EE™ technologies.


Resource environment provider

WebSphere Application Server Versions 5.x and 6.x support the referencing of a resource environment reference, which is similar to referencing other already supported resource references, such as a DataSource, QueueConnection factories, and so on, and is accessible through JNDI lookups. While the classes for DataSource, QueueConnection factories, and others, are predefined in WebSphere Application Server, you must create the classes required for referencing a resource environment provider yourself.

At a minimum, two classes are required to use the resource environment provider in an application: a factory class, and a class that provides custom properties. It is mandated that the factory class implement the interface javax.naming.spi.ObjectFactory. The method getObjectInstance(...) returns the class holding the custom properties. With the help of these two classes and the administration support provided by WebSphere Application Server, we can convert the properties defined in the properties file (or in a deployment descriptor file) into managed variables, and administer them through the WebSphere Application Server administrative console. Once these managed variables can be managed through the admin console, any environment-specific variable can be administered through the console, and the need to alter the deployed properties files or to create environment-specific properties files is eliminated. With this approach, each environment uses the same deployed files.


Sample implementation

An example will help explain these concepts. The example we will look at uses two classes:

  • ConfigFactory
  • Config

Listings 1 and 2 show the code for both of these.

Listing 1. ConfigFactory.java
package com.ibm.acme.ree.lib;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

public class ConfigFactory implements ObjectFactory
{
	private static Config config = null;
	public Object getObjectInstance(
		Object object,
		Name name,
		Context nameCtx,
		Hashtable environment)
		throws NamingException
	{
		if(config == null)
		{
			config = new Config();
			Reference ref = (Reference) object;
			Enumeration addrs = ref.getAll();
			RefAddr addr = null;
			String entryName = null;
			String value = null;
			while (addrs.hasMoreElements())
			{
				addr = (RefAddr) addrs.nextElement();
				entryName = addr.getType();
				value = (String) addr.getContent();
				config.setAttribute(entryName, value);
			}	
		}
		return config;
	}
}
Listing 2. Config.java
package com.ibm.acme.ree.lib;

import java.util.HashMap;
import java.util.Map;

public class Config
{
	private Map attributes = null;
	public Config()
	{
		attributes = new HashMap(10);
	}
	protected void setAttribute(String attributeName, String attributeValue)
	{
		attributes.put(attributeName, attributeValue);
	}
	public Object getAttribute(String attributeName)
	{
		return attributes.get(attributeName);
	}
}

The caching of the custom properties is illustrated in ConfigFactory.java (Listing 1). Depending on the application requirements, the properties could be made dynamic, thereby avoiding the caching in the above code.

To create and use a resource environment provider in a Web application, you need to:

  1. Create a shared library
  2. Create a resource environment provider
  3. Create a referenceable object.
  4. Create resource environment entries.
  5. Create custom properties.
  6. Create resource environment reference within the Web module.

The sections that follow illustrate these steps.

1. Create a shared library

Create a simple shared library so that the classes can be used for all applications hosted on the server. WebSphere Application Server provides a wizard to do this:

  1. Compile the two classes, Config.java and ConfigFactory.java, and create a JAR file, named reelib.jar.

  2. Copy the JAR file to a location of your choice, such as C:\temp\.

  3. From the WebSphere Application Server administrative console, expand Environment => Shared Libraries.

  4. Set the library Scope to Cell, then select New (Figure 1).

    Figure 1. Set shared library scope
    Figure 1. Set shared library scope
  5. Enter a Name for the library: ree_lib.

  6. Enter a text Description and a Classpath name for the library, then select Apply (Figure 2).

    Figure 2. Define shared library
    Figure 2. Define shared library
  7. Save changes to complete the library creation. The new library will be listed, as shown in Figure 3

    Figure 3. Available shared library listing
    Figure 3. Available shared library listing

2. Create a resource environment provider

To create a resource environment provider:

  1. From the administrative console, select References => Resource Environment => Resource Environment Providers (Figure 4).

    Figure 4. Create Resource environment provider
    Figure 4. Create Resource environment provider
  2. Set the Scope level to Cell, then select New (Figure 5).

    Figure 5. Create new resource environment provider
    Figure 5. Create new resource environment provider
  3. Name the resource environment provider MyResourceEnvironmentProvider, enter a Description for the resource, then click OK (Figure 6).

    Figure 6. Define resource environment provider
    Figure 6. Define resource environment provider
  4. Save changes.

When complete, the newly created resource environment provider will be listed in the display (Figure 7).

Figure 7. Available resource environment provider
Figure 7. Available resource environment provider

3. Create a referenceable object

A "referenceable" is the object defining the relationship between the factory class and the class holding the custom properties. To create a referenceable:

  1. From the administrative console, expand Resources => Resource References => Resource Environment Providers.

  2. From the Resource environment providers panel (Figure 8), select the provider you just created, MyResourceEnvironmentProvider.

    Figure 8. Select resource environment provider
    Figure 8. Select resource environment provider
  3. Select Referenceables (Figure 9).

    Figure 9. Resource environment provider detail
    Figure 9. Resource environment provider detail
  4. Click on New.

  5. The classes defined earlier, com.ibm.acme.ree.lib.ConfigFactory and com.ibm.acme.ree.lib.Config, are used to create Referenceables. On the Referenceables dialog (Figure 10), enter fully qualified class names for Factory class (com.ibm.acme.ree.lib.ConfigFactory) and Class name (com.ibm.acme.ree.lib.Config), then select OK. The defined referenceable will then display, as shown in Figure 11.

    Figure 10. Define referenceable
    Figure 10. Define referenceable
    Figure 11. Defined referenceables
    Figure 11. Defined referenceables
  6. Save changes.

4. Create resource environment entries

About variable names
If you use different names to define any elements than those used in these examples, be sure to note them and substitute them where appropriate throughout these instructions.

A resource environment entry enables access to the resource by reference via JNDI lookup. To define a resource environment entry:

  1. From the administrative console, expand Resources => Resource Environment => Resource Environment Providers => MyResourceEnvironmentProvider.

  2. Select Resource environment entries (Figure 12).

    Figure 12. Resource environment provider detail
    Figure 12. Resource environment provider detail
  3. On the next dialog, select New (Figure 13).

    Figure 13. Create new resource environment entry
    Figure 13. Create new resource environment entry
  4. On the Configuration dialog (Figure 14), enter values for Name (MyResourceReference) and JNDI name (rep/dev/app1/MyResourceReference). This JNDI name is used during application deployment resource reference mapping.

    Figure 14. Configure resource environment entry
    Figure 14. Configure resource environment entry
  5. Click OK, then save the changes.

    Figure 15. Defined resource environment entry
    Figure 15. Defined resource environment entry

5. Create custom properties

To define the custom properties that would be used in the application:

  1. From the administrative console, expand navigate to Resources => Resource Environment => Resource Environment Providers => MyResourceEnvironmentProvider => Resource Environment Entries => MyResourceReference.

  2. Select Custom properties (Figure 16).

    Figure 16. Select custom properties
    Figure 16. Select custom properties
  3. Select New. (Figure 17)

    Figure 17. Create new custom properties
    Figure 17. Create new custom properties
  4. Enter values for the Name (MyVariable), Description, Type, and Value fields, then OK. (Figure 18)

    Figure 18. Define custom property
    Figure 18. Define custom property
    Figure 19. Defined custom properties
    Figure 19. Defined custom properties
  5. The custom property you defined appears in the custom properties list (Figure 19). Repeat step d to add additional variables.

Notice that the wizard provided by WebSphere Application Server does not provide an option to specify the required attribute, although it defaults to false. Through WebSphere admin scripting, you can specify a value for the required attribute. If you are running a standalone application server, or if it is a member in a cluster, the new resources you defined are available after restarting the application server.

6. Create resource environment reference within the Web module

Similar to accessing any resource within a container, to access the resource reference entries, you have to declare a reference within the Web module or EJB module, as appropriate. To create a resource reference using IBM Rational® Application Developer:

  1. For a Web module, open the web.xml file (for an EJB module, open the ejb-jar.xml file ) using the deployment descriptor editor.

  2. Click on the References tab, then select Add (Figure 20).

    Figure 20. Deployment descriptor editor
    Figure 20. Deployment descriptor editor
  3. From the Add Reference dialog, select Resource environment reference, then Next (Figure 21).

    Figure 21. Add a reference
    Figure 21. Add a reference
  4. Enter values for Name (MyConstants), Type, and Description, then select Finish (Figure 22).

    Figure 22. Configure resource environment reference
    Figure 22. Configure resource environment reference

Using the resource environment provider elements

This code sample in Listing 3 shows how to access the referenceable and the associated custom properties.

Listing 3. Accessing custom properties
try {
	Context ctx = new InitialContext();
	Object object = 
ctx.lookup("java:comp/env/MyConstants");
	Config config = (Config) config;
	String myVariable = config.getProperty("MyVariable");
} catch (Exception e) {
	// .. Handle Exception e
}

Before you can actually use the resource environment provider you created, you have to define the implementation classes within the application's classpath. This can be done by mapping the shared libraries at application deployment time. We will not show the full application deployment process here, but we will show the necessary steps to map the shared library:

  1. On the Preparing for the application installation dialog, select your WAR file, then check Local file system and Show me all installation options, then Next (Figure 23).

    Figure 23. Prepare application for deployment
    Figure 23. Prepare application for deployment
  2. Continue with the application deployment process, selecting default values (or other values, at your discretion), through installation Steps 1, 2, and 3. When you arrive at Step 4: Map Shared Libraries (Figure 24), check the module you want to select, then click Reference shared libraries.

    Figure 24. Display shared map libraries
    Figure 24. Display shared map libraries
  3. On the Enterprise Applications dialog, select the library you want to add to the application's classpath, ree_lib, then click on the >> button to adds the selected library to the Selected list. Click OK. (Figure 25)

    Figure 25. Select shared libraries
    Figure 25. Select shared libraries
  4. Make sure that the library is added to the application classpath by examining the Shared Libraries column, as shown in Figure 26.

  5. Continue with the application deployment process.

    Figure 26. Map shared libraries
    Figure 26. Map shared libraries
  6. On step 5 of application deployment, Map resource environment entry references to resources, enter the JNDI name of the referenceable (rep/dev/app1/MyResourceReference) into the field Target Resource JNDI Name field.

  7. Continue with the application deployment process.

    Figure 27. Specify resource environment entry
    Figure 27. Specify resource environment entry

After the application has been deployed, you will want to test the application's use of the resource environment provider. To do so, you need to first restart the application. Once started, you can easily verify that the application is taking its value from the resource environment entry, rather than from a property defined in a property file, or from an environment entry defined in web.xml or ejb-jar.xml. Whenever needed, you can alter this variable by changing the value from the WebSphere Application Server administrative console and restarting the cluster members -- all without touching any deployed files, retaining the integrity of the entire application and its processing environments.


Conclusion

This article discussed the use of resource environment entries as an alternative to using properties files or deployment descriptor files for environment-specific application variables. Information on the WebSphere implementation of resource environment providers, referenceable objects, resource environment entries, and custom properties were discussed, along with instructions on mapping a shared library, and mapping resource environment entry references to resources during deployment.


Acknowledgements

The author wishes to express sincere thanks to Tom Bergman, IBM IT Architect, for reviewing and commenting on this article.

Resources

Learn

Get products and technologies

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=171867
ArticleTitle=Using resource environment providers in WebSphere Application Server
publish-date=11012006