0

There is my servlet in "java" directory:

@WebServlet("HelloWebServlet")
public class HelloWebServlet extends HttpServlet {

private HttpServletRequest request;
private String title = "Servlet test app";

public void doPost(HttpServletRequest req, HttpServletResponse resp) {

    doGet(req, resp);

} // end: doPost()

private void sendHead(HttpServletResponse resp) {

    try {

        PrintWriter writer = resp.getWriter();

        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html; charset=utf-8");

        writer.println("<HTML>");
        writer.println("<HEAD>");
        writer.println("<meta charset=\"UTF-8\">");
        writer.println("<TITLE>" + title + "</TITLE>");
        writer.println("</HEAD>");
        writer.println("<BODY>");

    } catch (Exception e) {

            throw new Error(e);

    }

} // END: sendHead()

private void sendFlooter(HttpServletResponse resp) {

    try {

        PrintWriter writer = resp.getWriter();
        writer.println("</BODY>");
        writer.println("</HTML>");

    } catch (Exception e) {
        throw new Error(e);
    }

} // END: sendHead()

public void doGet(HttpServletRequest req, HttpServletResponse resp) {

    this.request = req;

    try {

        sendHead(resp);

        PrintWriter writer = resp.getWriter();

        writer.println("<CENTER>");
        writer.println("<FORM>");
        writer.println("<H1>Input your request</H1>");
        writer.println("<INPUT TYPE=\"submit\" value=\"" + "Send" + "\" />");
        writer.println("</FORM>");
        writer.println("</CENTER>");

        sendFlooter(resp);

    } catch (Exception e) {

            throw new Error(e);

    }

} // END: doGet()

} //END: class HelloWebServlet

There is web.xml file:

<?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_4_0.xsd"
    version="4.0">

    <display-name>Servlet test app</display-name>

 <servlet-mapping>
     <servlet-name>HelloWebServlet</servlet-name>
     <url-pattern>/hello</url-pattern>
 </servlet-mapping>

</web-app>

And there the index.html file:

<html>
<head>
    <meta charset="UTF-8">
    <title>Request from servlet</title>
</head>
<body>

<form action="./hello" method="POST">
    <center>
        <h1>Send request</h1>
        <form>
            <input NAME="Request" TYPE="submit" VALUE="Request from servlet"/>
        </form>
    </center>
</form>

</center>
</body>
</html>

When my servlet class in "java" directory it works perfectly. But if I try to move it to the some package like add "package info.bhrigu.spring.test.servlets" at the first line in HelloWebApp:

package info.bhrigu.spring.test.servlets; // <------- now in the package!

@WebServlet("HelloWebServlet")
public class HelloWebServlet extends HttpServlet {
private static ArrayList<String> text;
...

And chagne web.xml to:

<?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_4_0.xsd" version="4.0">

<description>Servlet test app</description>
<display-name>Servlet test app</display-name>

<servlet>
    <servlet-name>HelloWebServlet</servlet-name>
    <servlet-class>info.bhrigu.spring.test.servlets.HelloWebServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>HelloWebServlet</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

</web-app>

Then I recive message from tomcat that the class is missing:

HTTP Status 500 – Internal Server Error

Type Exception Report

Message Error instantiating servlet class [info.bhrigu.spring.test.servlets.HelloWebServlet]

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

javax.servlet.ServletException: Error instantiating servlet class [info.bhrigu.spring.test.servlets.HelloWebServlet] org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)

Root Cause

java.lang.ClassNotFoundException: info.bhrigu.spring.test.servlets.HelloWebServlet

How to write a right configuration for the servlet placed in some package?

Yury Finchenko
  • 1,035
  • 13
  • 19
  • 1
    Did you place your java source file into java/info/bhrigu/spring/test/servlets directory and the compiled class file is in WEB-INF/classes/info/bhrigu/spring/test/servlets? – Selaron Oct 08 '19 at 14:48
  • How are you compiling this? Maven, for example, has a defined place to put your classes and HTML/JSP files to package it the correct way. Other build environments work similarly. – stdunbar Oct 08 '19 at 15:22
  • @Selaron Yes, problem was that I save my class file in the /classes folder without compete path. Thank you. – Yury Finchenko Oct 08 '19 at 15:29
  • @stdunbar I compile it by JAR plugin (like a regular jar) but create internal file structure by my own. It possible in maven. – Yury Finchenko Oct 08 '19 at 15:30

2 Answers2

1

I would recommend removing your web.xml file all together. Because you're using the newer annotations you don't need it.

To map to a particular URL, use an annotation like:

@WebServlet("/hello")
public class HelloWebServlet extends HttpServlet {

Secondly, you're not making a .jar file, you're making a .war file. Your pom.xml should reflect that:

<?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/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <artifactId>your-artifact-id</artifactId>
    <groupId>info.bhrigu</groupId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.2</version>
            </plugin>
         </plugins>
    </build>
</project>

The directory structure will be something like:

pom.xml
src/
    main/
        java/
            info/
                bhrigu/
                    spring/
                        test/
                            servlets/
                                HelloWebServlet.java
        webapp/
            index.html

If you really want to use the web.xml (sometimes it is still needed), your structure will be:

pom.xml
src/
    main/
        java/
            info/
                bhrigu/
                    spring/
                        test/
                            servlets/
                                HelloWebServlet.java
        webapp/
            WEB-INF/
                web.xml
            index.html
stdunbar
  • 16,263
  • 11
  • 31
  • 53
  • web plugin is unavailable in IntelliJ community version, isn't? – Yury Finchenko Oct 08 '19 at 15:47
  • I'm not sure about that I'm afraid. But the war plugin in the pom.xml is available normally - it's not part of IntelliJ. You can create a .war file and deploy it to any web container (Tomcat, Wildfly, Jetty, etc.). – stdunbar Oct 08 '19 at 16:45
0

Thank you to @Selaron. Right answer that path of classes in a .war file must contain original directories structure. If I use package like info.bhrigu.spring.test.servlets.HelloWebServlet then I must to save this strucure for /class directory in .war file and place it in \WEB-INF\classes\info\bhrigu\spring\test\servlets\HelloWebServlet.class folder and not in \WEB-INF\classes directly.

Yury Finchenko
  • 1,035
  • 13
  • 19