I currently work in the capacity of Software Engineer at a reputed company in Sri Lanka. I'm most keen in J2EE Technologies and love working with open source libraries which fit my project needs. Very interested in the NoSQL concept and experimenting with various products to find a good blend for our projects within the company. Part time freelancer. Avid contributor in the stackoverflow arena. Android is another area which I am looking at with very keen interest as I believe mobile development is the way forward. Dinuka is a DZone MVB and is not an employee of DZone and has posted 24 posts at DZone. You can read more from them at their website. View Full User Profile

Setting up JNDI with Jetty (Embedded)

05.03.2012
| 7492 views |
  • submit to reddit
I was running embedded Jetty on my development work-space saving some time on vicious cycle of compiling and deployment. I have not worked with Jetty much and the ease of use made me hook on to it. I needed to set up JNDI in order to retrieve a connection pool for my database related activities. Though there were comprehensive documentation in some places, most were scattered. So this post is intended to be your one stop place for the requirement of setting up JNDI with Jetty. If it does not, please do leave a comment and i will be glad to help you out.

So starting off, first let us see how to setup Jetty to run as an embedded server. The folder structure of my eclipse project is as follows;



The etc folder will consist of all the configuration files required by jetty. You can download jetty from here. For this example i have used jetty-6.1.26.

Include the following jars from the given folder locations;


lib jetty-x.x.xx.jar, jetty-util-x.x.xx.jar,servlet-api-x.x.jar
lib/plus jetty-plus-x.x.xx.jar
lib/naming jetty-naming-x.x.xx.jar


For my example, i have set up mysql and therefore mysql-connector jar is also included in my library path.

Copy all the files residing in your jetty installation's etc directory to the etc directory of your eclipse project.

In order to enable JNDI, we first need to include jetty-plus. There are many ways you can do this such as providing it as a run-time argument, including it within your own jetty-env.xml residing in your WEB-INF or copying and pasting the required xml snippets from the jetty-plus.xml to your jetty.xml. I have chosen the latter. Hence, i have included the following snippet within my jetty.xml;
   <Array id="plusConfig" type="java.lang.String">
    <Item>org.mortbay.jetty.webapp.WebInfConfiguration</Item>
    <Item>org.mortbay.jetty.plus.webapp.EnvConfiguration</Item>
    <Item>org.mortbay.jetty.plus.webapp.Configuration</Item>
    <Item>org.mortbay.jetty.webapp.JettyWebXmlConfiguration</Item>
    <Item>org.mortbay.jetty.webapp.TagLibConfiguration</Item>
  </Array>

<call name="addLifeCycle">
      <arg>
        <new class="org.mortbay.jetty.deployer.WebAppDeployer">
          <set name="contexts"><ref id="Contexts"></ref></set>
          <set name="webAppDir"><systemproperty default="." name="jetty.home">/webapps</systemproperty></set>
          <set name="parentLoaderPriority">false</set>
          <set name="extract">true</set>
          <set name="allowDuplicates">false</set>
          <set name="defaultsDescriptor"><systemproperty default="." name="jetty.home">/etc/webdefault.xml</systemproperty></set>
          <set name="configurationClasses"><ref id="plusConfig"></ref></set>
        </new>
      </arg>
</call>
Next up, you need to add the XML fragment related to your data-source into your jetty.xml. I have added the snippet required for mysql. For any other database, please check this link. 
 
  <New id="myds" class="org.mortbay.jetty.plus.naming.Resource">

     <Arg>jdbc/MySQLDS</Arg>
     <Arg>
        <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
           <Set name="Url">jdbc:mysql://localhost:3306/test</Set>
           <Set name="User">root</Set>
           <Set name="Password">password</Set>
        </New>
     </Arg>
</New>
Now that we have setup everything, all you need to do is run jetty in your embedded environment. Following code shows you how to run Jetty in the embedded mode as part of your main class; 
 
import java.io.File;

import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.DefaultHandler;
import org.mortbay.jetty.handler.HandlerList;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.xml.XmlConfiguration;




public class JettyTest {

 public static void main(String[] args) throws Exception {
  Server jetty = new Server();
  String[] configFiles = {"etc/jetty.xml"};
  for(String configFile : configFiles) {
  XmlConfiguration configuration = new XmlConfiguration(new File(configFile).toURI().toURL());
  configuration.configure(jetty);
  }
  
  WebAppContext appContext = new WebAppContext();
  appContext.setContextPath("/myapp");
  File rd = new File("path_to_your_war_file");
  appContext.setWar(rd.getAbsolutePath());
  HandlerList handlers = new HandlerList();
  handlers.setHandlers(new Handler[]{ appContext, new DefaultHandler()});
  jetty.setHandler(handlers);
  jetty.start();
 }
}

Thats about it. Now you can look up your data-source which is exposed from Jetty. For ease, i have configured it with Spring's JNDIObjectFactoryBean. One important aspect to note is the jndi provider URL and the initial context factory entries required for Jetty. 
 
  <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <property name="environment">
            <props>
                <prop key="java.naming.factory.initial">org.mortbay.naming.InitialContextFactory</prop>
                <prop key="java.naming.provider.url">org.mortbay.naming</prop>
            </props>
        </property>
    </bean>
    
    <bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
   
        <property name="jndiTemplate">
          <ref bean="jndiTemplate"/>
        </property>
        <property name="jndiName">
              <value>jdbc/MySQLDS</value>
        </property>
      </bean>
With that you have all that you need to configure JNDI and access it through Spring's JNDI template. One other thing i was interested in was remote debugging with jetty server. After some searching i found that you need to include the following in your runtime configuration as VM arguments;
-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
This will enable you to remote debug your application on port 8000. If there are any queries please do leave a comment and i will be more than happy to help anyone. And of course if you do see any error, leave a reply too which again is much appreciated :). 
Published at DZone with permission of Dinuka Arseculeratne, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags: