---
title: "Run JNLP Apps in the Browser"
source: "https://cheerpj.com/docs/tutorials/jnlp"
---

# 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](https://cheerpj.com/cheerpj-jnlp-runner) browser extension.

The tutorial has two parts:

- [Application example (SwingSet3)](#jnlp-application-swingset3)
- [Applet example (Pitch)](#jnlp-applet-pitch)

## Prerequisites

For either example you need:

- The `.jnlp` file (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](https://cheerpj.com/docs/getting-started/JNLP.md).

## 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 `codebase` attribute 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-class` attribute of `<application-desc>`. The `<application-desc>` tag also tells you that this is a standalone application.

`SwingSet3.jnlp`

```xml
<?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:

```plaintext
https://raw.githubusercontent.com/leaningtech/cheerpj-meta/main/examples/SwingSet3/SwingSet3.jar
```

Do 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`:

```bash
mkdir cheerpj-example-swingset3
```

Recreate the directory structure used in the JNLP file. For this example that is a `lib` subdirectory:

```sh
cd cheerpj-example-swingset3
mkdir lib
```

Move the JARs into place, following the paths in the JNLP file:

```plaintext
└──cheerpj-example-swingset3
    ├── SwingSet3.jar
    └── lib
        ├── AnimatedTransitions.jar
        ├── AppFramework.jar
        ├── javaws.jar
        ├── swing-worker.jar
        ├── swingx.jar
        └── TimingFramework.jar
```

### 4. Create an HTML file

In `cheerpj-example-swingset3`, create a file called `index.html`:

`index.html`

```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:

```html
<script src="https://cjrtnc.leaningtech.com/5.0/loader.js"></script>
```

- [`cheerpjInit()`](https://cheerpj.com/docs/reference/cheerpjInit.md) initialises CheerpJ.
- [`cheerpjCreateDisplay()`](https://cheerpj.com/docs/reference/cheerpjCreateDisplay.md) creates the display that holds all Java windows. With `-1, -1` it fills the container element and follows its size.
- [`cheerpjRunJar()`](https://cheerpj.com/docs/reference/cheerpjRunJar.md) runs the application.
- `/app/` is the [virtual file system](https://cheerpj.com/docs/explanation/File-System-support.md) mount point for the root of the web server the page is loaded from.

> This example uses [`cheerpjRunJar()`](https://cheerpj.com/docs/reference/cheerpjRunJar.md) because `SwingSet3.jar` names its main class in its manifest. When a JAR does not, use [`cheerpjRunMain()`](https://cheerpj.com/docs/reference/cheerpjRunMain.md) with the `main-class` from the JNLP file and the JARs as the class path, for example `cheerpjRunMain("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](https://vitejs.dev/) works well during development because it reloads the page when the files change:

```sh
npx vite
```

Alternatively, use the http-server utility:

```sh
npx http-server -p 8080
```

Open the URL shown in the terminal, for example `http://127.0.0.1:8080/`.

> **Note**
>
> The 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](https://github.com/leaningtech/cheerpj-meta/tree/main/examples/SwingSet3)
- 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](https://www.grc.nasa.gov/WWW/K-12/airplane/). The applet is an interactive animation of an aircraft’s pitch motion. [See more](https://www1.grc.nasa.gov/beginners-guide-to-aeronautics/aircraft-rotations/).

### 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 `codebase` attribute 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-class` attribute of `<applet-desc>`. The `<applet-desc>` tag also tells you that this is an applet, and gives its width and height.

`PitchApplet.jnlp`

```xml
<?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:

```plaintext
https://raw.githubusercontent.com/leaningtech/cheerpj-meta/main/examples/Pitch-Applet/Pitch.jar
```

### 3. Create a project directory

Create a directory for the files. Any name works, for example `cheerpj-example-applet`:

```bash
mkdir cheerpj-example-applet
```

Move `Pitch.jar` into it:

```plaintext
└──cheerpj-example-applet
    └── Pitch.jar
```

### 4. Create an HTML file

In the project directory, create a file called `index.html`:

`index.html`

```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 8**
>
> cheerpjInit 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:

```html
<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. The `cheerpj-` prefix stops a Java plug-in, if one is installed, from trying to run the applet. The classic `<applet>` tag also works.
- [`cheerpjInit()`](https://cheerpj.com/docs/reference/cheerpjInit.md) initialises CheerpJ, which then runs the applets on the page. Applets do not need `cheerpjCreateDisplay()`.

### 5. Host your page locally

From the project directory, serve the files over HTTP. [Vite](https://vitejs.dev/) works well during development because it reloads the page when the files change:

```sh
npx vite
```

Alternatively, use the http-server utility:

```sh
npx http-server -p 8080
```

Open the URL shown in the terminal, for example `http://127.0.0.1:8080/`.

> **Note**
>
> The 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

- [View full source code for this example on GitHub](https://github.com/leaningtech/cheerpj-meta/tree/main/examples/Pitch-Applet)

- The applet used in this tutorial belongs to NASA’s [Beginner’s Guide to Aeronautics](https://www.grc.nasa.gov/WWW/K-12/airplane/) and it is available at their [GitHub repository](https://github.com/nasa/BGA/tree/main).

## Further reading

- [Run a JNLP application](https://cheerpj.com/docs/getting-started/JNLP.md)
- [Runtime API reference](https://cheerpj.com/docs/reference.md)
- [JNLP Runner](https://cheerpj.com/cheerpj-jnlp-runner) browser extension, for opening JNLP files without writing a page
