Protect Tomcat Web Applications

tomcat turns a WAR into a self-contained Tomcat base. It uses the Tomcat components built into the packager, and never touches your local Tomcat installation.

1. Using the GUI

  1. On the application type page, select Tomcat WAR.

    Select Tomcat WAR

  2. Select the input WAR, the bundled Java version, and the target platforms, then choose simple or advanced mode.

    Select the input, Java version, target platform, and mode

  3. In advanced mode, choose Tomcat 9 or 10.1 or leave detection on automatic, and set the context path, JVM options, and exclusion rules as needed. Simple mode picks the Tomcat version from the compatibility scan. For what each option does, see Protector4J Advanced Mode Settings.

    Configure the Tomcat version, context path, and exclusion rules

  4. Select the output directory, review the summary, then click Run protection.

    Select the output directory and run protection

2. CLI examples

Setting the context path:

p4j tomcat app.war dist --context /app

Compatibility scanning, and applying the recommendations automatically:

p4j tomcat app.war --compat-scan
p4j tomcat app.war dist --compat-apply --context /app

The two options cannot be used together. They differ as follows:

OptionWhat it doesWhen to use it
--compat-scanScans the input WAR, prints the risks and configuration recommendations, and exits. It does not encode anything and does not produce dist, so no output directory is needed.Read the report first when you protect an application for the first time, after upgrading Tomcat-related dependencies, after changing the protection scope or JSP settings, and when investigating a compatibility problem.
--compat-applyScans, merges in the conservative recommendations, then continues encoding and writes the output, so an output directory is required.Use it to finish packaging once you have read the scan results and accepted the recommendations. It also suits repeat builds and CI pipelines where the rules are already verified.

For tomcat, --compat-apply can add exclusion patterns based on the scan results and adjust the Tomcat version, ZIP overlay, and archive suffix options. For those last three, a value given explicitly on the command line wins. Recommended exclusions are merged into your explicit --exclude patterns by default; pass --no-compat-excludes as well if you do not want them added. The scanner only performs static heuristic analysis, so problems that require source changes are not fixed by --compat-apply, and the packaged application still needs regression testing on the target platform.

For the other CLI commands, the full option list, environment variables, and automation examples, see the CLI Reference.

--tomcat-version defaults to auto. Set it to 9 or 10.1 when you need to be explicit:

p4j tomcat app.war dist --context /app --tomcat-version 10.1

3. Output structure

dist/
├── bin/
│   ├── catalina.sh
│   ├── startup.sh
│   ├── shutdown.sh
│   └── *.bat
├── conf/p4jx/
│   ├── contexts.list
│   ├── protected-classes.list
│   └── allowed-prefixes.list
├── protected/
│   └── app.p4jx
├── lib/
│   ├── p4jx-tomcat-runtime.jar
│   └── tomcat-runtime-deps.jar
├── vlxjre/
├── run.sh
└── run.bat

No physical WAR is produced by default. The web.xml, static resources, unprotected classes, metadata stubs, and protected implementations all live in protected/<context>.p4jx, which is presented to Tomcat through the P4JX WebResourceSet.

4. Starting and stopping

To run in the foreground:

./run.sh

To start and stop in the background, Tomcat style:

./bin/startup.sh
./bin/shutdown.sh

On Windows, use the matching .bat files. Logs are written to the logs/ directory inside the output.

For Windows targets you can also generate a native launcher, which starts the embedded Tomcat in the foreground — see Create a Windows EXE Launcher.

JVM startup options

At packaging time, enter one option per line under JVM startup options in the GUI, or set them on the command line:

p4j tomcat app.war dist \
  --context /app \
  --jvm-option -Xms1g \
  --jvm-option -Xmx2g

To change them in a deployed package:

  • macOS and Linux: edit bin/catalina.sh and add JVM_OPTS+=("-Xms1g" "-Xmx2g") after the JVM_OPTS=(...) line inside run_java(). This applies both to foreground runs and to background runs started by startup.sh.
  • Windows, foreground: edit bin\catalina.bat and add set "JVM_OPTS=%JVM_OPTS% -Xms1g -Xmx2g" after the existing set "JVM_OPTS=..." line.
  • Windows, background: add set "APP_JAVA_OPTS=-Xms1g -Xmx2g" in bin\startup.bat before it calls catalina.bat. If you need one set of permanent options covering both foreground and background, it is easier to regenerate the package from the GUI or CLI.

You can also set APP_JAVA_OPTS in front of the command for a single run. For full CMD, PowerShell, and script examples, see JVM Startup Options.

5. Choosing the Tomcat version

API namespace in the WARTomcatJava required
javax.servlet.*Tomcat 9Java 8, 11, 17, 21, or 25
jakarta.servlet.*Tomcat 10.1Java 11, 17, 21, or 25

Automatic detection identifies the API namespace from the application classes and deployment descriptors first, treating JAR names only as supporting evidence. If both javax and jakarta are in use, the tool refuses to guess.

6. JSP

When a WAR contains JSP files, they are precompiled into servlet classes and URL mappings during encoding by default. Compiling JSPs at run time would define new classes from the Tomcat work directory, which is outside the boundary the protected runtime allows for class definition.

You can control this explicitly:

--precompile-jsp
--no-precompile-jsp

Keep the default precompilation in production. Turning it off can leave pages in a JSP-based application failing to load.

7. Protection scope and exclusion rules

By default the application classes under WEB-INF/classes are protected, and WEB-INF/lib is not. Web-facing classes can be excluded:

p4j tomcat app.war dist \
  --context /app \
  --exclude 'com.example.web.**,com.example.dto.**'

Exclude servlets, filters, and listeners first, along with DTOs, configuration classes, entities, JNI bridge classes, and anything the container has to enhance. The compatibility scan makes conservative recommendations for you.

8. Adding another application to the same Tomcat package

p4j tomcat second.war dist \
  --append-app \
  --context /second

Constraints:

  • The context path must not clash with an existing application;
  • The existing and new applications must share the same Tomcat major version, Java version, and target platform;
  • Without --append-app, the tool refuses to write into an existing Tomcat package;
  • In the GUI, tick Append application to an existing Tomcat folder and pick the existing directory.

9. Note for Java 8

Java 8 targets enable the ZIP overlay automatically, so that the Tomcat WebResourceSet can open the protected archive.