1

I have the following:

Startup code:

    Server server = new Server(8080);

    WebAppContext context = new WebAppContext();

    context.setDescriptor("/WEB-INF/web.xml");
    context.setResourceBase("/home/webapp);
    context.setContextPath("/");
    context.setParentLoaderPriority(true);

    server.setHandler(context);

    server.start();

jetty-env.xml in /home/webapp/WEB-INF:

 <?xml version="1.0"?> 
 <Configure class="org.mortbay.jetty.webapp.WebAppContext">
   <New id="properties"  class="org.mortbay.jetty.plus.naming.EnvEntry">
     <Arg>property_file</Arg>
     <Arg>/home/webapp/web.properties</Arg>
   </New>  
 </Configure>

jndi.properties in classpath:

java.naming.factory.url.pkgs=org.eclipse.jetty.jndi
java.naming.factory.initial=org.eclipse.jetty.jndi.InitialContextFactory

The initial context is created OK, but attempting to lookup the property_file key throws name not found exception. Enumeration only returns the keys defined in jndi.properties.

Context initContext = new InitialContext();
Hashtable<?,?> ht = initContext.getEnvironment();
Enumeration<?> keys = ht.keys();
while(keys.hasMoreElements()) {
    Object key = keys.nextElement();
    System.out.println(key.toString() + "=" + ht.get(key).toString());
}

String props=(String)initContext.lookup("java:comp/env/property_file");

What am I doing wrong?

Ya.
  • 1,671
  • 4
  • 27
  • 53

2 Answers2

3

You have a bad mix of jetty versions.

<Configure class="org.mortbay.jetty.webapp.WebAppContext">
<New id="properties"  class="org.mortbay.jetty.plus.naming.EnvEntry">

That points to Jetty 6 use, and ...

java.naming.factory.url.pkgs=org.eclipse.jetty.jndi
java.naming.factory.initial=org.eclipse.jetty.jndi.InitialContextFactory

points to Jetty 9 use...

This is what is messing you up. The XML you are using will not work on Jetty 9 (Only Jetty 6), and the properties file you are defining should never be defined manually for Jetty 9 (its present in the jetty-jndi-{ver}.jar)

$ jar -tvf lib/jetty-jndi-9.2.9.v20150224.jar | grep jndi.properties
125 Tue Feb 24 10:49:42 MST 2015 jndi.properties

The instructions for Jetty 9 are found at

https://www.eclipse.org/jetty/documentation/current/jndi-embedded.html

This is how you setup Embedded Jetty with JNDI support. There's some parts you need to enable in the WebAppContext configuration, and that should enable the jetty-env.xml to be used.

Namely ...

// Enable parsing of jndi-related parts of web.xml and jetty-env.xml
Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration",
    "org.eclipse.jetty.plus.webapp.EnvConfiguration",
    "org.eclipse.jetty.plus.webapp.PlusConfiguration");

Finally, the jetty-env.xml structure and syntax are documented here

https://www.eclipse.org/jetty/documentation/current/jndi-configuration.html

So your example would look like this ...

<?xml version="1.0"?> 
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
   "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="wac" class="org.eclipse.jetty.webapp.WebAppContext">
  <New id="properties" class="org.eclipse.jetty.plus.jndi.EnvEntry">
    <Arg><Ref refid="wac"/></Arg>
    <Arg>property_file</Arg>
    <Arg>/home/webapp/web.properties</Arg>
    <Arg type="boolean">true</Arg>
  </New>
</Configure>

Yes, the DOCTYPE is important.

As for the 4 parameters on EnvEntry, those are documented at the APIDOC site for EnvEntry.

One last piece of advice, DO NOT USE jetty-all.jar for your project, it exists only to allow some basic command line experimentation with Jetty, it is not meant to be used as a dependency in your project.

Joakim Erdfelt
  • 46,896
  • 7
  • 86
  • 136
  • That link https://www.eclipse.org/jetty/documentation/current/jndi-embedded.html still doesn't tell me how to get jetty to read jetty-env.xml. It only tells me how to set jndi values programmatically. If the way I'm reading jetty-env.xml is wrong then I still don't know what way is right. – Ya. Mar 27 '15 at 19:38
  • Its part of the `Configuration.ClassList`, as outlined in the documentation (lines 18 thru 20 in the example in the documentation), and the answer above. The `EnvConfiguration` is what tells jetty to load the `jetty-env.xml`. None of your pasted examples show this, in any of your questions. I've mentioned `Configuration.ClassList` numerous times in comments and answers in your various questions. This is the key. I really don't know any way to make this more obvious. – Joakim Erdfelt Mar 27 '15 at 19:58
  • I think I finally understand... Configuration.ClassList will actually cause WEB-INF/jetty-env.xml to be read (during context initialization) as long as it's present. The way I interpreted it first was that it would only "enable" the parsing, but you still had to load it explicitly. – Ya. Mar 27 '15 at 20:15
1

My apologies, I'm new to jetty and I forgot to mention that I was using embedded mode. By now I've figured out that in the embedded mode jetty does NOT automatically read jetty-env.xml. You have to do it explicitly, for example:

    Resource jettyEnv = Resource.newSystemResource("jetty-env.xml");
    XmlConfiguration conf = new XmlConfiguration(jettyEnv.getInputStream());
    Object obj = conf.configure();
    WebAppContext context = (WebAppContext)obj;

The response about mixing different jetty versions does still apply.

Ya.
  • 1,671
  • 4
  • 27
  • 53
  • 1
    This is wrong, and completely ignores the webapp classloader, thread contexts, thread scopes, and jndi scopes required by JNDI and the servlet spec. Setup the `Configuration.ClassList` correctly, so that the WebAppContext initialization can load jetty-env.xml correctly (see answer above) – Joakim Erdfelt Mar 27 '15 at 17:59