Java Run Class Within WAR In CLI
When deploying a Java web application, the code is packaged into a WAR (Web Application Archive) file and typically deployed in a servlet container like Tomcat, Jetty, or WildFly. However, there may be situations where you need to run a standalone Java class within a WAR file from the command line. This article explores different approaches to achieving this.
1. Sample Application
Let’s create a simple Java web application with a standalone class we want to execute from the command line.
Project Structure
Main Class (MainClass.java
)
This is the Java class we want to execute within the WAR file.
1 2 3 4 5 6 | public class MainClass { public static void main(String[] args) { System.out.println( "Hello from inside the WAR file!" ); } } |
This is a simple Java class with a main
method that prints a message to the console.
1.1 Building the WAR File
We will use a build tool like Apache Maven to build the WAR file. Here’s the pom.xml
file for the project. Run the following command to build the WAR file.
1 | mvn clean package |
This generates sample-war-app/target/sample-war-app.war
.
2. Running the Class from the WAR File
Let’s explore various methods to run a class from a WAR file using the command line.
2.1 Using java -cp
To run a Class Inside the WAR
By default, Java does not recognize a WAR file as an executable JAR because it follows a different directory structure. The compiled class files are placed inside WEB-INF/classes/
, and dependencies are stored in WEB-INF/lib/
. Since the java -jar
command does not automatically load classes from these locations, we must explicitly specify the classpath using -cp
.
To ensure Java can find and execute the class inside the WAR file, update the pom.xml
file to include the Main-Class and correctly reference the classpath.
Update pom.xml
to Specify Entry Point and Classpath
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | < build > < plugins > < plugin > < groupId >org.apache.maven.plugins</ groupId > < artifactId >maven-war-plugin</ artifactId > < version >3.3.2</ version > < configuration > < archive > < manifest > < mainClass >com.jcg.MainClass</ mainClass > < addClasspath >true</ addClasspath > < classpathPrefix >WEB-INF/classes/</ classpathPrefix > </ manifest > </ archive > </ configuration > </ plugin > </ plugins > </ build > |
This configuration ensures that when the WAR file is built:
- The
Main-Class
entry is added to theMANIFEST.MF
file, allowing Java to recognize which class should be executed. - The
addClasspath
option ensures that all required classes and dependencies insideWEB-INF/classes/
andWEB-INF/lib/
are referenced in the manifest. - The
classpathPrefix
option specifies that Java should look for compiled classes insideWEB-INF/classes/
, ensuring thatMainClass
is correctly loaded.
After modifying pom.xml
, rebuild the WAR file using mvn clean package
. To run the WAR with the correct classpath, manually specify the -cp
option as follows:
1 | java - cp target /sample-war-app-1 .0.war:target /sample-war-app-1 .0 /WEB-INF/classes com.jcg.MainClass |
This command runs the MainClass
inside the WAR file by manually specifying the classpath. The -cp
option sets the classpath to include both the WAR file (target/sample-war-app-1.0.war
) and the WEB-INF/classes
directory (target/sample-war-app-1.0/WEB-INF/classes
), where compiled Java classes are stored. Since java -jar
does not automatically recognize classes inside WEB-INF/classes/
, this approach ensures that Java can locate and execute com.jcg.MainClass
.
The output displays:
1 | Hello from inside the WAR file! |
Alternatively, if you want to extract the WAR and run the class manually, use:
1 2 3 4 | mkdir extracted-war cd extracted-war jar -xf .. /target/sample-war-app-1 .0.war java - cp WEB-INF /classes com.jcg.MainClass |
3. Using java -jar
with an Embedded Tomcat Server
Instead of manually specifying the classpath, another approach is to package the application as an executable WAR with an embedded Tomcat server. This allows the WAR to run directly using the java -jar
command, just like a JAR file. To enable this approach, update your pom.xml
to package the WAR with an embedded Tomcat server using Spring Boot or Tomcat’s Maven plugin. Below is an example using Spring Boot:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <!-- Spring Boot Starter for War Packaging --> < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-tomcat</ artifactId > < scope >provided</ scope > </ dependency > < build > < plugins > < plugin > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-maven-plugin</ artifactId > < executions > < execution > < goals > < goal >repackage</ goal > </ goals > </ execution > </ executions > < configuration > < finalName >sample-war</ finalName > < mainClass >com.jcg.SampleWarApplication</ mainClass > </ configuration > </ plugin > </ plugins > </ build > |
After modifying pom.xml
, build the WAR file using. Now, you can execute the WAR file directly using:
1 | java -jar target /sample-war .war |
By including an embedded Tomcat server, the WAR file becomes self-contained and behaves like a JAR file. The java -jar
command launches the embedded Tomcat instance, which then loads and runs the application automatically. The following output confirms that the Spring Boot application has successfully started.
1 2 3 4 5 6 7 8 | 2025-02-24T09:22:49.153+01:00 INFO 76601 --- [sample-war] [ main] com.jcg.SampleWarApplication : No active profile set, falling back to 1 default profile: "default" 2025-02-24T09:23:00.958+01:00 INFO 76601 --- [sample-war] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) 2025-02-24T09:23:01.185+01:00 INFO 76601 --- [sample-war] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2025-02-24T09:23:01.188+01:00 INFO 76601 --- [sample-war] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.36] 2025-02-24T09:23:02.413+01:00 INFO 76601 --- [sample-war] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2025-02-24T09:23:02.432+01:00 INFO 76601 --- [sample-war] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 12620 ms 2025-02-24T09:23:06.638+01:00 INFO 76601 --- [sample-war] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' 2025-02-24T09:23:06.901+01:00 INFO 76601 --- [sample-war] [ main] com.jcg.SampleWarApplication : Started SampleWarApplication in 23.617 seconds (process running for 31.468) |
This method is useful for running a web application without requiring an external Tomcat server, making deployment easier and more portable.
4. Conclusion
Running a class inside a WAR file from the command line can be achieved using different approaches. If you simply need to execute a standalone class within a WAR, using the java -cp
option allows you to specify the correct classpath manually. However, if you want to run the WAR as an executable file using java -jar
, you need to embed a servlet container like Tomcat. This can be done either with Spring Boot, which simplifies the process
5. Download the Source Code
This article explored how to run a Java class within a WAR file using the cli (command line).
You can download the full source code of this example here: Java run class within war cli