Embedded tomcat 7 servlet 3.0 annotations not working

后端 未结 4 679
孤独总比滥情好
孤独总比滥情好 2020-12-01 03:19

I have a stripped down test project which contains a Servlet version 3.0, declared with annotations like so:

    @WebServlet(\"/test\")
public class TestServ         


        
相关标签:
4条回答
  • 2020-12-01 03:27

    Well I finally solved it by looking in the Tomcat7 sources, namely in the unit tests that deal with EmbeddedTomcat and servlet 3.0 annotations.

    Basically, you must start your Embedded Tomcat 7 like this to make it aware of your annotated classes:

    String webappDirLocation = "src/main/webapp/";
    Tomcat tomcat = new Tomcat();
    tomcat.setPort(8080);
    
    StandardContext ctx = (StandardContext) tomcat.addWebapp("/embeddedTomcat",
                    new File(webappDirLocation).getAbsolutePath());
    
    //declare an alternate location for your "WEB-INF/classes" dir:     
    File additionWebInfClasses = new File("target/classes");
    VirtualDirContext resources = new VirtualDirContext();
    resources.setExtraResourcePaths("/WEB-INF/classes=" + additionWebInfClasses);
    ctx.setResources(resources);
    
    tomcat.start();
    tomcat.getServer().await();
    

    For the sake of clarity I should mention that this works for a standard Maven project where your "web resources" (such as static and dynamic pages, WEB-INF directory etc) are found in:

    [your project's root dir]/src/main/webapp

    and your classes get compiled into

    [your project's root dir]/target/classes

    (such that you'd have [your project's root dir]/target/classes/[some package]/SomeCompiledServletClass.class)

    For other directories layouts, these locations need to be changed accordingly.

    ==== UPDATE: Embedded Tomcat 8 ====

    Thanks to @kwak for noticing this.

    The APIs have changed a bit, here how the above example changes when using Embedded Tomcat 8:

    String webappDirLocation = "src/main/webapp/";
    Tomcat tomcat = new Tomcat();
    tomcat.setPort(8080);
    
    StandardContext ctx = (StandardContext) tomcat.addWebapp("/embeddedTomcat",
                    new File(webappDirLocation).getAbsolutePath());
    
    //declare an alternate location for your "WEB-INF/classes" dir:     
    File additionWebInfClasses = new File("target/classes");
    WebResourceRoot resources = new StandardRoot(ctx);
    resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClasses.getAbsolutePath(), "/"));
    ctx.setResources(resources);
    
    tomcat.start();
    tomcat.getServer().await();
    
    0 讨论(0)
  • 2020-12-01 03:32
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(port);
    
        Context ctx = tomcat.addWebapp("/", new File(docBase).getAbsolutePath());
        StandardJarScanner scan = (StandardJarScanner) ctx.getJarScanner();
        scan.setScanClassPath(true);
        scan.setScanBootstrapClassPath(true); // just guessing here
        scan.setScanAllDirectories(true);
        scan.setScanAllFiles(true);
    
        tomcat.start();
        tomcat.getServer().await();
    

    it works well for me using Tomcat Embed 7.0.90 from MVN

    0 讨论(0)
  • 2020-12-01 03:34

    Given the JNDI magic in the snippet you posted:

    try {
        listBindings = context.getResources().listBindings(
                "/WEB-INF/classes");
    } catch (NameNotFoundException ignore) {
        // Safe to ignore
    }
    

    could you maybe set up the same sort of entries in JNDI yourself?

    Context ctx = tomcat.addWebapp(...);
    FileDirContext fdc = new FileDirContext();
    fdc.setDocBase(new File("/path/to/my/classes").getAbsolutePath());
    ctx.getResources().createSubcontext("/WEB-INF/classes").bind("myclasses", fdc);
    
    0 讨论(0)
  • 2020-12-01 03:51

    I think in 8.5 and later it's just one liner:

    Context.setAddWebinfClassesResources(true);

    Sets the flag that indicates if /WEB-INF/classes should be treated like an exploded JAR and JAR resources made available as if they were in a JAR.

    http://tomcat.apache.org/tomcat-8.5-doc/api/org/apache/catalina/core/StandardContext.html#setAddWebinfClassesResources(boolean)

    0 讨论(0)
提交回复
热议问题