I have got a problem with JNDI configuration on Jetty server. I cannot by any means configure it in a way that afterwards Spring (3.0.5) can retrieve JNDI variables.
I have some credentials which I do not want to store in properties so that it will not exist in git repo. My web application is running on Jetty (most recent version 9.2.3), thus I came up with idea to store this credentials in Jetty web application context. Jetty provides such solution with jetty-env.xml
. So I have created jetty-env.xml file in my WEB-INF/ like following:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="webappCtx" class="org.eclipse.jetty.webapp.WebAppContext">
<New id="username" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="webappCtx"/></Arg> <!-- scope -->
<Arg>server/username</Arg> <!-- name -->
<Arg type="java.lang.String">myUsername</Arg> <!-- value -->
</New>
<New id="password" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="webappCtx"/></Arg> <!-- scope -->
<Arg>server/password</Arg> <!-- name -->
<Arg type="java.lang.String">qwerty</Arg> <!-- value -->
</New>
</Configure>
After that I have defined binding in the web.xml
as follows:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="MyWebApp" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>My Web App</display-name>
<!-- INITIALIZE SPRING -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- JETTY-ENV JNDI -->
<resource-ref>
<res-ref-name>server/username</res-ref-name>
<res-type>java.lang.String</res-type>
</resource-ref>
<resource-ref>
<res-ref-name>server/password</res-ref-name>
<res-type>java.lang.String</res-type>
</resource-ref>
</web-app>
And configured my Spring context in this way:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<jee:jndi-lookup id="serverUsername" jndi-name="server/username" expected-type="java.lang.String" resource-ref="true" />
<jee:jndi-lookup id="serverPassword" jndi-name="server/password" expected-type="java.lang.String" resource-ref="true"/>
<bean name="abstractServerConnectionFactory" class="my.package.ServerConnectionFactory" abstract="true">
<constructor-arg value="${server.host}"/>
<constructor-arg value="${server.port}"/>
<constructor-arg ref="serverUsername"/>
<constructor-arg ref="serverPassword"/>
</bean>
</beans>
After that I am starting Jetty with --add-to-startd=jndi
enabled and I am always getting javax.naming.NameNotFoundException
when creating serverUsername
and serverPassword
. I have tried many modfication, but non have seem to work. I have tried:
org.eclipse.jetty.plus.jndi.Resource
to org.eclipse.jetty.plus.jndi.EnvEntry
and then refering to it via resource-env-ref
in web.xml<Arg><Ref refid="webappCtx"/></Arg>
to <Arg></Arg>
as mentioned here<Call name="bindToENC">
<Arg>server/username</Arg> <!-- binds server/username to java:comp/env/server/username for this webapp -->
</Call>
And many other, but it just does not work. Please give me a working example how I can get it to work. Thank you!
Ok so I have managed to get this working. The problem was the configuration. I am using Jetty 9 so according to the official documentation (https://eclipse.dev/jetty/documentation/jetty-9/index.html#jndi-quick-setup) the only thing that needs to be done prior to using JNDI in Jetty is adding jndi
module to start.d
by doing --add-to-startd=jndi
. And well, that's not exactly true, because this will enable JNDI, BUT WILL NOT INCLUDE jetty-env.xml
contents (Jetty do not even touch it). I've been reading about the container lifecycle and noticed that in order to use JNDI one need to include following classes in the web application context configuration classes set:
This is done by default in $JETTY_HOME/etc/jetty-plus.xml
, which is config file for plus
module. So in order to add this classes into the Jetty container lifecycle, and by this include and parse jetty-env.xml, one need to enable plus module in addition to jndi module (jndi does not depend upon plus)! Thus I have changed my start.d config by invoking --add-to-startd=jndi,plus
(no space between modules) and everything started working like a charm.