Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java+Maven+Embedded Tomcat: Project refuses to recognize web page

I have been trying to make my Java application host a web page (an HTML page, not JSP) through Apache Tomcat embedded in the application. I am using Maven for the build system on NetBeans IDE 8.0.2. For some reason, Tomcat refuses to recognise the index.html page I have placed in the application despite multiple attempts and creating all sorts of folders like WEB-INF. But it still throws a 404 error at me.

Here is some of the relevant code as I have set up in my project (some code has been omitted but irrelevant to the situation):

1. MainApplication.java - fires up Tomcat

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.io.*;
import java.util.Optional;
import org.apache.catalina.startup.Tomcat;

public class MainApplication{

    public static final Optional<String> port = Optional.ofNullable(System.getenv("PORT"));

    public static void main(String[] args) throws Exception {
        String contextPath = "/";
        String appBase = ".";
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(Integer.valueOf(port.orElse("8080")));
        tomcat.getHost().setAppBase(appBase);
        tomcat.addWebapp(contextPath, appBase);
        tomcat.start();
        tomcat.getServer().await();
    }
}

2. ShuttleServlet.java

@WebServlet(
            name = "ShuttleServlet", urlPatterns = {"/shuttle"}
    )

public class ShuttleServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Code to interact with application to be added later
    } 

3. Directory structure

- src
|
 - main
 |
  - resources
  - webapp
  |
    * index.html
    * scripts.js

4. Maven pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.example</groupId>
    <artifactId>TransportApp</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-logging-juli</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper-el</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jsp-api</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.5</version>
        </dependency>
    </dependencies>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <tomcat.version>7.0.57</tomcat.version>
    </properties>
    <build>
  <finalName>TransportApp</finalName>
  <resources>
      <resource>
          <directory>src/main/webapp</directory>
          <targetPath>META-INF/resources</targetPath>
      </resource>
  </resources>
  <plugins>
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.3.2</version>
          <inherited>true</inherited>
          <configuration>
              <source>1.8</source>
              <target>1.8</target>
          </configuration>          
      </plugin>      
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-assembly-plugin</artifactId>
          <configuration>
              <descriptorRefs>
                  <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <finalName>TransportApp-${project.version}</finalName>
              <archive>
                  <manifest>
                      <mainClass>com.example.TransportApp.MainApplication</mainClass>
                  </manifest>
              </archive>
          </configuration>
          <executions>
              <execution>
                  <phase>package</phase>
                  <goals>
                      <goal>single</goal>
                  </goals>
              </execution>
          </executions>
      </plugin>     
  </plugins>
</build>            
</project>

5. Tomcat console logs

Dec 04, 2016 3:09:24 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Dec 04, 2016 3:09:24 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Dec 04, 2016 3:09:24 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.57
Dec 04, 2016 3:09:24 AM org.apache.catalina.startup.ContextConfig getDefaultWebXmlFragment
INFO: No global web.xml found
Dec 04, 2016 3:09:25 AM org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [170] milliseconds.
Dec 04, 2016 3:09:25 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]

All of these result in a 404 that has been persistent despite multiple attempts and now-deleted folders. I hope all of this helps in finding the culprit.

like image 501
Mayukh Nair Avatar asked Oct 17 '22 21:10

Mayukh Nair


1 Answers

Root cause of the issue:

The issue is with your Launcher class. In the launcher class, below lines of code trying to look into the same directory for the web-app, which essentially is not correct.

 tomcat.addWebapp(contextPath, appBase);

Since appBase is set to ".", which means it will try to look into the same directory where your launcher class is.

Solution

Try to use below code, which is pretty straight forward to understand. You have to set the webApp path correctly to the tomcat context to recognize it when you hit that path at run-time.

    String webappDirLocation = "src/main/webapp/";
    Tomcat tomcat = new Tomcat();

    //The port that we should run on can be set into an environment variable
    //Look for that variable and default to 8080 if it isn't there.
    String webPort = System.getenv("PORT");
    if(webPort == null || webPort.isEmpty()) {
        webPort = "8080";
    }

    tomcat.setPort(Integer.valueOf(webPort));

    StandardContext ctx = (StandardContext) tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
    System.out.println("configuring app with basedir: " + new File("./" + webappDirLocation).getAbsolutePath());

    // Declare an alternative location for your "WEB-INF/classes" dir
    // Servlet 3.0 annotation will work
    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();
like image 163
Birendra Singh Bisht Avatar answered Oct 20 '22 11:10

Birendra Singh Bisht