Search code examples
javaspringmavenjndi

Using JNDI for for my datasource and location of properties files


I want to use jndi in my spring mvc application for 2 things:

  1. datasource settings
  2. store the location of my properties file so I can do a lookup in my code

I actually have 2 applications, 1 is a spring mvc and the other is a spring so I'm planning on using the same jndi settings for both.

Also, the 2 applications run on different contains (tomcat and jetty), I've never used jndi before so I hope I can define this in a single location and have both applications point to the same jndi file (assuming its a file).

So as for #1, my datasource settings in my spring context file are currently:

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost/mydb_development"/>
        <property name="username" value="devuser1"/>
        <property name="password" value="123"/>

        <property name="maxActive" value="100"/>
        <property name="maxIdle" value="30"/>
        <property name="maxWait" value="1000"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>

        <property name="testOnBorrow" value="true"/>
        <property name="validationQuery" value="SELECT 1"/>

    </bean>

Can someone tell me how I can extract this out to use JNDI, confused, is it a separate file that has to be in my class loader, or do I hard code the path in my spring context file?

And as for #2, in my code I am currently loading a properties file that is in my class path like:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream is = classLoader.getResourceAsStream("test.properties");

Now the test.properties file is in my classpath so it works out of the box, but what I want to know/understand is if I could somehow use jndi to lookup the location of the properties file (if that makes sense?) and not have this file in my classpath potentially.

I did google around and I know in spring I can pull in jndi using:

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/mysqlDataSource" />

But what I don't understand is, where is the actual file that has the settings? Can it be in a location other than my web.xml file? (my other application again is using spring, but it is a daemon so it doesn't have a web.xml file).

The goal for me is to be able to change the values of the jndi file (like username, passwords, file paths) and NOT have these embedded into a jar. I want to be able to manually edit these files on the production server or dev servers and just restart the container.


Solution

  • I'm kinda rusty with spring but I remember using a PropertyPlaceHolderConfigurer, something like:

    <bean id="propertyPlaceholderConfigurer"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="ignoreResourceNotFound">
                <value>true</value>
            </property>
            <property name="ignoreUnresolvablePlaceholders">
                <value>true</value>
            </property>
            <property name="locations">
                <list>
                    <value>file:path to your file
                    </value>
                    <value>file:path to another file if needed
                    </value>
                </list>
            </property>
        </bean>
    

    Then you can use the values on the .properties defined on the list directly. i.e. if you have a property like

    db.driver=com.mysql.jdbc.Driver
    

    you can use it like

    bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
            <property name="driverClassName" value="${db.driver}"/>
    

    when you want to define a value.

    If you want further control over the file, the path to the file itself can be registered on your server and you can look it up through JNDI, changing

    file:path to your file 
    

    into

    file:${propertiesFilePath}
    

    I'm pretty sure you can look up those configuration properties by code too by a normal JNDI lookup.