Run JNLP Apps in the Browser
Run a working example of a JNLP application or applet
This tutorial runs two Java Web Start (JNLP) examples in the browser with CheerpJ: a standalone application and an applet. You read the JAR files and the main class from the .jnlp file, then start the application from your own page with the CheerpJ API.
To open JNLP files from the pages that already launch them, without writing a page of your own, use the JNLP Runner browser extension.
The tutorial has two parts:
Prerequisites
For either example you need:
- The
.jnlpfile (given below) - Node.js (>= 18)
- A local HTTP server that supports Range requests, such as
npx http-server - A text editor to create and edit an HTML file
- A modern browser such as Chrome, Edge, Firefox or Safari
If you already have a JNLP application and want to run it in the browser, see the JNLP quickstart.
JNLP application: SwingSet3
1. The .jnlp file
Start with the JNLP file. Below is a JNLP file for SwingSet3, the Swing demo application. Three elements are highlighted:
- The code base: the
codebaseattribute of<jnlp>. It is the URL the application files are downloaded from. - The JAR files: the
<jar>tags in the<resources>section. - The class name: the
main-classattribute of<application-desc>. The<application-desc>tag also tells you that this is a standalone application.
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc.//DTD JNLP 1.5//EN"><jnlp codebase="https://raw.githubusercontent.com/leaningtech/cheerpj-meta/main/examples/SwingSet3/" href="SwingSet3.jnlp" spec="6.0+"> <information> <title>SwingSet3</title> <vendor>Oracle America, Inc.</vendor> <homepage href="https://swingset3.dev.java.net"/> <description>Demo to showcase features of the Swing UI toolkit in Java 6</description> <icon href="swingset3/resources/images/splash.png" kind="splash"/> <offline-allowed/> <shortcut online="true"/> </information> <resources> <j2se version="1.6+"/> <jar href="SwingSet3.jar" main="false"/> <jar href="lib/AppFramework.jar"/> <jar href="lib/TimingFramework.jar"/> <jar href="lib/swing-worker.jar"/> <jar href="lib/swingx.jar"/> </resources> <application-desc main-class="com.sun.swingset3.SwingSet3"/></jnlp>2. Download the application files
Build the full URL of each JAR by appending its href to the codebase URL, then open it in the browser to download it. For example:
https://raw.githubusercontent.com/leaningtech/cheerpj-meta/main/examples/SwingSet3/SwingSet3.jarDo this for every JAR in the JNLP file, keeping the lib/ paths. The manifest of SwingSet3.jar also lists lib/AnimatedTransitions.jar and lib/javaws.jar in its Class-Path; download them from the same code base.
3. Create a project directory
Create a directory for the files. Any name works, for example cheerpj-example-swingset3:
mkdir cheerpj-example-swingset3Recreate the directory structure used in the JNLP file. For this example that is a lib subdirectory:
cd cheerpj-example-swingset3mkdir libMove the JARs into place, following the paths in the JNLP file:
└──cheerpj-example-swingset3 ├── SwingSet3.jar └── lib ├── AnimatedTransitions.jar ├── AppFramework.jar ├── javaws.jar ├── swing-worker.jar ├── swingx.jar └── TimingFramework.jar4. Create an HTML file
In cheerpj-example-swingset3, create a file called index.html:
<!doctype html><html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> <title>SwingSet3 (CheerpJ)</title> <script src="https://cjrtnc.leaningtech.com/5.0/loader.js"></script> <style> html, body { margin: 0; }
#container { width: 100vw; height: 100svh; } </style> </head> <body> <div id="container"></div> <script type="module"> await cheerpjInit(); cheerpjCreateDisplay(-1, -1, document.getElementById("container")); await cheerpjRunJar("/app/SwingSet3.jar"); </script> </body></html>What is going on?
- The
<script>tag in the<head>loads CheerpJ:
<script src="https://cjrtnc.leaningtech.com/5.0/loader.js"></script>cheerpjInit()initialises CheerpJ.cheerpjCreateDisplay()creates the display that holds all Java windows. With-1, -1it fills the container element and follows its size.cheerpjRunJar()runs the application./app/is the virtual file system mount point for the root of the web server the page is loaded from.
This example uses
cheerpjRunJar()becauseSwingSet3.jarnames its main class in its manifest. When a JAR does not, usecheerpjRunMain()with themain-classfrom the JNLP file and the JARs as the class path, for examplecheerpjRunMain("com.sun.swingset3.SwingSet3", "/app/SwingSet3.jar:/app/lib/AppFramework.jar:...").
5. Host your page locally
From the project directory, serve the files over HTTP. Vite works well during development because it reloads the page when the files change:
npx viteAlternatively, use the http-server utility:
npx http-server -p 8080Open the URL shown in the terminal, for example http://127.0.0.1:8080/.
NoteThe server must support HTTP Range requests, and the page cannot be opened from file://. Python’s http.server does not support Range requests. See basic server setup.
The result
The application runs in the browser:
Source code and credits
- View full source code for this example on GitHub
- SwingSet3 is a demo application by Oracle America, Inc.
JNLP applet: Pitch
This part uses the Pitch applet from NASA’s Beginner’s Guide to Aeronautics. The applet is an interactive animation of an aircraft’s pitch motion. See more
.
1. The .jnlp file
Start with the JNLP file. Below is a JNLP file for the Pitch applet. Three elements are highlighted:
- The code base: the
codebaseattribute of<jnlp>. It is the URL the applet files are downloaded from. - The JAR files: the
<jar>tags in the<resources>section. - The class name: the
main-classattribute of<applet-desc>. The<applet-desc>tag also tells you that this is an applet, and gives its width and height.
<?xml version="1.0" encoding="utf-8"?><!-- JNLP File for Pitch applet --><jnlp spec="1.0+" codebase="https://raw.githubusercontent.com/leaningtech/cheerpj-meta/main/examples/Pitch-Applet/"
href="PitchApplet.jnlp"> <information> <title>Pitch</title> <vendor>NASA Glenn Research Center</vendor> <homepage href="https://www.grc.nasa.gov/WWW/K-12/airplane/"/> <description>Pitch motion simulator</description> <description kind="short">Beginner's Guide to Aeronautics - Pitch motion simulator written in Java</description> <offline-allowed/> </information> <security> <all-permissions/> </security> <resources> <j2se version="1.4+" initial-heap-size="30m" max-heap-size="300m" /> <jar href="Pitch.jar"/> </resources> <applet-desc main-class="Pitchview" width="500" height="300"/></jnlp>2. Download the applet file
Build the full URL of the JAR by appending its href to the codebase URL, then open it in the browser to download it:
https://raw.githubusercontent.com/leaningtech/cheerpj-meta/main/examples/Pitch-Applet/Pitch.jar3. Create a project directory
Create a directory for the files. Any name works, for example cheerpj-example-applet:
mkdir cheerpj-example-appletMove Pitch.jar into it:
└──cheerpj-example-applet └── Pitch.jar4. Create an HTML file
In the project directory, create a file called index.html:
<!doctype html><html lang="en"> <head> <meta charset="utf-8" /> <title>Pitch applet (CheerpJ)</title> <script src="https://cjrtnc.leaningtech.com/5.0/loader.js"></script> <style> div { max-width: 500px; margin: auto; text-align: center; } h1 { margin-bottom: 50px; } h5 { margin-top: 20px; } </style> </head>
<body> <div> <h1>Applet example with CheerpJ</h1> <div> <cheerpj-applet archive="Pitch.jar" code="Pitchview" height="300" width="500" > Your browser cannot handle the applet tag! </cheerpj-applet> </div> <h5> The applet shown in this example belongs to the NASA's <a href="https://www.grc.nasa.gov/WWW/K-12/airplane/" >Beginner's Guide to Aeronautics</a > and it is available at their <a href="https://github.com/nasa/BGA/tree/main">GitHub repository</a>. </h5> <h5> Applet is running with <a href="https://cheerpj.com/">CheerpJ</a> by <a href="https://leaningtech.com/">©Leaning Technologies</a> </h5> </div> <script type="module"> await cheerpjInit(); </script> </body></html>Java applets and Java 8cheerpjInit runs Java 8 when no version is set. Applets run on Java 8 only, so do not set version to 11 or higher on a page that runs an applet.
What is happening?
- The
<script>tag in the<head>loads CheerpJ:
<script src="https://cjrtnc.leaningtech.com/5.0/loader.js"></script>- The
<cheerpj-applet>tag gives the JAR (archive), the class name (code) and the size, taken from<jar>and<applet-desc>in the JNLP file. Thecheerpj-prefix stops a Java plug-in, if one is installed, from trying to run the applet. The classic<applet>tag also works. cheerpjInit()initialises CheerpJ, which then runs the applets on the page. Applets do not needcheerpjCreateDisplay().
5. Host your page locally
From the project directory, serve the files over HTTP. Vite works well during development because it reloads the page when the files change:
npx viteAlternatively, use the http-server utility:
npx http-server -p 8080Open the URL shown in the terminal, for example http://127.0.0.1:8080/.
NoteThe server must support HTTP Range requests, and the page cannot be opened from file://. Python’s http.server does not support Range requests. See basic server setup.
The result
The applet runs in the browser:
Source code and credits
-
The applet used in this tutorial belongs to NASA’s Beginner’s Guide to Aeronautics
and it is available at their GitHub repository
.
Further reading
- Run a JNLP application
- Runtime API reference
- JNLP Runner browser extension, for opening JNLP files without writing a page