Skip to content
/ tommybox Public

TommyBox is a single-file executable that makes it possible to launch web apps on a desktop.

License

Notifications You must be signed in to change notification settings

xnbox/tommybox

Repository files navigation

🍥 TommyBox

License MIT Version 2.14.2 Powered by Tommy

TommyBox Demo App

About:

TommyBox is a standalone executable container that makes it possible to launch static and dynamic web apps on a desktop by providing built-in server and browser functionality.
TommyBox is similar to Electron and NW.js.

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

Under the hood, TommyBox is built on top of Tommy web server and SWT browser widget. App can be packed as WAR or ZIP archive and can optionally contain PWA manifest, JSP, servlets and all static stuff like CSS, JavaScript files etc.

See TommyBox in action: https://github.com/xnbox/tommybox_demo

Download:

Download the latest release of tb.jar

Features:

  • Single cross-platform executable jar (starts from ~25Mb)
  • No dependencies
  • No installation
  • No own configuration files, instead, TommyBox uses standard standard PWA webmanifest and standard Tomcat configuration files
  • Operating systems:
    • Linux
    • macOS
    • Windows
  • Architectures:
    • x86_64
    • win32-x86_64
    • aarch64
    • ppc64le
  • Supports custom command line args, stdin, stdout, stderr
  • Configurable display modes:
    • in-window
    • in-browser
    • fullscreen
    • headless
  • Single and multiple windows modes
  • Optional custom splash screen
  • Optional custom context menu
  • Optional custom system tray icon with custom menu

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 tb.jar [options] [custom arg]...

Options:
        --help               print help message
        --app <file|dir|URL> run app from ZIP or WAR archive, directory or URL
        --password <string>  provide password for encrypted ZIP or WAR archive

Run app:

Run ZIP (or WAR) file:

java -jar tb.jar --app MyKillerApp.war

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

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

Run ZIP (or WAR) from web server:

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

Run exploded web app from directory:

java -jar tb.jar --app MyKillerAppDir

Run password-protected ZIP (or WAR) archive:

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

Embed app:

  • Option 1. Copy your app content into the /app directory of the tb.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 tb.jar.

Brand your app by renaming the tb.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 ...

TommyBox specific PWA manifest keys:


Key Type Default value Description
display string standalone Standard PWA display mode.
Possible values:
standalone
minimal_ui
browser
fullscreen
minimized_window (non-standard)
maximized_window (non-standard)
desktop_area (non-standard)
headless (non-standard)
enable_fullscreen booleantrue Allow fullscreen mode
tray_icon booleantrue Tray icon
window_buttons array ["minimize", "maximize", "close"]Window buttons list.
Possible elements:
minimize
maximize
close
window_menu string none Window menu mode.
Possible values:
custom
native
none
window_always_on_topbooleanfalse Always on top window property
window_size string null Window size as string Eg.: 640x480
window_x number null Window location X coordinate (in pixels)
window_y number null Window location Y coordinate (in pixels)
strings array [] I18N dictionary for custom strings

TommyBox specific URL protocols:


Protocol Description HTML Example
home: Home action <a href="home:">Home</a>
back: Back action <a href="back:">Back</a>
forward: Forward action <a href="forward:>Forward</a>
reload: Reload action <a href="reload:">Reload</a>
quit: Exit to OS <a href="quit:">Exit</a>
minimize: Minimize window <a href="minimize:">Minimize</a>
fullscreen: Switch to fullscreen <a href="fullscreen:">Fullscreen</a>
open: Open the given URL in OS <a href="open:file://home/john/my.pdf">Open PDF</a>
open_in_new_window:Open the given URL in the new window <a href="open_in_new_window:http://example.com">Open in New Window</a>
open_in_browser:Open the given URL in the browser <a href="open_in_browser:http://example.com">Open in Browser</a>
java: Launch Java code <a href="java:javax.swing.JOptionPane.showMessageDialog(null, \"Hello, Java!\")">Launch Java Code</a>
js: Launch JavaScript code <a href="js:javax.swing.JOptionPane.showMessageDialog(null, 'Hello, JavaScript!')">Launch JavaScript Code</a>

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. 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.*.