/tommy

Tommy is Apache Tomcat, bundled as a single executable jar.

Primary LanguageJavaMIT LicenseMIT

🌆 Tommy Web Server

License MIT Version 10.0.10

About:

Tommy is a tiny single-file fully configurable Apache Tomcat web server that allows you to run or embed static and dynamic (JSP and Servlets) web applications.

An app can be provided as a directory or packed as WAR (or ZIP) archive that can contain servlets, JSP, HTML and all other static stuff like CSS, JavaScript, etc.

We use the Tommy web server in other our projects:

Download:

Download the latest release of tommy.jar

Features:

  • No dependencies
  • No installation
  • No own configuration files, instead, Tommy uses standard Tomcat configuration files
  • Single executable jar (starts from ~10Mb)
  • Supports custom command line args, stdin, stdout, stderr

Supported web apps:

  • WAR files
  • Web apps packed as ZIP archives (including standard password-protected ZIPs)
  • Exploded web apps (local directories)
  • Remote WAR / ZIP files (on HTTP servers)
  • Embedded WAR / ZIP files and directories

Usage:

java -jar tommy.jar [options] [custom arg]...

Options:
        --help                  print help message
        --app <file|dir|URL>    run app from ZIP or WAR archive, directory or URL
        --port <number>         HTTP TCP port number, default: 8080
        --port-ssl <number>     HTTPS TCP port number, default: 8443
        --redirect              redirect HTTP to HTTPS
        --context-path <string> context path, default: /
        --password <string>     provide password (for encrypted ZIP (or WAR) archive)

Run app:

Run ZIP (or WAR) file:

java -jar tommy.jar --app MyKillerApp.war

Run ZIP (or WAR) file with custom command-line args:

java -jar tommy.jar --app MyKillerApp.war myparam1 myparam2 ...

Run ZIP (or WAR) from web server:

java -jar tommy.jar --app https://example.com/MyKillerApp.zip

Run exploded web app from directory:

java -jar tommy.jar --app MyKillerAppDir

Run password-protected ZIP (or WAR) archive:

java -jar tommy.jar --app MyKillerApp.zip --password mysecret

Run password-protected ZIP (or WAR) archive with custom command-line args:

java -jar tommy.jar --app MyKillerApp.zip --password mysecret myparam1 myparam2 ...

Embed app:

  • Option 1. Copy your app content into the /app directory of the tommy.jar.
  • Option 2. Pack your app as app.war or app.zip (the archive can be encrypted) and copy the archive to the root directory of the tommy.jar.

Brand your app by renaming the tommy.jar to the MyKillerApp.jar.

Run embedded app:

java -jar MyKillerApp.jar

Run embedded app with custom command-line args:

java -jar MyKillerApp.jar myparam1 myparam2 ...

Run password-protected embedded app:

java -jar MyKillerApp.jar --password mysecret

Run password-protected embedded app with custom command-line args:

java -jar MyKillerApp.jar --password mysecret myparam1 myparam2 ...

Tomcat configuration:

Tommy uses the Apache Tomcat configuration files from /META-INF/tomcat/conf directory of the tommy.jar archive.

Access to the custom command-line args and system streams programmatically (JNDI):

// ...somewhere in your Servlet or JSP

InitialContext ctx = new InitialContext();

/* get custom command-line args */
String[] args = (String[]) ctx.lookup("java:comp/env/tommy/args");

/* get standard input (stdin) */
InputStream stdin = (InputStream) ctx.lookup("java:comp/env/tommy/stdin");

/* get standard output (stdout) */
PrintStream stdout = (PrintStream) ctx.lookup("java:comp/env/tommy/stdout");

/* get standard error (stderr) */
PrintStream stderr = (PrintStream) ctx.lookup("java:comp/env/tommy/stderr");

/* get "--app" parameter value */
String app = (String) ctx.lookup("java:comp/env/tommy/app");

// ...

F.A.Q.

Q. How to hide Tomcat stack trace and server info in error pages?

A. Steps:

  1. Edit the file /META-INF/tomcat/conf/server.xml of the tommy.jar archive
  2. Search for the <Host> element
  3. Just below that line, insert the following <Valve> element:
<Valve className      = "org.apache.catalina.valves.ErrorReportValve"
       showReport     = "false"
       showServerInfo = "false" />

Q. My app failed with java.lang.ClassNotFoundException: javax.servlet.*

A. As a result of the move from Java EE to Jakarta EE, starting from v10, Apache Tomcat supports only the Jakarta EE spec. javax.servlet.* is no longer supported. Replace the javax.servlet.* imports in your code with jakarta.servlet.*.