1
votes

Providing every step I took with this short video: https://youtu.be/hbSr8sRYuOk

Project code here: https://github.com/LJonn/restapiHelloWorld

Running everything on a local server on tomcat.

I'm having this issue for quite some time and ran out of ideas where the problem might be... I tried URL's such as these: "http://localhost:8080/api/hello" and "http://localhost:8080/helloworld/api/hello" and expected one of these to work.

Running http://localhost:8080/manager/text/list shows that helloworld.war is deployed fine and working:
OK - Listed applications for virtual host [localhost]
/:running:0:ROOT
/helloworld:running:0:helloworld
/examples:running:0:examples
/host-manager:running:0:host-manager
/manager:running:0:manager
/docs:running:0:docs

So why I still get a HTTP Status 404 page? What could I try to do to find the issue?

These are my project's Maven dependencies:

  <dependencies>
    <dependency>
        <groupId>jakarta.platform</groupId>
        <artifactId>jakarta.jakartaee-web-api</artifactId>
        <version>9.1.0</version>
        <scope>provided</scope>
    </dependency>
  </dependencies>

Thanks to Nikos Paraskevopoulos comment it looks like changing from Tomcat to TomEE might fix the issue, but now I'm running into a problem where the .war file can't be deployed/started, probably some sort of versions compatibility issue, tomcat manager GUI gives this error when trying to start the .war file:

FAIL - Application at context path [/helloworld] could not be started
FAIL - Encountered exception [org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/helloworld]]]

Looking to manager logs It looks like it has something to do with annotations and Java 16 maybe?:

...
Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 60
        at org.apache.xbean.asm7.ClassReader.<init>(ClassReader.java:195)
        at org.apache.xbean.asm7.ClassReader.<init>(ClassReader.java:176)
        at org.apache.xbean.asm7.ClassReader.<init>(ClassReader.java:162)
        at org.apache.xbean.asm7.ClassReader.<init>(ClassReader.java:283)
        at org.apache.xbean.finder.AnnotationFinder.readClassDef(AnnotationFinder.java:1176)
        ... 52 more
01-Sep-2021 15:25:02.185 INFO [http-nio-8080-exec-3] org.apache.catalina.core.ApplicationContext.log HTMLManager: list: Listing contexts for virtual host 'localhost'

I've tried to check JRE version on Eclipse and it's 16.0.2 and it looks to me that the same version is running on tomcat.

1
Just a guess… Try using 127.0.0.1 instead of localhost to avoid name resolution. Ex: http://127.0.0.1:8080/helloworld etc.Basil Bourque
both 127.0.0.1 and localhost works the same for me. Seems like tomcat is working properly and I can access its GUI if I run it via startup.bin, but ".../api/hello" URL doesn't return a string which I expect it to do..LuckyTriple Smile
There are two issues I can think of: (1) you are using the jakarta APIs, are you sure you are using a version of Tomcat that supports it over javax? Please double check!!! (2) Is Tomcat supposed to pick up the JAX-RS application without an entry to the web.xml? Can you try again with an appropriate <servlet> and <servlet-mapping> for JAX-RS in the web.xml?Nikos Paraskevopoulos

1 Answers

2
votes

Tomcat 10.0 and 10.1 are not full Jakarta EE 9.1 application servers: you shouldn't use the jakarta.jakartaee-web-api artifact, which would imply that the runtime supports all Jakarta EE 9.1 Web Profile technologies.

Tomcat does not implement all the specs required in Web Profile. At least four other products do. See this list for Jakarta Web Profile 9.1:

  • Apache TomEE
  • Eclipse Glassfish
  • IBM Open Liberty
  • Red Hat WildFly

You can find the list of supported technologies on Tomcat's web site and for Tomcat 10 they translate to this list shown as a Maven POM snippet.

    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>5.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jakarta.servlet.jsp</groupId>
      <artifactId>jakarta.servlet.jsp-api</artifactId>
      <version>3.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jakarta.el</groupId>
      <artifactId>jakarta.el-api</artifactId>
      <version>4.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jakarta.websocket</groupId>
      <artifactId>jakarta.websocket-api</artifactId>
      <version>2.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jakarta.security.auth.message</groupId>
      <artifactId>jakarta.security.auth.message-api</artifactId>
      <version>2.0.0-RC1</version>
      <scope>provided</scope>
    </dependency>

Since Servlet 3.0, additional Jakarta EE specifications can be added using the servlet pluggability mechanism. To use JAX-RS you need to add:

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>3.0.2</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.inject</groupId>
    <artifactId>jersey-hk2</artifactId>
    <version>3.0.2</version>
</dependency>

or an equivalent configuration using other JAX-RS implementations.