1

I am trying to setup Angular 7 with a maven based back-end java project into a single war file. At the moment I am trying to configure the web.xml file where I am currently having this problem. I am not sure at all if my approach is valid or 'good' therefore I will first describe what I am trying to do (if you think better on this aspect please do correct me).
So I have a couple of JAX-RS classes which I'd like to serve as a REST API. For this purpose I have created corresponding javax.ws.rs.core.Application classes to provide these REST components. Then I am including the Application classes in the web.xml file. Below are the files:

web.xml

 <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

  <servlet>
    <servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
    <servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
    <url-pattern>/rmz/*</url-pattern>
  </servlet-mapping>

Another variation of web.xml that I tried

 <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

  <servlet>
    <servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
    <servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>backend.backendservice.StammSolvaraJahrRestApplication</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
    <url-pattern>/rmz/*</url-pattern>
  </servlet-mapping>

Application class

public class StammSolvaraJahrRestApplication extends Application {

  @Override
  public Set<Class<?>> getClasses() {
    Set<Class<?>> sets = new HashSet<>();
    sets.add(StammSolvaraJahrRest.class);
    return sets;
  }

}

The error that I get is: java.lang.ClassCastException: backend.backendservice.StammSolvaraJahrRestApplication cannot be cast to javax.servlet.Servlet and if I remove the <servlet-class> then I'll get No servlet class has been specified for servlet. I am following https://docs.oracle.com/cd/E24329_01/web.1211/e24983/configure.htm#RESTF183 and How to deploy a JAX-RS application? among others but it seems not to be working.

Bendemann
  • 735
  • 11
  • 31

2 Answers2

1

The problem is just what it says. This line in your web.xml requires a javax.servlet.Servlet:

<servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>

Since an Application is not a javax.servlet.Servlet, you're getting the error at runtime when your XML file is processed.

If you can, I would suggest that you start with a Spring Boot starter application. Spring Boot handles all of this for you. It can even embed a Tomcat server inside a jar file so that you can run your server like a simple Java application. Doing this would save you having to worry about what you're dealing with here.

CryptoFool
  • 21,719
  • 5
  • 26
  • 44
  • I can't work with Spring unfortunately. So then how am I supposed to configure this? I was following among others ´https://stackoverflow.com/questions/2072295/how-to-deploy-a-jax-rs-application´ and ´https://docs.oracle.com/cd/E24329_01/web.1211/e24983/configure.htm#RESTF183´ – Bendemann Jul 11 '19 at 15:30
  • Is it possible that you're using the wrong definition of `Application`? Maybe there is a `Application` class that is a `Servlet`, but you're using something else? - I don't remember the details of building up a war-based application in this way. Spring Boot let me throw away all of my code in this area. – CryptoFool Jul 11 '19 at 15:33
  • Nope its whats supposed to be: `javax.ws.rs.core.Application` – Bendemann Jul 11 '19 at 15:34
  • 1
    I just googled javax.ws.rs.core.Application. That's just an Object, right? So it isn't a Servlet, and so you can't use it like one. – CryptoFool Jul 11 '19 at 15:36
  • 1
    I just looked at your second link. I did so very quickly, but if you look, I don't think you are doing the same thing as what is shown there. I don't see a case where the `` tag is set to an instance of `Application`. The `` tag is, but not ``. – CryptoFool Jul 11 '19 at 15:41
  • It looks like the `` tag has to refer to a `ServletContainer` class specific to whatever Servlet container. See the docs for the `` tag in that documentation. – CryptoFool Jul 11 '19 at 15:47
  • Looks like @EmanuelRamirez. Might have an answer for you. I only gave you a diagnosis of the problem :) – CryptoFool Jul 11 '19 at 15:48
  • Yeah. Thanks for taking the time to look into this :) – Bendemann Jul 12 '19 at 11:04
1

There are two ways to define your JAX-RS servlet.

1) With Application Subclass like the one you have, you can skip the web.xml config and just add the application annotation

@ApplicationPath("resources")
public class StammSolvaraJahrRestApplication extends Application

2) With web.xml config

<servlet>
    <display-name>JAX-RS Servlet</display-name>
    <servlet-name>package.hierarchy.StammSolvaraJahrRestApplication</servlet-name>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>package.hierarchy.StammSolvaraJahrRestApplication</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>JaxRSServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

If you skip the servlet mapping from the last one, it will use your your @ApplicationPath specified value, or "/resources" if the previous one is missing.

Emanuel Ramirez
  • 392
  • 2
  • 8
  • I wana go for the `web.xml` config but what I don't understand is why `servlet-name` at `servlet-mapping` and `servlet` have different values? Indeed, if I try your example, I'll get a `Servlet mapping specifies an unknown servlet name [JaxRSServlet]` error. If the naming is consistent then I'll get a `500 No servlet class has been specified for servlet`, which is indicating that I need a `servlet-class`. – Bendemann Jul 12 '19 at 11:03