Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8807737
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T02:26:29+00:00 2026-06-14T02:26:29+00:00

I’m trying to create a simple webapp without any XML configuration using Spring 3.1

  • 0

I’m trying to create a simple webapp without any XML configuration using Spring 3.1 and an embedded Jetty 8 server.

However, I’m struggling to get Jetty to recognise my implementaton of the Spring WebApplicationInitializer interface.

Project structure:

src
 +- main
     +- java
     |   +- JettyServer.java
     |   +- Initializer.java
     | 
     +- webapp
         +- web.xml (objective is to remove this - see below).

The Initializer class above is a simple implementation of WebApplicationInitializer:

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.springframework.web.WebApplicationInitializer;

public class Initializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        System.out.println("onStartup");
    }
}

Likewise JettyServer is a simple implementation of an embedded Jetty server:

import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;

public class JettyServer {

    public static void main(String[] args) throws Exception { 

        Server server = new Server(8080);

        WebAppContext webAppContext = new WebAppContext();
        webAppContext.setResourceBase("src/main/webapp");
        webAppContext.setContextPath("/");
        webAppContext.setConfigurations(new Configuration[] { new AnnotationConfiguration() });
        webAppContext.setParentLoaderPriority(true);

        server.setHandler(webAppContext);
        server.start();
        server.join();
    }
}

My understanding is that on startup Jetty will use AnnotationConfiguration to scan for
annotated implementations of ServletContainerInitializer; it should find Initializer and wire it in…

However, when I start the Jetty server (from within Eclipse) I see the following on the command-line:

2012-11-04 16:59:04.552:INFO:oejs.Server:jetty-8.1.7.v20120910
2012-11-04 16:59:05.046:INFO:/:No Spring WebApplicationInitializer types detected on classpath
2012-11-04 16:59:05.046:INFO:oejsh.ContextHandler:started o.e.j.w.WebAppContext{/,file:/Users/duncan/Coding/spring-mvc-embedded-jetty-test/src/main/webapp/}
2012-11-04 16:59:05.117:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8080

The important bit is this:

No Spring WebApplicationInitializer types detected on classpath

Note that src/main/java is defined as a source folder in Eclipse, so should be on the classpath. Also note that the Dynamic Web Module Facet is set to 3.0.

I’m sure there’s a simple explanation, but I’m struggling to see the wood for the trees! I suspect the key is with the following line:

...
webAppContext.setResourceBase("src/main/webapp");
...

This makes sense with a 2.5 servlet using web.xml (see below), but what should it be when using AnnotationConfiguration?

NB: Everything fires up correctly if I change the Configurations to the following:

...
webAppContext.setConfigurations(new Configuration[] { new WebXmlConfiguration() });
...

In this case it finds the web.xml under src/main/webapp and uses it to wire the servlet using DispatcherServlet and AnnotationConfigWebApplicationContext in the usual way (completely bypassing the WebApplicationInitializer implementation above).

This feels very much like a classpath problem, but I’m struggling to understand quite how Jetty associates itself with implementations of WebApplicationInitializer – any suggestions would be most appreciated!

For info, I’m using the following:

