Java – ServletException: No servlet class has been specified

javaservletstomcat

I have what should be an extremely simple "Hello World" servlet, but I cannot get it to work. I am using Eclipse, Tomcat 8, Java 7, and Servlet 3.1.

I have looked at many tutorials and questions, but they have not completely helped. Most tutorials I have seen talk about creating servlets by extending HttpServlet. I got those to work. Now I'd like to try the cleaner annotation approach.

I've been referring to this tutorial, but it isn't quite complete and seems to have some incorrect or incomplete examples:
Packaging and Deploying RESTful Web Services

Why is com.testing.service.MyApplication not being loaded?

Any help on getting this thing to run would be immensely appreciated!

Here are my files:

MyApplication.java

package com.testing.service;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("app")
public class MyApplication extends Application {
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(HelloWorldResource.class);
        return s;
    }
}

HelloWorldResource.java

package com.testing.service;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/helloworld")
public class HelloWorldResource {
    @SuppressWarnings("unused")
    private static final long serialVersionUID = 1L;

    @GET
    @Produces("text/plain")
    public String sayHello() {
        return "Hello World!";
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
  <display-name>service</display-name>
  <servlet>
    <servlet-name>com.testing.service.MyApplication</servlet-name>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.testing.service.MyApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

</web-app>

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.testing</groupId>
  <artifactId>service</artifactId>
  <version>1.0</version>
  <packaging>war</packaging>
  <name>Rest Test</name>
  <dependencies>
    <dependency>
      <groupId>javax.ws.rs</groupId>
      <artifactId>javax.ws.rs-api</artifactId>
      <version>2.0.1</version>
    </dependency>
  </dependencies>  
  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.1</version>
          <configuration>
            <source>1.7</source>
            <target>1.7</target>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Whenever I run Tomcat, it displays the following error:

INFO: Marking servlet com.testing.service.MyApplication as unavailable
Feb 05, 2015 3:28:55 PM org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet /service threw load() exception
javax.servlet.ServletException: No servlet class has been specified for servlet com.testing.service.MyApplication
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1099)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1041)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4944)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5230)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

Best Solution

I found the answer in the comments of a related question. The answer was provided by Alvin Thompson. Unfortunately, I don't have enough reputation to up-vote your answer.

If you're using a standard Tomcat install (or some other servlet container), you need to include a REST implementation since Tomcat doesn't come with one. If you're using Maven, add this to the dependencies section:

<dependencies>
  <dependency>
    <groupId>org.glassfish.jersey.bundles</groupId>
    <artifactId>jaxrs-ri</artifactId>
    <version>2.13</version>
  </dependency>
  ...
</dependencies>

Then just add an application config class to your project. If you don't have any special configuration needs aside from setting the context path for the rest services, the class can be empty. Once this class is added, you don't need to configure anything in web.xml (or have one at all).

Originally posted here:

How to set up JAX-RS Application using annotations only (no web.xml)?