Without commenting on the value proposition of what you propose to do, I am fairly certain that jpackage is not the way to do it. The job of jpackage is to take an application, bundle it with a Java Runtime, and create a native package / installer from it. What you are describing goes far beyond that. You are describing a new capability of the JDK that would take Java bytecode and compile it to run it on top of a JavaScript engine.

jpackage will use a JavaScript AOT compiler (TeaVM) to convert the Java
code to JavaScript, with the main class compiled to a JavaScript method
called 'main()'.

This is a good indicator that your proposal isn't simply targeting a new platform that already exists, and for which there is a Java runtime that supports running on this platform.

-- Kevin


On 4/25/2021 5:10 PM, Andrew Oliver wrote:
While I agree it is a somewhat different platform than Linux, Mac, or
Windows, I do think the web is a platform worth targeting.  And when seen
through just a slightly different lens, it is more like the others than it
might first seem:

On the platform:
* It is difficult for users to run Java bytecode or JARs directly
* Bytecode needs some form of transformation to operate efficiently
* Packaging into a platform-specific format is required for easy
distribution
* Without a packager tool, developers have to surmount significant
obstacles to distribute on the platform, reducing the appeal and adoption
of Java

Yes, there are maven and gradle plugins available to allow Java to target
the JavaScript platform.  ( For example,
https://teavm.org/docs/intro/getting-started.html )

However, for many users a browser-friendly solution with a small number of
dependencies is going to be the only option.  Take, for example, new users,
students, and educational settings.  In many cases, programming assignments
are required to be posted on the web.  If the JDK could target
self-contained web applications, as per this proposal, students could
easily post their assignments for the whole class to see.  This would be
much more reasonable than asking students to learn Java and maven and POM
files (and I'm saying that as a fan of maven).

Lest people misinterpret the above as suggesting this JEP is useful only in
an educational context, many business projects these days need to be web
applications.  Users are often unwilling or unable to download and install
applications for short, quick, or one-off transactions.  Thus there is a
large market for projects that absolutely require a web presence.  This JEP
would help illustrate how Java could be used even for front-end web
development.  Yes, large-scale projects would likely use maven or gradle.
But for quick proofs-of-concept, little could make it easier to demonstrate
the ability to do front-end development in Java then easily packaging a
Java code into a ZIP and deploying on any web server (or a WAR on an
application server, if desired).

   -Andrew

On Sat, Apr 24, 2021 at 10:39 PM Scott Palmer <swpal...@gmail.com> wrote:

This doesn’t seem like something that should be the job of jpackage.  The
jpackage tool is currently used for producing platform-specific packages or
installers targeted at end-users that include native launchers and a JRE.
Web-based applications are an entirely different beast. This seems like
more of a job for a Maven or Gradle plugin.

Regards,

Scott


On Apr 24, 2021, at 5:59 PM, Andrew Oliver <93q...@gmail.com> wrote:

Below is a Java Enhancement Proposal for your consideration to add
JavaScript to jpackage as a new target platform.  I would appreciate
feedback on the proposal contents.  I am also interested in learning
about
the process, specifically what approvals are required prior to start of
implementation, should sufficient consensus be reached.

( To view this proposal as a web page, please visit:
https://frequal.com/TeaVM/openjdk/jdk-list-draft1.html )

Thank you!

  -Andrew Oliver

Title: Add JavaScript platform to jpackage
Author: Andrew Oliver
Created: 2021/04/24
Type: Feature
State: Draft
Exposure: Open
Component: tools/jpackage
Scope: JDK
Discussion: core-libs-dev@openjdk.java.net
Template: 1.0

Summary
-------

jpackage already allows packaging Java applications for several
platforms.
This proposal adds a new platform: JavaScript.

This effort will enable jpackage to convert bytecode from the provided
classes into JavaScript, and generate the required HTML to invoke the
specified main method when opened in a web browser. These files will be
bundled into a WAR file for easy deployment.

Goals
-----

*   Enabling JVM languages to build client-side web applications
*   Allow easy generation of JavaScript from JVM bytecode
*   Allow easy deployment and execution of generated JavaScript in web
browsers
*   Allow easy deployment of the generated JavaScript in all web server
environments
    *   Java web application container (like Tomcat)
    *   Static file web servers
    *   Static file web hosting services

Non-Goals
---------

*   Allowing execution of JavaScript server-side. (Java already has
numerous options for executing bytecode server-side.)

Motivation
----------

Java was once used to create client-side web applications via applets
that
could be launched by visiting a web page. Applets could draw on an area
of
the screen (like HTML5 Canvas) or manipulate the page DOM to create
dynamic
front-end applications (like JS single-page apps).

However, as evident in JEP 398 ([
https://openjdk.java.net/jeps/398](https://openjdk.java.net/jeps/398)),
applets are no longer feasible due to the actions of browser vendors.
While
browsers have lost the ability to execute Java bytecode or invoke methods
from the Java class libraries, they do have mature engines for executing
a
different sort of code (JavaScript) and an extensive list of useful APIs.
By converting class files to JavaScript, and providing mechanisms to
invoke
browser APIs, Java can again be used to create in-browser applications.
[TeaVM](https://teavm.org) has demonstrated that this is feasible and
has
numerous benefits:

*   Provides a strongly-typed language for client-side web development
*   Provides a wealth of IDEs, build tools, and testing tools for
client-side web development
*   Allows teams with Java experience to produce apps with familiar
technology
*   Allows sharing of POJO and business logic classes, simplifying
development
*   Allows options for porting applet- and JNLP-based systems to
present-day browsers

Details
-------

An additional jpackage option for type will be added: `js`

jpackage will use a JavaScript AOT compiler (TeaVM) to convert the Java
code to JavaScript, with the main class compiled to a JavaScript method
called 'main()'.

jpackage bundles application code, runtime, and resources into a
platform-specific format. For this new JavaScript type, the layout will
be
either a ZIP file or a standard WAR file. The ZIP format will contain the
files ready to be extracted to a static file webserver or HTML hosting
service. Generated WARs will have the required structure to be deployable
in a Java web application container.

### WAR layout

*   HelloApp.war
    *   index.html (Main application page, loads classes.js and invokes
main())
    *   teavm
        *   classes.js (Class files, templates, and resources compiled to
JavaScript)
    *   css
        *   (CSS files from application)
    *   META-INF
        *   MANIFEST.MF
    *   WEB-INF
        *   web.xml

### ZIP Layout

*   HelloApp.zip
    *   index.html (Main application page, loads classes.js and invokes
main())
    *   teavm
        *   classes.js (Class files, templates, and resources compiled to
JavaScript)
    *   css
        *   (CSS files from application)

Basic usage: Non-modular applications
-------------------------------------

Command-line usage is similar to jpackage today, except you use the
`--type
js`. For example, if you have your application JARs in a folder called
`lib` and the JAR with the declared `main()` method is `main.jar`, you
could use this command:

```
$ jpackage --type js --name myapp --input lib --main-jar main.jar
```

This will produce `myapp.war` in the current directory. This is a
standard
WAR file ready for deployment in any web application container (like
Tomcat). When myapp/index.html is opened in a browser, the code in main()
will be executed, in-browser. A typical Hello World main() method like

```
    public static void main(String args\[\]) {
        System.out.println("Hello, Browser!");
    }
```

will print the message on the browser developer console.

Processing
----------

Conversion of the input JAR files to the classes.js file will be done by
TeaVM. It will

*   Convert provided class files to JavaScript
*   Expose the specified main method as main()
*   Provide implementation of selected core Java classes that function
in a
browser environment
*   Bundle resources into the generated JavaScript
*   Include images, css, and web.xml in the generated package, if
provided
*   Provide default index.html if omitted
*   Provide default web.xml if omitted and WAR format specified
*   Optionally minify the generated JavaScript

### js-specific options

1.  `--minify`: Perform a minification pass after generating JavaScript,
renaming classes and methods to short, generated names to reduce download
sizes and provide some obfuscation.
2.  `--debug`: Enable generation of source maps.
3.  `--debug-full`: Enable generation of source maps and bundled source
files.
4.  `--optimization`: Choose simple, advanced, or full.
    *   simple: Perform only basic optimizations
    *   advanced: Perform more optimizations. Recommended for production.
    *   full: Perform aggressive optimizations. Increases compilation
time.
5.  `--timezone-support`: Enables timezone support, at the cost of
increased application size
6.  `--locale-list`: Add extra locales via a list, at the cost of
increased
application size. Format: comma-separated list of locale IDs like
"en\_US,
ru\_RU"

### Unsupported options for the JavaScript type

These options are unsupported for `--type js`

*   `--file-associations`: Not yet meaningful for a web-based app, though
it may be in the future once PWAs support file types: [

https://github.com/WICG/file-handling](https://github.com/WICG/file-handling)
*   `--app-version, --copyright, --description, --license-file,
--vendor`:
jpackage will only support --name initially. Users can customize
index.html
(and the rest of the application) to show branding and metadata as
desired.
*   `--java-options`: Not yet supported, use `--arguments` instead.

Caveats
-------

Certain Java classes are not feasible to implement in a browser setting.
Socket, for example, is not useful in a browser since JavaScript cannot
open arbitrary socket connections. Code using unavailable classes will
fail
during packaging time with warnings about the missing classes.

Testing
-------

Since TeaVM is Java-based, tests will be able to run on any platform.

Testing will focus on the new jpackage code and added functionality.
Tests
will confirm that when valid parameters are provided, that output is
generated with the right name and in the right folder. Contents of the
generated ZIP and WAR files will be checked for the presence of expected
files. Testing generated files in a browser will be done manually.

A thorough test of TeaVM itself is out of scope for the jpackage testing.
This is in line with jpackage testing for other platforms, in which the
external packaging tool (like Wix on Windows) isn't exhaustively tested.

Dependencies
------------

The jpackage `js` type will require TeaVM binaries to be present.

Implementation options:

*   Download TeaVM on-demand and cache it. (This is the likely option.)
    *   Look for TeaVM in local repositories for popular build tools like
Maven and Gradle
    *   If not found locally, download TeaVM binaries from the read-only
central repository and store in the cache folder
    *   Invoke TeaVM from the local repository or cache
*   Require that TeaVM binaries be installed locally
    *   Provide the path to TeaVM binaries on the command line
*   Bundle TeaVM
    *   Challenging due to incompatible licenses (Apache v2 vs. GPL v2
with
CPE)
    *   Probably unnecessary given the options above. Other jpackage
options require pre-installed tools, this will be no different.

High-Level Design
-----------------

A new bundler will be added to the jpackage Java source code.

It will first ensure that TeaVM binaries (JAR files) are available
locally,
as described in the section above.

The new bundler will use TeaVM's TeaVMRunner ([

https://github.com/konsoletyper/teavm/blob/master/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java](https://github.com/konsoletyper/teavm/blob/master/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java)
),
which conveniently accepts options similar to jpackage itself.
TeaVMRunner
will do the heavy lifting of converting the application JAR files and
resources into `classes.js`.

The bundler will provide additional files required to make a web
application, including an `index.html` to launch the `main()` method. The
bundler will create the final archive (ZIP or WAR) using Java's
ZipOutputStream. For the WAR format, the bundler will also add `web.xml`
and `MANIFEST.MF` if not present to create a deployable, standard WAR
file.



Reply via email to