Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configure embedded jetty with web.xml?

I am trying to generate both a war with my web application as well as a self contained jar file with embedded jetty. For the embedded jetty (the jar file distribution) I add a servlet as follows:

public static void main(String[] args) throws Exception {     Server server = new Server(8080);      ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);     context.setContextPath("/");     server.setHandler(context);      context.addServlet(new ServletHolder(new HelloServlet()),"/*");      server.start();     server.join(); } 

The war file distribution uses a web.xml file that contains the following in the web-app section:

<servlet>     <servlet-class>com.example.HelloServlet</servlet-class>     <servlet-name>SimplestServer</servlet-name> </servlet> <servlet-mapping>     <servlet-name>HelloServlet</servlet-name>     <url-pattern>/*</url-pattern> </servlet-mapping> 

This works. However, I want to get rid of the duplication between the two approaches. I.e., when I add a new servlet I want to have to configure it in only one location. Can I load and use the web.xml file from the embedded jetty?

like image 740
Stephan Avatar asked Dec 26 '13 14:12

Stephan


People also ask

What is Jetty XML file?

The Jetty XML syntax is a straightforward mapping of XML elements to a Java API so that POJOs can be instantiated and getters, setters and methods called. It is very similar to Inversion Of Control (IOC) or Dependency Injection (DI) frameworks like Spring or Plexus (but it predates all of them).

Is Jetty a web server?

Jetty provides a web server and servlet container, additionally providing support for HTTP/2, WebSocket, OSGi, JMX, JNDI, JAAS and many other integrations. These components are open source and are freely available for commercial use and distribution.

How does a Jetty server work?

The Jetty Server is the plumbing between a collection of Connectors that accept HTTP connections, and a collection of Handlers that service requests from the connections and produce responses, with the work being done by threads taken from a thread pool.


1 Answers

Use a org.eclipse.jetty.webapp.WebAppContext

Example:

package jetty;  import org.eclipse.jetty.server.Server; import org.eclipse.jetty.webapp.WebAppContext;  public class OnWebApp {     public static void main(String[] args) throws Exception     {         // Create a basic jetty server object that will listen on port 8080.         // Note that if you set this to port 0 then a randomly available port         // will be assigned that you can either look in the logs for the port,         // or programmatically obtain it for use in test cases.         Server server = new Server(8080);          // The WebAppContext is the entity that controls the environment in         // which a web application lives and breathes. In this example the         // context path is being set to "/" so it is suitable for serving         // root context requests and then we see it setting the location of         // the war. A whole host of other configurations are available,         // ranging from configuring to support annotation scanning in the         // webapp (through PlusConfiguration) to choosing where the webapp         // will unpack itself.         WebAppContext webapp = new WebAppContext();         webapp.setContextPath("/");         webapp.setWar("path/to/my/test.war");          // A WebAppContext is a ContextHandler as well so it needs to be set to         // the server so it is aware of where to send the appropriate requests.         server.setHandler(webapp);          // Start things up! By using the server.join() the server thread will         // join with the current thread.         // See http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()         // for more details.         server.start();         server.join();     } } 

Note that you will build a normal WAR file, and use it with Jetty.

If you have special requirements such as Annotation scanning or JNDI, then you'll need to get into configuration specification.

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

For a longer example of this in a WebAppContext, see the ServerWithAnnotations example.

Also note that you will have all of the webapp classloader rules in place using this technique as well. Meaning you will have a classloader for the webapp and another one for the server. This is important to understand.

There are a few tweaks you can do to the WebAppContext for classloaders, but you can't eliminate them, just control how they behave.

WebAppContext webapp = new WebAppContext(); // ... various setup of the webapp ... // Flip the classloader priority from servlet spec where webapp is first to // Standard java behavior of parent (aka Server classloader) is first. webapp.setParentLoaderPriority(true); 

See also:

  • WebAppContext.setClassLoader(ClassLoader classloader)
  • WebAppContext.addServerClass(String classOrPackage)
  • WebAppContext.addSystemClass(String classOrPackage)
like image 95
Joakim Erdfelt Avatar answered Sep 17 '22 14:09

Joakim Erdfelt