Proposal to add JavaScript platform to jpackage

Kevin Rushforth kevin.rushforth at oracle.com
Mon Apr 26 12:38:54 UTC 2021


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 <swpalmer at 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 <93q62q at 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 at 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.
>>
>>



More information about the core-libs-dev mailing list