HTTP status 404 for a servlet using Tomcat and IntelliJ. Yac678 asked on 2010-04-10. Editors IDEs; Apache Web Server; JSP; 8 Comments. Today I was running Apache Tomcat from Eclipse and while accessing URL found HTTP Status 404 – Not Found error.
Introduction
Oracle REST Data Services (ORDS) maps HTTP(S) verbs (GET, POST, PUT, DELETE, etc.) to database transactions and returns any results formatted using JSON.
If you want to use the web container (such as: Tomcat or Glassfish) as the listener for the Oracle Apex, you have to deploy the ORDS.war
application to it.
404 Not Found
has been a ccommon problem after we install the ORDS to a web container.
The article proposes a procedure the trouble shooting the 404 Not Found
problem.
The deployment for the Oracle Apex in our case is shown in the following:
Procedure
Step Check the Oracle DB listener.
Make sure the listener working properly.
Login to Oracle
user in the Oracle DB
Server. Use the following command to show the listener status:
Step Check the RESTFul Service of the Apex in the Oracle DB
You should have the following three accounts for the RESTFul Service in the Oracle DB:
- APEX_PUBLIC_USER
- APEX_LISTENER
- APEX_REST_PUBLIC_USER
Connect to the Oracle DB
and use the following SQL statement to check these users.
If you don’t have the three users, run the scrip @apex_rest_config.sql
in the Apex install directory.
Step Check ORDS configurations.
Make sure the DB user ORDS_PUBLIC_USER
exist in the Oracle DB.
If not, you have to reinstall the ORDS.
Login to the ORDS_NODE
server (where you install the ORDS service), run the following commands:
The installation process will use the sys
account to connect to the Oracle DB
server and then install the required schema (Oracle REST Data Services) and create the ORDS_PUBLIC_USER
user.
After completing the installation, we can validate it by running the command:
The logs of the installation and validation will be generated at /usr/share/ords/logs
.
Step Check the status of the accounts used by the ORDS to connects to Oracle DB.
Four accounts have been created:
- APEX_PUBLIC_USER
- APEX_LISTENER
- APEX_REST_PUBLIC_USER
- ORDS_PUBLIC_USER
Make sure the four accounts do not be locked and with expired passwords in the Oracle DB.
Login as sys
to the Oracle DB
, run the following statement to check:
Step Check the passwords of the previous accounts for the ORDS application.
ORDS application will use the four accounts to connect to Oracle DB. The passwords of the four accounts are stored at the configuration directory you have specified by the configdir
parameter for ords.war
. For example, run the following command in the ORDS_NODE
server:
specify the configuration directory at usr/share/ords/conf/ords/conf
.
In this configuration directory, you can see four xml files:
These xml files stores the names and passwords for the four accounts. Make sure the these accounts are consistent with those in the Oracle DB.
If the password is inconsistent, the Tomcat cannot create the connection pool for the account for connecting to Oracle DB.You can find the error message in the Tomcat log. See How to Update the ORDS_PUBLIC_USER Password | ThatJeffSmith for more details.
I have an HTML form in a JSP file in my WebContent/jsps
folder. I have a servlet class servlet.java
in my default package in src
folder. In my web.xml
it is mapped as /servlet
.
I have tried several URLs in action
attribute of the HTML form:
But none of those work. Video converter for mac aimersoft. They all keep returning a HTTP 404 error like below in Tomcat 6/7/8:
HTTP Status 404 — /servlet
Description: The requested resource (/servlet) is not available.
Or as below in Tomcat 8.5/9:
HTTP Status 404 — Not Found
Message: /servlet
Description: The origin server did not find a current representation for the target resource or is not willing to disclose that one exists
Why is it not working?
Put servlet class in a package
First of all, put the servlet class in a Java package
. You should always put publicly reuseable Java classes in a package, otherwise they are invisible to classes which are in a package, such as the server itself. This way you eliminiate potential environment-specific problems. Packageless servlets work only in specific Tomcat+JDK combinations and this should never be relied upon.
In case of a “plain” IDE project, the class needs to be placed in its package structure inside “Java Resources” folder and thus not “WebContent”, this is for web files such as JSP. Below is an example of the folder structure of a default Eclipse Dynamic Web Project as seen in Navigator view:
In case of a Maven project, the class needs to be placed in its package structure inside main/java
and thus not e.g. main/resources
, this is for non-class files. Below is an example of the folder structure of a default Maven webapp project as seen in Eclipse’s Navigator view:
Note that the /jsps
subfolder is not strictly necessary. You can even do without it and put the JSP file directly in webcontent/webapp root, but I’m just taking over this from your question.
Set servlet URL in url-pattern
The servlet URL is specified as the “URL pattern” of the servlet mapping. It’s absolutely not per definition the classname/filename of the servlet class. The URL pattern is to be specified as value of @WebServlet
annotation.
In case you want to support path parameters like /servlet/foo/bar
, then use an URL pattern of /servlet/*
instead. See also Servlet and path parameters like /xyz/{value}/test, how to map in web.xml?
@WebServlet
works only on Servlet 3.0 or newer
In order to use @WebServlet
, you only need to make sure that your web.xml
file, if any (it’s optional since Servlet 3.0), is declared conform Servlet 3.0+ version and thus not conform e.g. 2.5 version or lower. Below is a Servlet 3.1 compatible one (which matches Tomcat 8+, WildFly 8+, GlassFish 4+, etc).
Or, in case you’re not on Servlet 3.0+ yet (not Tomcat 7 or newer, but Tomcat 6 or older), then remove the @WebServlet
annotation.
And register the servlet instead in web.xml
like this:
Note thus that you should not use both ways. Use either annotation based configuarion or XML based configuration. When you have both, then XML based configuration will override annotation based configuration.
Verifying the build/deployment
In case you’re using a build tool such as Eclipse and/or Maven, then you need to make absolutely sure that the compiled servlet class file resides in its package structure in /WEB-INF/classes
folder of the produced WAR file. In case of package com.example; public class YourServlet
, it must be located in /WEB-INF/classes/com/example/YourServlet.class
. Otherwise you will face in case of @WebServlet
also a 404 error, or in case of <servlet>
a HTTP 500 error like below:
HTTP Status 500
Error instantiating servlet class com.example.YourServlet
And find in the server log a java.lang.ClassNotFoundException: com.example.YourServlet
, followed by a java.lang.NoClassDefFoundError: com.example.YourServlet
, in turn followed by javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet
.
Http 404 Apache Tomcat
An easy way to verify if the servlet is correctly compiled and placed in classpath is to let the build tool produce a WAR file (e.g. rightclick project, Export > WAR file in Eclipse) and then inspect its contents with a ZIP tool. If the servlet class is missing in /WEB-INF/classes
, then the project is badly configured or some IDE/project configuration defaults have been mistakenly reverted (e.g. Project > Build Automatically has been disabled in Eclipse). In case you have no clue, best is to restart from scratch and do not touch any IDE/project configuration defaults.
Testing the servlet individually
Provided that the server runs on localhost:8080
, and that the WAR is successfully deployed on a context path of /contextname
(which defaults to the IDE project name, case sensitive!), and the servlet hasn’t failed its initialization (read server logs for any deploy/servlet success/fail messages and the actual context path and servlet mapping), then a servlet with URL pattern of /servlet
is available at http://localhost:8080/contextname/servlet
.
You can just enter it straight in browser’s address bar to test it invidivually. If its doGet()
is properly overriden and implemented, then you will see its output in browser. Or if you don’t have any doGet()
or if it incorrectly calls super.doGet()
, then a “HTTP 405: HTTP method GET is not supported by this URL” error will be shown (which is still better than a 404 as a 405 is evidence that the servlet itself is actually found).
Overriding service()
is a bad practice, unless you’re reinventing a MVC framework — which is very unlikely if you’re just starting out with servlets and are clueless as to the problem described in the current question 😉 See also Design Patterns web based applications.
Regardless, if the servlet already returns 404 when tested invidivually, then it’s entirely pointless to try with a HTML form instead. Logically, it’s therefore also entirely pointless to include any HTML form in questions about 404 errors from a servlet.
Referencing the servlet URL from HTML
Once you’ve verified that the servlet works fine when invoked individually, then you can advance to HTML. As to your concrete problem with the HTML form, the <form action>
value needs to be a valid URL. The same applies to <a href>
. You need to understand how absolute/relative URLs work. You know, an URL is a web address as you can enter/see in the webbrowser’s address bar. If you’re specifying a relative URL as form action, i.e. without the http://
scheme, then it becomes relative to the current URL as you see in your webbrowser’s address bar. It’s thus absolutely not relative to the JSP/HTML file location in server’s WAR folder structure as many starters seem to think.
Http 404 Tomcat Eclipse
So, assuming that the JSP page with the HTML form is opened by http://localhost:8080/contextname/jsps/page.jsp
, and you need to submit to a servlet located in http://localhost:8080/contextname/servlet
, here are several cases (note that you can safely substitute <form action>
with <a href>
here):
Form action submits to an URL with a leading slash.
The leading slash
/
makes the URL relative to the domain, thus the form will submit toBut this will likely result in a 404 as it’s in the wrong context.
Form action submits to an URL without a leading slash.
This makes the URL relative to the current folder of the current URL, thus the form will submit to
But this will likely result in a 404 as it’s in the wrong folder.
Form action submits to an URL which goes one folder up.
This will go one folder up (exactly like as in local disk file system paths!), thus the form will submit to
This one must work!
The canonical approach, however, is to make the URL domain-relative so that you don’t need to fix the URLs once again when you happen to move the JSP files around into another folder.
This will generate
Which will thus always submit to the right URL.
Http Status 404 Tomcat Linux
Use straight quotes in HTML
You need to make absolutely sure you’re using straight quotes in HTML attributes like action='..'
or action='..'
and thus not curly quotes like action=”..”
or action=’..’
. Curly quotes are not supported in HTML and they will simply become part of the value.
See also:
- Our servlets wiki page – Contains some hello world examples
Http 404 Tomcat Free
Other cases of HTTP Status 404 error:
Tags: http