How to ensure that a Servlet is Deployed on Tomcat 7 using Servlet Container 3.0?

3

I'm developing an application that uses the Servlet 3.0 API via Notes and porting does not need WEB-INF / web.xml file

The problem that sometimes when I do Deploy in Tomcat 7 the Servlet is not available and I get a 404 error. There is no error message in the LOG.

In summary, I'd like to force Tomcat to see my Servlet, preferably programmatically so I do not need to edit JEE XML descriptors.

NOTE: The Servlet was available and apparently unmodified it started to acknowledge error 404 when I made a new Application Deploy.

I am declaring the Servlet with Note @WebServlet where I use only the attributes name and urlPatterns

Is this the right approach? Missing some annotation? Do I need to use Interface javax.servlet.ServletRegistration ?

    
asked by anonymous 21.03.2014 / 20:26

1 answer

2

If you use Tomcat Embedded you can force Tomcat to view your Servlet programmatically and not need to edit JEE XML descriptors.

Here is an example below where you do not need to use the @WebServlet annotation:

Main method

// Para tratar o CTRL-C
final Tomcat tomcat = new Tomcat();
Runtime.getRuntime().addShutdownHook(new Thread() {
    @Override
    public void run() {
        try {
            tomcat.stop();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
    }
});

// inicio
tomcat.setPort(Integer.valueOf(args[0]));
Log containerLogger = context.getLogger();

try {
    Context context = tomcat.addWebapp("/",
            new File(".").getAbsolutePath());

    containerLogger.info("*** INICIANDO ***");

    containerLogger.info("*** iniciando o Tomcat com o servlet "
            + MyDynServlet.class.getSimpleName());

    tomcat.start();

    String myDynServletName = MyDynServlet.class.getSimpleName()
            .toLowerCase();
    Wrapper myDynServlet = context.createWrapper();
    myDynServlet.setName(myDynServletName);
    myDynServlet.setServletClass(MyDynServlet.class.getCanonicalName());
    myDynServlet.addInitParameter("debug", "0");
    myDynServlet.addInitParameter("listings", "false");
    myDynServlet.setLoadOnStartup(1);
    context.addChild(myDynServlet);
    // O mapping do Servlet pode vir de qualquer fonte. 
    // Abaixo está hard-coded
    context.addServletMapping("/mydynservlet", myDynServletName);
    // Para ajudar na resolução de problemas listo os mappings
    String[] servletMappings = context.findServletMappings();
    for (String mapping : servletMappings) {
        containerLogger.info("*** ServletMapping " + mapping);
    }
} catch (ServletException | LifecycleException e) {
    e.printStackTrace();
}

int CINCO_SEGUNDOS = 5 * 1000;
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
    public void run() {
        // Wait until a proper shutdown command is received, then
        // cancel timer thread.
        containerLogger.info("***  AWAIT Server");

        tomcat.getServer().await();

        containerLogger.info("***  Server Shutdown Complete ***");
        containerLogger.info("***  Cancelando Timer Thread  ***");
        timer.cancel();
    }
}, CINCO_SEGUNDOS);

// Você pode desejar fazer algo depois de carregar o Tomcat em outra Thread.

Note that a Timer Task was created only to not block the current Thread. This is optional.

Maven dependencies:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <tomcat-embed.version>7.0.52</tomcat-embed.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-core</artifactId>
        <version>${tomcat-embed.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-api</artifactId>
        <version>${tomcat-embed.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-logging-juli</artifactId>
        <version>${tomcat-embed.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <version>${tomcat-embed.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat7-websocket</artifactId>
        <version>${tomcat-embed.version}</version>
    </dependency>
</dependencies>

Dependency with Websocket is optional.

    
22.03.2014 / 12:47