Announcement Announcement Module
Collapse
No announcement yet.
Embedding a web container Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Embedding a web container

    Hi All,

    I have a standalone application in which I am embedding the Jetty webserver. The Jetty server will run a Spring MVC app, alongside the rest of the application.

    I would like to have the WebApplicationContext have the main applications ApplicationContext as a parent, but I am at a loss as to how to make this come together. I am constructing the Jetty server via Java code, and I have tried all different permuations of adding the DispatcherServlet manually, setting a context attribute with a dummy WebApplicationContext, etc. -- as yet, I have had no success.

    Does anyone have any idea as to how you might go about doing this?

    Thanks,
    mug

  • #2
    Firstly, unless i misunderstand you, you won't be able to set your org.mortbay.jetty.servlet.WebApplicationContext as a parent to your org.springframework.context.ApplicationContext ClassCastException etc.

    I'm doing something similar however which may solve your problem. I have a class Launcher I use to launch my application during development and acceptance testing - during testing this allows me to access the springApplicationContext directly in my tests.

    Code:
    import org.apache.log4j.Logger;
    import org.mortbay.http.SocketListener;
    import org.mortbay.jetty.Server;
    import org.mortbay.jetty.servlet.WebApplicationContext;
    import org.mortbay.util.MultiException;
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.web.context.support.XmlWebApplicationContext;
    
    import java.util.Locale;
    public class Launcher
    {
        private WebApplicationContext jettyWebAppContext;
        private Server server;
        Logger logger = Logger.getLogger(getClass());
    
        public Launcher()
        {
            Locale.setDefault(Locale.ENGLISH);
            logger.info("Configuring jetty server");
    
            System.setProperty("java.io.tmpdir", "output/");
            System.setProperty("LOG_CLASSES", "org.mortbay.util.log4j.Log4jSink");
    
            server = new Server();
    
            SocketListener listener = new SocketListener();
            listener.setPort(8090);
            server.addListener(listener);
    
            jettyWebAppContext = new WebApplicationContext("output/webapp/war/");
            jettyWebAppContext.setDefaultsDescriptor("etc/jetty/webdefault.xml");
            jettyWebAppContext.setClassLoaderJava2Compliant(true);
            jettyWebAppContext.setContextPath("/");
            server.addContext(jettyWebAppContext);
        }
    
        public void start() throws MultiException
        {
            logger.info("Starting jetty server");
            try
            {
                server.start();
            } catch (MultiException e)
            {
                logger.warn("While starting jetty server", e);
                throw e;
            }
        }
    
        public AbstractApplicationContext getSpringContext()
        {
            Object o = jettyWebAppContext.getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.scoilbuy");
            XmlWebApplicationContext springApplicationContext = (XmlWebApplicationContext) o;
    
            return springApplicationContext;
        }
    
        public static void main(String[] args) throws MultiException
        {
            Launcher launcher = new Launcher();
            launcher.start();
        }
    
        public void stop() throws InterruptedException
        {
            server.stop();
        }
    }

    Comment


    • #3
      Well, after a little wrangling, I was able to get this working. Here's the code from my bean that starts the Jetty server:

      Code:
      WebApplicationContext ctx = server.addWebApplication("/", dir);
      ctx.getServletContext().setAttribute("PARENT_APPCTX", springAppContext);
      ....
      server.start();
      I then extended the DispatcherServlet and overriding the initWebApplicationContext() method and overloading the createWebApplicationContext() method to allow me to set a regular Spring ApplicationContext as a parent to a Spring WebApplicationContext (These are mostly copied from their superclass versions, but they get the job done):

      Code:
      	protected WebApplicationContext initWebApplicationContext() throws BeansException {
      		ApplicationContext appCtx = (ApplicationContext)getServletContext().getAttribute("PARENT_APPCTX");
      
      		WebApplicationContext wac = createWebApplicationContext(appCtx);
      		if (logger.isInfoEnabled()) {
      			logger.info("Using context class [" + wac.getClass().getName() + "] for servlet '" +
      					getServletName() + "'");
      		}
      
      		if (isPublishContext()) {
      			// Publish the context as a servlet context attribute.
      			String attrName = getServletContextAttributeName();
      			getServletContext().setAttribute(attrName, wac);
      			if (logger.isDebugEnabled()) {
      				logger.debug("Published WebApplicationContext of servlet '" + getServletName() +
      						"' as ServletContext attribute with name [" + attrName + "]");
      			}
      		}
      
      		return wac;
      	}
      	
      	
      	/* (non-Javadoc)
      	 * @see org.springframework.web.servlet.FrameworkServlet#createWebApplicationContext(org.springframework.web.context.WebApplicationContext)
      	 */
      	protected WebApplicationContext createWebApplicationContext(
      			ApplicationContext parent) throws BeansException {
      		if (logger.isDebugEnabled()) {
      			logger.debug("Servlet with name '" + getServletName() +
      					"' will try to create custom WebApplicationContext context of class '" +
      					getContextClass().getName() + "'" + ", using parent context [" + parent + "]");
      		}
      		if (!ConfigurableWebApplicationContext.class.isAssignableFrom(getContextClass())) {
      			throw new ApplicationContextException(
      					"Fatal initialization error in servlet with name '" + getServletName() +
      					"': custom WebApplicationContext class [" + getContextClass().getName() +
      			"] is not of type ConfigurableWebApplicationContext");
      		}
      		
      		ConfigurableWebApplicationContext wac =
      			(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass());
      		wac.setParent(parent);
      		wac.setServletContext(getServletContext());
      		wac.setNamespace(getNamespace());
      		if (getContextConfigLocation() != null) {
      			wac.setConfigLocations(
      					StringUtils.tokenizeToStringArray(
      							getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
      		}
      		wac.refresh();
      		return wac;
      		
      	}

      Comment

      Working...
      X