//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

= Using Maven

http://maven.apache.org/[Apache Maven] is a software project management and comprehension tool.
Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.

It is an ideal tool to build a web application project, and such projects can use the xref:maven-jetty/jetty-maven-plugin.adoc[jetty-maven-plugin] to easily run the web application and save time in development.
You can also use Maven to build, test and run a project which embeds Jetty.

[NOTE]
====
Use of Maven and the jetty-maven-plugin is *not* required.
Using Maven for Jetty implementations is a popular choice, but users encouraged to manage their projects in whatever way suits their needs.
Other popular tools include Ant and Gradle.
====

[[configuring-embedded-jetty-with-maven]]
== Using Embedded Jetty with Maven

Maven uses convention over configuration, so it is best to use the project structure Maven recommends.
You can use _http://maven.apache.org/guides/introduction/introduction-to-archetypes.html[archetypes]_ to quickly setup Maven projects, but we will set up the structure manually for this simple tutorial example:

----
> mkdir JettyMavenHelloWorld
> cd JettyMavenHelloWorld
> mkdir -p src/main/java/org/example
----

[[creating-helloworld-class]]
=== Creating the HelloWorld Class

Use an editor to create the file `src/main/java/org/example/HelloWorld.java` with the following contents:

[,java]
----
package org.example;

import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;

class HelloWorldHandler extends Handler.Abstract.NonBlocking
{
    @Override
    public boolean handle(Request request, Response response, Callback callback)
    {
        response.setStatus(200);
        response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/html; charset=UTF-8");

        // Write a Hello World response.
        Content.Sink.write(response, true, """
            <!DOCTYPE html>
            <html>
            <head>
              <title>Jetty Hello World Handler</title>
            </head>
            <body>
              <p>Hello World</p>
            </body>
            </html>
            """, callback);
        return true;
    }
}

Server server = new Server();
Connector connector = new ServerConnector(server);
server.addConnector(connector);

// Set the Hello World Handler.
server.setHandler(new HelloWorldHandler());

server.start();
}
----

[[creating-embedded-pom-descriptor]]
=== Creating the POM Descriptor

The `pom.xml` file declares the project name and its dependencies.
Use an editor to create the file `pom.xml` in the `JettyMavenHelloWorld` directory with the following contents:

[,xml,subs=attributes+]
----
<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>
  <groupId>org.example</groupId>
  <artifactId>hello-world</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>Jetty HelloWorld</name>

  <properties>
    <jettyVersion>{jetty-version}</jettyVersion>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-server</artifactId>
      <version>$\{jettyVersion}</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <executions>
          <execution><goals><goal>java</goal></goals></execution>
        </executions>
        <configuration>
          <mainClass>org.example.HelloWorld</mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
----

[[buildng-and-running-embedded-helloworld]]
=== Building and Running Embedded HelloWorld

You can now compile and execute the HelloWorld class by using these commands:

----
> mvn clean compile exec:java
----

Point your browser to `+http://localhost:8080+` to see the _Hello World_ page.

[[developing-standard-webapp-with-jetty-and-maven]]
== Developing a Standard WebApp with Jetty and Maven

The previous section demonstrated how to use Maven with an application that embeds Jetty.
We can instead develop a standard webapp using Maven and Jetty.
First create the Maven structure (you can use the maven webapp archetype instead if you prefer):

----
> mkdir JettyMavenHelloWarApp
> cd JettyMavenHelloWebApp
> mkdir -p src/main/java/org/example
> mkdir -p src/main/webapp/WEB-INF
----

[[creating-servlet]]
=== Creating a Servlet

Use an editor to create the file `src/main/java/org/example/HelloServlet.java` with the following contents:

[,java]
----
package org.example;

import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        response.setContentType("text/html");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().println("<h1>Hello Servlet</h1>");
        response.getWriter().println("session=" + request.getSession(true).getId());
    }
}
----

This servlet must be declared in the web deployment descriptor, so create the file `src/main/webapp/WEB-INF/web.xml` and add the following contents:

[,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<web-app
   xmlns="https://jakarta.ee/xml/ns/jakartaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
   metadata-complete="false"
   version="6.0">

  <servlet>
    <servlet-name>Hello</servlet-name>
    <servlet-class>org.example.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Hello</servlet-name>
    <url-pattern>/hello/*</url-pattern>
  </servlet-mapping>

</web-app>
----

[[creating-plugin-pom-descriptor]]
=== Creating the POM Descriptor

The `pom.xml` file declares the project name and its dependencies.
Use an editor to create the file `pom.xml` with the following contents in the `JettyMavenHelloWarApp` directory, noting particularly the declaration of the xref:maven-jetty/jetty-maven-plugin.adoc[jetty-maven-plugin] for the Jakarta {ee-current-caps} environment:

[,xml,subs=attributes+]
----
<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>
  <groupId>org.example</groupId>
  <artifactId>hello-world</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>Jetty HelloWorld WebApp</name>

  <properties>
    <jettyVersion>{jetty-version}</jettyVersion>
  </properties>

  <dependencies>
    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>6.0.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.eclipse.jetty.ee10</groupId>
        <artifactId>jetty-ee10-maven-plugin</artifactId>
        <version>$\{jettyVersion}</version>
      </plugin>
    </plugins>
  </build>

</project>
----

[[building-and-running-web-application]]
=== Building and Running the Web Application

The web application can now be built and run without first needing to assemble it into a war by using the xref:maven-jetty/jetty-maven-plugin.adoc[jetty-maven-plugin] via the command:

----
> mvn jetty:run
----

You can see the static and dynamic content at `+http://localhost:8080/hello+`

There are a great deal of configuration options available for the jetty-maven-plugin to help you build and run your webapp.
The full reference is at xref:maven-jetty/jetty-maven-plugin.adoc[Configuring the Jetty Maven Plugin].

[[building-war-file]]
=== Building a WAR file

A Web Application Archive (WAR) file can be produced from the project with the command:

----
> mvn package
----

The resulting war file is in the `target` directory and may be deployed on any standard servlet server, including xref:operations-guide:deploy/index.adoc[Jetty].
