Tomcat, JNDI and Spring bean application configuration

While setting up a Continuous Integration environment recently i faced an issue related to application (REST API in this case) configuration not being deployment-environment independent. Namely as the code pushed to Git repository and picked up by Jenkins build server was later on automatically deployed across several server environments (DEV, INT, STAGING, PROD) it turned out that in each of those environments the API application (war archive deployed in Tomcat container) requires to be fed with a specific/different configuration (environment-specific settings).


This is how i managed to solve this issue:


1. I created the following Tomcat context entry in “conf/context.xml” file:

    <Resource name="config/Api"
        sso="" />


2. Created the “CustomApiJNDIFactory” class:

public class CustomApiJNDIFactory implements ObjectFactory {

    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?,?> environment) throws Exception {

        validateProperty(obj, "Invalid JNDI object reference");

        String scheme = null;
        String host = null;
        String port = null;
        String version = null;
        String sso = null;

        Reference ref = (Reference) obj;

        Enumeration props = ref.getAll();

        while (props.hasMoreElements()) {

            RefAddr addr = props.nextElement();
            String propName = addr.getType();
            String propValue = (String) addr.getContent();

            switch (propName) {
                case "scheme":
                    scheme = propValue;
                case "host":
                    host = propValue;
                case "port":
                    port = propValue;
                case "version":
                    version = propValue;
                case "sso":
                    sso = propValue;


        // validate properties
        validateProperty(scheme, "Invalid or empty scheme type");
        validateProperty(host, "Invalid or empty server host name");
        validateProperty(port, "Invalid or empty port number");
        validateProperty(version, "Invalid or empty API version number");
        validateProperty(sso, "Invalid or empty SSO server name");

        //create API Configuration Bean
        return new ApiConfigBean(scheme, host, port, version, sso);


     * Validate internal String properties
     * @param property the property
     * @param errorMessage the error message
     * @throws javax.naming.NamingException
    private void validateProperty(String property, String errorMessage) throws NamingException {

        if (property == null || property.trim().equals("")) {
            throw new NamingException(errorMessage);




3. Defined an jndi-lookup entry in my “spring-api-context.xml” file that will read Tomcat JNDI configuration entry and expose it as a Spring bean of name jndiApi:

<jee:jndi-lookup id="jndiApi" jndi-name="java:/comp/env/config/Api" expected-type="com.mycompany.model.ApiConfigBean" />


4. Created the “jndiApi” Spring bean backing pojo

public class ApiConfigBean {

    private String scheme;
    private String host;
    private String port;
    private String version;
    private String sso;

    public ApiConfigBean(String scheme, String host, String port, String version, String sso) {
        this.scheme = scheme; = host;
        this.port = port;
        this.version = version;
        this.sso = sso;

    // getters and setters ommited.



5. and finally wired-in the bean to my classes where i needed to make use of the “externalized” configuration:

private ApiConfigBean apiConfigBean;

    public void foo() {

        String host = apiConfigBean.getHost();




That’s it! Have a wonderful day! 🙂


Tagged: , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: