Search code examples
javamavenjakarta-eepackaging

export Java EE Web Application as JAR


This might be a weird question but I am curious about this:

I want to create a Java EE Web Project, that I can package into a JAR file (<packaging>jar</packaging> instead of <packaging>war</packaging>).

In other words, I want to include the Java EE web server inside a JAR (built by maven).

Inside the WebServer I want to use Servlets like I can use them when I package it to a WAR file but without requireing the devices that execute the JAR to have a Web server installed where they can deploy my JAR.

I want something like an executeable JAR that contains the server and runs it without the need to install something else.

Is there a (ideally light-weight) server that works within a JAR file or any other possibility to create a JAR file like this?


Solution

  • If you want to use vanilla Java EE, you can use an Embedded Jetty Server or Embedded Tomcat Server:

    Here is an example with Embedded Tomcat and 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>org.company</groupId>
        <artifactId>app</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    
        <packaging>jar</packaging>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>12</maven.compiler.source>
            <maven.compiler.target>12</maven.compiler.target>
    
            <servlet.version>3.1.0</servlet.version>
            <jsf.version>2.2.19</jsf.version>
            <tomcat.version>9.0.21</tomcat.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>com.sun.faces</groupId>
                <artifactId>jsf-api</artifactId>
                <version>${jsf.version}</version>
            </dependency>
            <dependency>
                <groupId>com.sun.faces</groupId>
                <artifactId>jsf-impl</artifactId>
                <version>${jsf.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-core</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.embed</groupId>
               <artifactId>tomcat-embed-el</artifactId>
               <version>${tomcat.version}</version>
          </dependency>
    
      </dependencies>
    
        <build>
            <finalName>app</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>3.8.1</version>
                    <configuration>
                        <source>12</source>
                        <target>12</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <finalName>app-${project.version}</finalName>
                        <archive>
                            <manifest>
                                <mainClass>org.company.app.Application</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>
    

    mainClass:

    package org.company.app;
    
    
    
    
    import org.apache.catalina.WebResourceRoot;
    import org.apache.catalina.core.StandardContext;
    import org.apache.catalina.startup.Tomcat;
    import org.apache.catalina.webresources.DirResourceSet;
    import org.apache.catalina.webresources.StandardRoot;
    
    import java.io.File;
    
    public class Application {
        public static void main(final String[] args) throws Exception {
    
            final String webappPath = new File("src/main/webapp").getAbsolutePath();
            final Tomcat tomcat = new Tomcat();
    
            final StandardContext ctx = (StandardContext) tomcat.addWebapp("/", webappPath);
            System.out.println(ctx
            );
            // Declare an alternative location for your "WEB-INF/classes" dir
            // Servlet 3.0 annotation will work
            final String targetClassesPath = new File("target/classes").getAbsolutePath();
            final WebResourceRoot resources = new StandardRoot(ctx);
            resources.addPreResources(new DirResourceSet(//
                    resources, "/WEB-INF/classes", //
                    targetClassesPath, "/"));
            ctx.setResources(resources);
    
            tomcat.start();
            tomcat.getServer().await();
        }
    }
    
    

    and the rest as usual java ee development