Spring 3.1.1
Jetty 8.1.7
STS 3.1.0

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T02:26:31+00:00Added an answer on June 14, 2026 at 2:26 am

    The problem is that Jetty’s AnnotationConfiguration class does not scan non-jar resources on the classpath (except under WEB-INF/classes).

    It finds my WebApplicationInitializer‘s if I register a subclass of AnnotationConfiguration which overrides configure(WebAppContext) to scan the host classpath in addition to the container and web-inf locations.

    Most of the sub-class is (sadly) copy-paste from the parent. It includes:

    • an extra parse call (parseHostClassPath) at the end of the configure method;
    • the parseHostClassPath method which is largely copy-paste from
      AnnotationConfiguration‘s parseWebInfClasses;
    • the getHostClassPathResource method which grabs the first non-jar URL
      from the classloader (which, for me at least, is the file url to my
      classpath in eclipse).

    I am using slightly different versions of Jetty (8.1.7.v20120910) and Spring (3.1.2_RELEASE), but I imagine the same solution will work.

    Edit: I created a working sample project in github with some modifications (the code below works fine from Eclipse but not when running in a shaded jar) – https://github.com/steveliles/jetty-embedded-spring-mvc-noxml

    In the OP’s JettyServer class the necessary change would replace line 15 with:

    webAppContext.setConfigurations (new Configuration []
    {
            new AnnotationConfiguration() 
            {
                @Override
                public void configure(WebAppContext context) throws Exception
                {
                    boolean metadataComplete = context.getMetaData().isMetaDataComplete();
                    context.addDecorator(new AnnotationDecorator(context));   
    
                    AnnotationParser parser = null;
                    if (!metadataComplete)
                    {
                        if (context.getServletContext().getEffectiveMajorVersion() >= 3 || context.isConfigurationDiscovered())
                        {
                            parser = createAnnotationParser();
                            parser.registerAnnotationHandler("javax.servlet.annotation.WebServlet", new WebServletAnnotationHandler(context));
                            parser.registerAnnotationHandler("javax.servlet.annotation.WebFilter", new WebFilterAnnotationHandler(context));
                            parser.registerAnnotationHandler("javax.servlet.annotation.WebListener", new WebListenerAnnotationHandler(context));
                        }
                    }
    
                    List<ServletContainerInitializer> nonExcludedInitializers = getNonExcludedInitializers(context);
                    parser = registerServletContainerInitializerAnnotationHandlers(context, parser, nonExcludedInitializers);
    
                    if (parser != null)
                    {
                        parseContainerPath(context, parser);
                        parseWebInfClasses(context, parser);
                        parseWebInfLib (context, parser);
                        parseHostClassPath(context, parser);
                    }                  
                }
    
                private void parseHostClassPath(final WebAppContext context, AnnotationParser parser) throws Exception
                {
                    clearAnnotationList(parser.getAnnotationHandlers());
                    Resource resource = getHostClassPathResource(getClass().getClassLoader());                  
                    if (resource == null)
                        return;
    
                    parser.parse(resource, new ClassNameResolver()
                    {
                        public boolean isExcluded (String name)
                        {           
                            if (context.isSystemClass(name)) return true;                           
                            if (context.isServerClass(name)) return false;
                            return false;
                        }
    
                        public boolean shouldOverride (String name)
                        {
                            //looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
                            if (context.isParentLoaderPriority())
                                return false;
                            return true;
                        }
                    });
    
                    //TODO - where to set the annotations discovered from WEB-INF/classes?    
                    List<DiscoveredAnnotation> annotations = new ArrayList<DiscoveredAnnotation>();
                    gatherAnnotations(annotations, parser.getAnnotationHandlers());                 
                    context.getMetaData().addDiscoveredAnnotations (annotations);
                }
    
                private Resource getHostClassPathResource(ClassLoader loader) throws IOException
                {
                    if (loader instanceof URLClassLoader)
                    {
                        URL[] urls = ((URLClassLoader)loader).getURLs();
                        for (URL url : urls)
                            if (url.getProtocol().startsWith("file"))
                                return Resource.newResource(url);
                    }
                    return null;                    
                }
            },
        });
    

    Update: Jetty 8.1.8 introduces internal changes that are incompatible with the code above. For 8.1.8 the following seems to work:

    webAppContext.setConfigurations (new Configuration []
        {
            // This is necessary because Jetty out-of-the-box does not scan
            // the classpath of your project in Eclipse, so it doesn't find
            // your WebAppInitializer.
            new AnnotationConfiguration() 
            {
                @Override
                public void configure(WebAppContext context) throws Exception {
                       boolean metadataComplete = context.getMetaData().isMetaDataComplete();
                       context.addDecorator(new AnnotationDecorator(context));   
    
    
                       //Even if metadata is complete, we still need to scan for ServletContainerInitializers - if there are any
                       AnnotationParser parser = null;
                       if (!metadataComplete)
                       {
                           //If metadata isn't complete, if this is a servlet 3 webapp or isConfigDiscovered is true, we need to search for annotations
                           if (context.getServletContext().getEffectiveMajorVersion() >= 3 || context.isConfigurationDiscovered())
                           {
                               _discoverableAnnotationHandlers.add(new WebServletAnnotationHandler(context));
                               _discoverableAnnotationHandlers.add(new WebFilterAnnotationHandler(context));
                               _discoverableAnnotationHandlers.add(new WebListenerAnnotationHandler(context));
                           }
                       }
    
                       //Regardless of metadata, if there are any ServletContainerInitializers with @HandlesTypes, then we need to scan all the
                       //classes so we can call their onStartup() methods correctly
                       createServletContainerInitializerAnnotationHandlers(context, getNonExcludedInitializers(context));
    
                       if (!_discoverableAnnotationHandlers.isEmpty() || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty())
                       {           
                           parser = createAnnotationParser();
    
                           parse(context, parser);
    
                           for (DiscoverableAnnotationHandler h:_discoverableAnnotationHandlers)
                               context.getMetaData().addDiscoveredAnnotations(((AbstractDiscoverableAnnotationHandler)h).getAnnotationList());      
                       }
    
                }
    
                private void parse(final WebAppContext context, AnnotationParser parser) throws Exception
                {                   
                    List<Resource> _resources = getResources(getClass().getClassLoader());
    
                    for (Resource _resource : _resources)
                    {
                        if (_resource == null)
                            return;
    
                        parser.clearHandlers();
                        for (DiscoverableAnnotationHandler h:_discoverableAnnotationHandlers)
                        {
                            if (h instanceof AbstractDiscoverableAnnotationHandler)
                                ((AbstractDiscoverableAnnotationHandler)h).setResource(null); //
                        }
                        parser.registerHandlers(_discoverableAnnotationHandlers);
                        parser.registerHandler(_classInheritanceHandler);
                        parser.registerHandlers(_containerInitializerAnnotationHandlers);
    
                        parser.parse(_resource, 
                                     new ClassNameResolver()
                        {
                            public boolean isExcluded (String name)
                            {
                                if (context.isSystemClass(name)) return true;
                                if (context.isServerClass(name)) return false;
                                return false;
                            }
    
                            public boolean shouldOverride (String name)
                            {
                                //looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
                                if (context.isParentLoaderPriority())
                                    return false;
                                return true;
                            }
                        });
                    }
                }
    
                private List<Resource> getResources(ClassLoader aLoader) throws IOException
                {
                    if (aLoader instanceof URLClassLoader)
                    {
                        List<Resource> _result = new ArrayList<Resource>();
                        URL[] _urls = ((URLClassLoader)aLoader).getURLs();                      
                        for (URL _url : _urls)
                            _result.add(Resource.newResource(_url));
    
                        return _result;
                    }
                    return Collections.emptyList();                 
                }
            }
        });
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Basically, what I'm trying to create is a page of div tags, each has
We are using XSLT to translate a RIXML file to XML. Our RIXML contains
I'm trying to create an if statement in PHP that prevents a single post
I'm making a simple page using Google Maps API 3. My first. One marker
I am trying to understand how to use SyndicationItem to display feed which is
I'm new to using the Perl treebuilder module for HTML parsing and can't figure
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.