Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Jndi Context and PropertyPlaceholderConfigurer

Using Spring, I want to read a variable inside the context of Webspehere.

Read a Environment Variable in Java with Websphere

To define the data.... inside web.xml

<env-entry>
   <env-entry-name>varName</env-entry-name>
   <env-entry-value>56</env-entry-value>
   <env-entry-type>java.lang.String</env-entry-type>
</env-entry>

To see with java

Context envEntryContext = (Context) new InitialContext().lookup("java:comp/env");
String mydata = (String)envEntryContext.lookup(“varName”);

But I want take the data in my common.xml like

<bean id="propertyPlaceholderConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>/WEB-INF/context/servweb.properties</value>
        </list>
    </property>
    <property name="ignoreUnresolvablePlaceholders">
        <value>true</value>
    </property>
</bean>

maybe with something like that

 <constructor-arg>
     <jee:jndi-lookup jndi-name="java:comp/env" default-value="data" /> 
  </constructor-arg>

but with context for do the same that

Context envEntryContext = (Context) new InitialContext().lookup("java:comp/env");
String mydata = (String)envEntryContext.lookup(“varName”);

maybe something like that:

 <constructor-arg>
    <jee:jndi-lookup  jndi-name="java:comp/env">
      <jee:environment>
          varName=default
     </jee:environment>
  </jee:jndi-lookup>

Anybody knows the correct way?

Thanks in Advance

like image 225
Kaltresian Avatar asked Jan 25 '12 06:01

Kaltresian


3 Answers

You can create your own PropertyPlaceholderConfigurer

public class JndiPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {

    private String jndiPrefix = "java:comp/env/";
    private JndiTemplate jndiTemplate = new JndiTemplate();

    @Override
    protected String resolvePlaceholder(String placeholder, Properties props) {
        String value = null;
        value = resolveJndiPlaceholder(placeholder);
        if (value == null) {
            value = super.resolvePlaceholder(placeholder, props);
        }
        return value;
    }

    private String resolveJndiPlaceholder(String placeholder) {
        try {
            String value = (String)jndiTemplate.lookup(jndiPrefix + placeholder, String.class);
            return value;
        } catch (NamingException e) {
            // ignore
        } 
        return null;
    }

    public void setJndiPrefix(String jndiPrefix) {
        this.jndiPrefix = jndiPrefix;
    }

    public void setJndiTemplate(JndiTemplate jndiTemplate) {
        this.jndiTemplate = jndiTemplate;
    }
}

and then use it in your applicationContext.xml

<bean id="propertyPlaceholderConfigurer"
      class="mypkg.helper.JndiPropertyPlaceholderConfigurer">
    <property name="properties">
        <props>
            <prop key="varName">default</prop>
        </props>
    </property>
</bean>

or for defining the default values in a properties file

<bean id="propertyPlaceholderConfigurer"
      class="mypkg.helper.JndiPropertyPlaceholderConfigurer">
    <property name="location" value="classpath:/defaults.properties"/>
</bean>
like image 196
beny23 Avatar answered Oct 19 '22 18:10

beny23


I'm doing the same thing in my webapplication but unable to read from Initialcontext

applicationcontext.xml has

<bean 
  class="com.test.webappl.JndiPropertyPlaceholderConfigurer"> 
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="location" value="file:c:\my.properties"/> 
</bean> 

my.properties has

default_mask=9999  

trying to read

Context context = new InitialContext();
String resource = context.lookup("java:comp/env/default_mask");

but the context's binding has only env-entry from web.xml, not from the properties file

like image 1
Anu Avatar answered Oct 19 '22 18:10

Anu


If you just want to get the value of a variable that was defined in the container context and use it as a String without creating a placeholder object, you can do the following (this was tested in Tomcat but most likely works the same in other container / JEE servers such as WebSphere):

Define the environment variable in Tomcat's context.xml (or use your own server's syntax) :

<Environment type="java.lang.String" name="myString" value="hello"/>

In the Spring XML context file :

Add the jee namespace to the root element :

xmlns:jee="http://www.springframework.org/schema/jee"

and in the the xsi:schemaLocation :

http://www.springframework.org/schema/jee       http://www.springframework.org/schema/jee/spring-jee-3.0.xsd

Now you can easily look up a value (note that you don't have to specify the java:/comp/env stuff, Spring does that for you):

<jee:jndi-lookup id="myStringValue"
                     jndi-name="myStringValue"
                     expected-type="java.lang.String" />

Then you can use it, for example pass it to the constructor of a bean as a reference :

<bean id="observationFileManager" class="my.service.Bean">
    <constructor-arg name="myString" ref="myStringValue" />
</bean>

The bean will receive "hello" as its construcotr arg.

EDIT :

If you run your Spring context outside the container (Tomcat, Websphere...) for integration testing, the lookup will not work. So if you have a special test context, just add the following String definition that will overrides the jee:lookup and set the value you want to use for testing :

<!-- This overrides the jndi jee:lookup used in the real context -->
<bean id="mediaFilesBaseDirPath" class="java.lang.String" >
    <constructor-arg value="Z:" />
</bean>
like image 1
Pierre Henry Avatar answered Oct 19 '22 19:10

Pierre Henry