From e0fb7848dfe9abf876a8d6b8ecb820fe2b290ac6 Mon Sep 17 00:00:00 2001 From: Ana Gabriela Reyna Date: Thu, 28 Sep 2023 19:10:53 +0100 Subject: [PATCH 01/33] Removed AOT and Java DOM content, updated some links, updated app and applet getting started examples, changelog, minor updates on index --- .../03-getting-started/01-Java-applet.mdx | 2 +- src/content/docs/cheerpj3/00-faq.md | 94 ++++ src/content/docs/cheerpj3/01-demos.md | 42 ++ src/content/docs/cheerpj3/02-changelog.md | 42 ++ .../03-getting-started/00-Java-app.md | 85 ++++ .../03-getting-started/01-Java-applet.mdx | 101 ++++ .../03-getting-started/02-Java-library.md | 30 ++ .../cheerpj3/04-guides/File-System-support.md | 65 +++ ...nting-Java-native-methods-in-JavaScript.md | 57 +++ .../04-guides/Startup-time-optimization.md | 99 ++++ .../cheerpj3/04-guides/Using-web-workers.md | 72 +++ .../05-reference/02-Command-Line-Options.md | 103 ++++ .../docs/cheerpj3/05-reference/Runtime-API.md | 444 ++++++++++++++++++ .../cheerpj3/05-reference/WebWorker-API.md | 69 +++ src/content/docs/cheerpj3/index.mdx | 67 ++- 15 files changed, 1368 insertions(+), 4 deletions(-) create mode 100644 src/content/docs/cheerpj3/00-faq.md create mode 100644 src/content/docs/cheerpj3/01-demos.md create mode 100644 src/content/docs/cheerpj3/02-changelog.md create mode 100644 src/content/docs/cheerpj3/03-getting-started/00-Java-app.md create mode 100644 src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx create mode 100644 src/content/docs/cheerpj3/03-getting-started/02-Java-library.md create mode 100644 src/content/docs/cheerpj3/04-guides/File-System-support.md create mode 100644 src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md create mode 100644 src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md create mode 100644 src/content/docs/cheerpj3/04-guides/Using-web-workers.md create mode 100644 src/content/docs/cheerpj3/05-reference/02-Command-Line-Options.md create mode 100644 src/content/docs/cheerpj3/05-reference/Runtime-API.md create mode 100644 src/content/docs/cheerpj3/05-reference/WebWorker-API.md diff --git a/src/content/docs/cheerpj2/03-getting-started/01-Java-applet.mdx b/src/content/docs/cheerpj2/03-getting-started/01-Java-applet.mdx index d5d9fc8d..30416a8c 100644 --- a/src/content/docs/cheerpj2/03-getting-started/01-Java-applet.mdx +++ b/src/content/docs/cheerpj2/03-getting-started/01-Java-applet.mdx @@ -21,7 +21,7 @@ CheerpJ can run Java applets in the browser seamlessly. This page will help you ### 1. Create a basic HTML file -```html title="index.html" {6-9, 12-20} +```html title="index.html" {6-9,12-19} diff --git a/src/content/docs/cheerpj3/00-faq.md b/src/content/docs/cheerpj3/00-faq.md new file mode 100644 index 00000000..8681d7d1 --- /dev/null +++ b/src/content/docs/cheerpj3/00-faq.md @@ -0,0 +1,94 @@ +--- +title: FAQ +--- + +## What is CheerpJ? + +CheerpJ is a solution for converting unmodified Java client applications into browser-based HTML5/JavaScript web applications. CheerpJ consists of a full Java runtime environment in JavaScript, and of a on-the-fly compiler for dynamic class generation, to be deployed alongside the application. + +## What does the CheerpJ compiler do? + +The CheerpJ compiler, based on LLVM/Clang, as well as on parts of [Cheerp](https://github.com/leaningtech/cheerp-meta), converts Java bytecode into JavaScript, without requiring the Java source. CheerpJ can be invoked on whole Java archives (.jar) or on single .class files. + +## What parts of the Java SE runtime are supported? + +The CheerpJ runtime environment is a full Java SE runtime in JavaScript. Differently from other technologies which provide a partial re-implementation written manually in JavaScript, we opted to convert the entire OpenJDK Java SE runtime to JavaScript using CheerpJ. The CheerpJ runtime is constituted of both JavaScript files and .jar archives. All CheerpJ runtime components are dynamically downloaded on demand by the application to minimise total download size. The CheerpJ runtime library is hosted by us on a dedicated CDN-backed domain, and we invite users to link to it in order to take advantage of caching and cross-application resource sharing. + +## Can I use CheerpJ to convert my legacy Java application? I have no longer access to the source code. + +Yes, you can convert any Java SE application with CheerpJ without touching the source code. You only need all the .jar archives of your application. + +## Can I use CheerpJ to convert Java libraries and integrate them in my HTML5 application? + +Yes. Java methods can be exposed to JavaScript with an asynchronous interface. A synchronous-looking construct is provided to minimise verbosity when multiple methods are invoked. + +## Can I call JavaScript libraries or web APIs from Java? + +Yes, CheerpJ allows you to interoperate with any JavaScript or browser API. + +## How does CheerpJ support reflection? + +In order to support reflection, CheerpJ, similarly to a JVM, utilizes the metadata available in the original .jar file. A converted application, to be deployed on a web server, comprises both the converted .jar.js JavaScript files and the .jar archives. After having converted a .jar archive, it is possible to remove all the bytecode from them prior to deployment, in order to minimize download time (we provide a simple tool to do so). The combined size of the pruned .jar archive and the output JavaScript, after compression, is comparable to the original .jar. + +Optionally, .jar archives can be split into multiple segments (size to be defined at compile time) before being deployed. The application will only load the required segments at run time, thus further reducing download time. + +## How does CheerpJ support dynamic class generation? + +One component of CheerpJ is the CheerpJ on-the-fly compiler (cheerpJ.js), a minimalistic Java-bytecode-to-JavaScript compiler written in C++ and compiled to JavaScript. CheerpJ.js needs to be distributed alongside any converted Java application that makes use of dynamic constructs such as proxy classes, which get compiled on the fly at run time directly on the browser. + +## What is the size of the output of CheerpJ + +The combined size of the .jar to be served (pruned of its bytecode) and of the resulting JavaScript is similar to that of the original .jar archive. Anecdotally, an overhead of 20% seems to be the average. + +## The size of the output is too big! Why doesn't CheerpJ remove "dead code"? + +In Java there is no "dead code". Java supports reflection, so all code and classes can be potentially used at runtime. For this reason CheerpJ cannot automatically remove any code. + +This said, depending on the application, it is often possible to remove a lot of code using ProGuard: an industry standard open source tool. CheerpJ provides support to automatically generate a ProGuard configuration file to make sure that classes used via reflection are not removed. For more information see: [here](/cheerpj3/guides/Startup-time-optimization#use-proguard-to-remove-unused-code) + +## Can JavaScript code produced by Cheerp be plugged into Node.js? + +Yes, it should. However, this has not been one of our areas of focus so far. + +## When compiling my application I see the message `Failure compiling MyFile.class`, but cheerpjfy continues to execute with no errors + +This means that it was not possible to use the new codegen. CheerpJ will use, for this class, the legacy codegen. This might happen for multiple classes in the same .jar, + +## My Java application needs to get data over the network, but I only get `SocketException`s + +In the browser environment it is not possible to use sockets to connect to arbitrary ports. As a special exception CheerpJ provides a custom HTTP/HTTPS handler (based on XHR) that can be used to get data over HTTP and use REST APIs. To enable this handler please set the property `java.protocol.handler.pkgs=com.leaningtech.handlers` during the `cheerpjInit` call, for example: + +`cheerpjInit({javaProperties:["java.protocol.handler.pkgs=com.leaningtech.handlers"]});` + +Please note that when using CheerpJ to run applets the custom handlers are enabled by default. + +## When I run an application compiled with CheerpJ I see 404 errors in the browser console. What's going on? + +Ignore those errors. CheerpJ provides a filesystem implementation on top of HTTP. In this context it is absolutely ok for some files to be missing. CheerpJ will correctly interpret 404 errors as a file not found condition. + +## My application compiled with CheerpJ does not work and I just see the "CheerpJ runtime ready" on the top of the screen. What's going on? + +Many first time users get stuck at this point. The most common issues are: + +- Opening the HTML page directly from disk: The URL in the browser should always start with http:// or https://, if it starts with file:// CheerpJ will not work. You need to use a local web server during testing. +- Forgetting to add "/app/" prefix to the JAR files used in Web page. CheerpJ implements a virtual filesystem with multiple mount points, the "/app/" prefix is required. +- More in general, you can use the "Network tab" of the developer tools in the browser to check if the JAR is being correctly downloaded. If the JAR is never downloaded, or a 404 error is returned, something is wrong with the JAR path. If you don't see anything in the "Network tab", please reload the page while keeping the developer tools open. +- When converting obfuscated JARs on MacOS and Windows there might be collisions between classes due to the case-insensitive nature of the filesystem. For example `a.class` and `A.class` will be considered the same. Always try to convert the JAR using a Linux machine before reporting a bug when converting obfuscated JARs. + +## My application compiled with CheerpJ does not work and I see a cross origin error to a Google service in the console. What's going on? + +The cross origin message you see happens as part of our automatic bug reporting system and it is not the real error. Something else is making your application crash, please report a bug [here](https://github.com/leaningtech/cheerpj-meta/issues). + +## Can I play Old School RuneScape using CheerpJ or the CheerpJ Applet Runner extension? + +Not yet. The main problem is that RuneScape requires low level network connections primitives (sockets) which are not provided by browsers at this time due to security concerns. In the future we might provide a paid add-on to the CheerpJ Applet Runner extension to support this use case via tunneling. + +## How can I use CheerpJ to generate WebAssembly code instead of JavaScript? + +CheerpJ cannot be used to generate WebAssembly code at the moment. + +CheerpJ uses WebAssembly internally for some components of the runtime, but Java bytecode can only be compiled to JavaScript at this time since WebAssembly currently is not an efficient target for Java. CheerpJ will support WebAssembly output when the platform matures. + +## What is the status of CheerpJ? + +CheerpJ is actively developed by [Leaning Technologies Ltd](https://leaningtech.com), a British-Dutch company focused on compile-to-JavaScript and compile-to-WebAssembly solutions. diff --git a/src/content/docs/cheerpj3/01-demos.md b/src/content/docs/cheerpj3/01-demos.md new file mode 100644 index 00000000..2a992f99 --- /dev/null +++ b/src/content/docs/cheerpj3/01-demos.md @@ -0,0 +1,42 @@ +--- +title: Demos +--- + +To showcase the capabilities of the CheerpJ compiler we have published several demos + +## OpenAstexViewer + + + +This demo highlights how complex Java applets with 3D rendering can efficiently and safely run in any browser using CheerpJ. + +This specific applet is a visualization tool for protein structures. + +- Go to the [demo](https://cheerpjdemos.leaningtech.com/OpenAstexViewer.html) +- Find the source code [here](https://github.com/openastexviewer/openastexviewer) + +## Swing examples: + + + +A few selected Java Swing examples to demonstrate how complex Swing GUI apps can be automatically converted to HTML5/JavaScript. + +- Go to the [demo](https://cheerpjdemos.leaningtech.com/SwingDemo.html) +- [Source](https://docs.oracle.com/javase/tutorial/uiswing/examples/components/index.html) + +## JavaFiddle + + + +A playground to compile and run Java programs directly in the browser. Both console and GUI applications are supported. The standard `javac` compiler is used, since `javac` is also written in Java the whole compiler runs in the browser, together with the compiled application. + +- Go to the [demo](https://javafiddle.leaningtech.com/) (please inspect the page using the devtools). + +## iText Demo + + + +Edit PDFs fully client side using the industry standard [iText](https://itextpdf.com/en) library converted to JavaScript. This demo demonstrates how CheerpJ APIs can be used to instance Java objects and call methods directly from JavaScript. + +- Go to the [demo](https://cheerpjdemos.leaningtech.com/iTextDemo.html) +- [Source](https://cheerpjdemos.leaningtech.com/itextCheerpJDemo.js) diff --git a/src/content/docs/cheerpj3/02-changelog.md b/src/content/docs/cheerpj3/02-changelog.md new file mode 100644 index 00000000..490916ff --- /dev/null +++ b/src/content/docs/cheerpj3/02-changelog.md @@ -0,0 +1,42 @@ +--- +title: Changelog +--- + +version 3.0 - September 22nd, 2023: + +``` + +Focus on performance, particularly on startup time +* Multiple fixes on the Cheerp compiler to better optimize JNI code +* Multiple experiments on the JIT to better interact with V8 tiering +``` + +version 3.0 - September 15th, 2023: + +``` +Work on CJ3 Library mode, with a focus on performance and Java <-> JS type conversions +* Optimized away context switching overhead on user native calls +* Support many more type conversion between JS numbers/integers/booleans and Java primitive types +* Support conversion between JS numbers and Java boxed types (i.e. java.lang.Integer) +* JIT optimizations +* Optimization of the core class loading code path +``` + +version 3.0 - September 8th, 2023: + +``` +JNLP support and performance work +* Significant speed up of System.arrayCopy +* JIT optimizations +``` + +version 3.0 - September 1st, 2023: + +``` +Focus on networking +* Integrated Tailscale support for low level TCP/UDP traffic, same code we use for WebVM/CheerpX +* Custom HTTP/HTTPS handlers are now enabled by default unless Tailscale is used. The handlers provide http/https support in common cases. +* Optimized exception handling +* Optimized code rendering +* Multiple JIT optimizations +``` diff --git a/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md b/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md new file mode 100644 index 00000000..4be1b833 --- /dev/null +++ b/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md @@ -0,0 +1,85 @@ +--- +title: Run a Java application +--- + +CheerpJ can run a Java application in the browser with little to no modifications. This page will help you getting started with CheerpJ and running your first Java application in the browser. + +Java source code is not needed to use CheerpJ. If you are building your own application you should already have its `.jar` file(s). + +**To get started you will need:** + +- Your Java application file(s). You can also use this [TextDemo.jar](https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/TextDemoProject/TextDemo.jar) sample. +- An HTML file where your Java app will be wrapped +- A simple HTTP server to test your webpage locally + +## 1. Create a project directory + +Let's start by creating a project folder where all your files will be. Please copy your java and future HTML files here. + +```shell + +mkdir directory_name + +``` + +## 2. Create a basic HTML file + +Let's create a basic HTML file like the following example. Please notice the CheerpJ runtime environment has been integrated and initialized. In this example we are assuming your HTML file and your `.jar` files are under the project directory you just created. + +```html title="index.html" {6, 9-16} + + + + + CheerpJ test + + + + + + +``` + +Alternatively, if your application is not designed to be executed with the command `java -jar` you can replace `cheerpjRunJar()` for `cheerpjRunMain()` and pass your qualified class name as an argument. For example: + +```js +cheerpjRunMain( + "com.application.MyClassName", + "/app/my_application_archive.jar:/app/my_dependency_archive.jar", +); +``` + +## 3. Host your page + +You can now serve this web page on a simple HTTP server, such as the http-server utility. + +```shell +npm install http-server +http-server -p 8080 +``` + +> To test CheerpJ you must use a web server. Opening the `.html` page directly from the disk (for example, by double-clicking on it) is not supported. + +## What's going on? + +- CheerpJ loader is included from our cloud runtime as + ``. +- CheerpJ runtime environment is initialized by `cheerpjInit()`. +- `cheerpjCreateDisplay()` creates a graphical environment to contain all Java windows +- `cheerpjRunMain()` executes the `main` method of `ChangeThisToYourClassName`. The second parameter is a `:` separated list of `.jar` files where application classes can be found (the classpath). +- The `/app/` is a virtual file system mount point that reference the root of the web server this page is loaded from. + +## The result + +You will see the CheerpJ display on your browser with some loading messages before showing your application running. Depending on your application and the optimizations applied, this could take just a few seconds. + +## Further reading + +- [Runtime API](/cheerpj3/reference/Runtime-API) diff --git a/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx b/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx new file mode 100644 index 00000000..442fcba6 --- /dev/null +++ b/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx @@ -0,0 +1,101 @@ +--- +title: Run a Java applet +--- + +import LinkButton from "../../../../components/LinkButton.astro"; + +CheerpJ can run Java applets in the browser seamlessly. This page will help you getting started with CheerpJ for Java applets. + +**There are two different ways to run a Java Applet in the browser:** + +- [Running your own Java applet](/cheerpj3/getting-started/Java-applet#running-your-own-applet) using the CheerpJ runtime environment and the `` tag in your own webpage. +- [Running a public applet](/cheerpj3/getting-started/Java-applet#running-a-public-applet) using the [CheerpJ Applet Runner](https://chrome.google.com/webstore/detail/cheerpj-applet-runner/bbmolahhldcbngedljfadjlognfaaein) Chrome extension for applets integrated with the applet tag `` on public websites. + +## Running your own applet + +**You will need:** + +- Your applet file(s) +- An HTML file to wrap your applet +- A basic HTTP server to test locally + +### 1. Create a basic HTML file + +```html title="index.html" {6, 9-15, 17-22} + + + + + CheerpJ applet test + + + + + + + + +``` + +### 2. Host your page locally + +You can now serve this web page on a simple HTTP server, such as the http-server utility. + +```shell +npm install http-server +http-server -p 8080 +``` + +### What's going on? + +- The `cheerpjInit({enablePreciseAppletArchives:true});` initializes CheerpJ runtime environment indicating we are loading an applet. +- The `` tag specifies the code base in a similar manner as the now deprecated `` tag. + +> To avoid potential conflicts with native Java we recommend replacing the original HTML tag with `cheerpj-` prefixed version. You should use ``, `` or `` depending on the original tag. + +## Running a public applet + +### 1. Install the CheerpJ applet runner + +CheerpJ Applet Runner is available for Chrome and Edge. + +
+ + + + +
+ +### 2. Go to a website with an applet + +Visit a page with a Java applet, [such as this one](http://www.neilwallis.com/projects/java/water/index.php) and click on the CheerpJ Applet Runner icon in the toolbar and enable CheerpJ. + +![](/cheerpj2/assets/cheerpj_applet_demo.gif) + +## The result + +You will see the CheerpJ display on your browser with some loading messages before showing your applet running. Depending on your application and the optimizations applied, this could take just a few seconds. + +## Further reading + +- [Runtime API](/cheerpj3/reference/Runtime-API) diff --git a/src/content/docs/cheerpj3/03-getting-started/02-Java-library.md b/src/content/docs/cheerpj3/03-getting-started/02-Java-library.md new file mode 100644 index 00000000..ca2e70ab --- /dev/null +++ b/src/content/docs/cheerpj3/03-getting-started/02-Java-library.md @@ -0,0 +1,30 @@ +--- +title: Run a Java library +subtitle: Use Java classes in JavaScript +--- + +## 1. Include CheerpJ on your page + +```html + +``` + +## 2. Initialize CheerpJ and load your Java library + +```js +cheerpjInit(); +cheerpjRunJar("/app/library.jar"); +``` + +This will load `library.jar` from the root of your web server. + +## 3. Call Java from JavaScript + +```js +let obj = await cjNew("com.library.MyClass"); +await cjCall(obj, "myMethod"); +``` + +## Further reading + +- [API reference](/cheerpj3/reference/Runtime-API#calling-java-from-js) diff --git a/src/content/docs/cheerpj3/04-guides/File-System-support.md b/src/content/docs/cheerpj3/04-guides/File-System-support.md new file mode 100644 index 00000000..805745e7 --- /dev/null +++ b/src/content/docs/cheerpj3/04-guides/File-System-support.md @@ -0,0 +1,65 @@ +--- +title: File System support +--- + +CheerpJ provides full filesystem support for converted Java applications. + +Read only and read/write filesystems are exposed in Java and can be used to read, write and manipulate files as normally when running on a JVM. + +**Note**: CheerpJ provides access to a virtualized filesystem, which does not correspond to the local computer. Accessing local files from the browser it's forbidden for security reasons. + +## File Systems in CheerpJ + +CheerpJ implements three main filesystem concepts: + +1. A read-only, HTTP-based filesystem +2. A read/write, IndexedDB-based, persistent filesystem +3. A read-only, memory based filesystem + +CheerpJ filesystems are implemented as UNIX-style virtual filesystems with multiple mount points. The default mount points are defined as follows: + +| Mount | Description | +| --------- | --------------------------------------------------------------------------------------------------------- | +| `/app/` | An HTTP-based read-only filesystem, used to access JARs and data from your local server | +| `/files/` | An IndexedDB-based, persistent read-write file system | +| `/lt/` | Another HTTP-based read-only filesystem, pointing to the CheerpJ runtime | +| `/str/` | A read-only filesystem to easily share JavaScript Strings or binary data (an `Uint8Array`) with Java code | + +## `/app/` mount point + +The /app/ mount point corresponds to a virtual read-only, HTTP-based filesystem. `/app/` is used to access JAR files and data from your local server. + +The `/app/` directory is virtual, and only exists inside of CheerpJ. It is required to distinguish files from the local server from runtime files and files stored in the browser database. + +The `/app/` directory refers to the root of your web server. So, assuming that your web server is available at `http://127.0.0.1:8080/`, here are some example file mappings: + +- `/app/example.jar` → `http://127.0.0.1:8080/example.jar` +- `/app/subdirectory/example.txt` → `http://127.0.0.1:8080/subdirectory/example.txt` + +## `/files/` mount point + +The `/files/` mount point corresponds to a virtual read-write, IndexedDB-based filesystem. `/files/` is used to store persistent data on the browser client. + +The `/files/` directory is a virtual concept used by CheerpJ to store and refer to files. + +## `/str/` mount point + +The `/str/` mount point is a simple read-only filesystem that can be populated from JavaScript to share data with Java code. + +From JavaScript you can add files into the filesystem using the `cheerpjAddStringFile` API. Example: + +```js +cheerpjAddStringFile("/str/fileName.txt", "Some text in a JS String"); +``` + +You can access this data from Java, for example: + +```java +import java.io.FileReader; +... + +FileReader f = new FileReader("/str/fileName.txt") +... +``` + +The `cheerpjAddStringFile` API can be used with JavaScript `String`s or `Uint8Array`s. `Uint8Array`s may be useful to provide binary data to the Java application, for example a user selected file coming from an HTML5 `` tag. diff --git a/src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md b/src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md new file mode 100644 index 00000000..ce2280d6 --- /dev/null +++ b/src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md @@ -0,0 +1,57 @@ +--- +title: Implementing native methods +--- + +With CheerpJ, it is possible to implement Java 'native' methods (that would normally be implemented in C/C++ or other AOT-compiled language) in JavaScript, similarly to what would be done in regular Java using the Java Native Interface (JNI). + +## Java Native Methods + +Take as an example the following Java class + +```java title="SomeClass.java" +public class SomeClass { + public static void someStaticMethod() { + ... + } + public float someInstanceMethod() { + ... + } + public native int someNativeMethod(); +} +``` + +Java will search for the implementation of `someNativeMethod` using the JNI. + +When compiling this class with CheerpJ, a JavaScript implementation of this method will need to be provided. Implementing native Java methods in JavaScript can be useful to use browser functionalities that are not currently exposed at the Java level. + +## Java Native Methods in CheerpJ + +Implementing native methods is simply a matter of adding a JavaScript function in the global scope with a correctly mangled signature. + +Since this is a rather involved process, the `cheerpjfy.py` script provides functionality to simplify the process by using the `--stub-natives=destinationDir` command line option. + +Assume the previous class has been compiled and packaged in `some.jar`, to generate a directory tree for JS native code you can do: + +```shell +mkdir native/ +cheerpjfy.py --stub-natives=native/ some.jar +``` + +This will generate a tree of directories under the `native` folder, which will replicate the Java package structure. Each class with at least one native method will generate a `ClassName_native.js` stub file ready to be implemented. + +```js title= "Someclass_native.js" +function _CHEERPJ_COMPRESS(ZN9Someclass16someNativeMethodEVEI)(a0,p) +{ + /*instance*/ + debugger +} + +``` + +Once all have been implemented, native methods can be packaged with the compiled code using the following command: + +```shell +cheerpjfy.py --natives=native/ some.jar +``` + +CheerpJ uses a compression scheme to encode mangled signatures. The `CHEERPJ_COMPRESS` macro is used automatically by the `cheerpjfy.py --stub-natives=` command, but can also be used manually. For more information about macros visit [this page](/cheerpj3/reference/Command-Line-Options#--stub-nativesnativespath). diff --git a/src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md b/src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md new file mode 100644 index 00000000..e7669274 --- /dev/null +++ b/src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md @@ -0,0 +1,99 @@ +--- +title: Startup time optimization +--- + +This page is a collection of different steps to reduce the startup time of a Java application converted with CheerpJ. + +## Overview + +Traditionally, users had to have Java preinstalled on their computer in order to run Java applications and applets. CheerpJ converts Java to HTML5/JavaScript, allowing to run applications and applets on browser without users having to install any additional dependency on their computer. Similarly to their JVM counterparts, applications converted to JavaScript with CheerpJ require runtime components to be loaded during execution. In CheerpJ, runtime components are JavaScript modules that are loaded on demand, only if required. + +The CheerpJ runtime is highly optimised to minimise the total download size of an 'average' application, totalling 10-20MB of data for a typical download (as a point of comparison, the approximate size of the Java runtime installer is over 60MB). All downloaded components of CheerpJ are cached by the browser, which reduces the download time in subsequent executions of a same application. + +This page provides a list of recommendations to reduce the one-time download size, and the resulting application first startup time. + +## Gzip compression of JavaScript on server + +In our experience it is not uncommon to see that most of the loading time is spent downloading the main `jar.js` file for the application (i.e. not from the runtime). **It is critical that the Web server on which your application is deployed has gzip compression enabled for the application's JavaScript files**. + +If you are self-hosting the CheerpJ runtime (most likely you will not), please make sure to enable compression on these components as well. The CheerpJ cloud runtime has compression enabled by default. + +## Use ProGuard to remove unused code + +ProGuard is an industry standard open-source tool to optimize and obfuscate Java bytecode. ProGuard, by itself, can automatically trace the classes used from the application entry point and automatically remove unused classes, methods and field. This can enable a very significant reduction of download size and startup time, especially with applications using multiple third party libraries. + +Since Java allows reflection at runtime, ProGuard may end up removing code which is actually used, causing unexpected errors. To help in this scenario CheerpJ supports a special option: + +```js +cheerpjInit({ enableProguardTrace: true }); +``` + +When initialized with this option CheerpJ will keep track of the classes used at runtime, including classes which are accessed via reflection. Follow these steps to safely optimize an application using ProGuard. + +1. Build a single `uber-JAR` by merging the application and dependencies +2. Convert the new JAR to JS using `cheerpjfy.py` +3. Run the application using CheerpJ with the `enableProguardTrace:true` option +4. Fully test the application, making sure that all possible scenarios are executed and all needed classes are loaded +5. From the browser console call `cjGetProguardConfiguration()`, a ProGuard configuration file (`cheerpj.pro`) will be automatically generated and downloaded +6. Run `proguard` on the `uber-JAR` using the generated configuration file to generate a smaller JAR with only the needed classes. `proguard -dontwarn -injars uber.jar -outjars uber-stripped.jar -libraryjars ~/cheerpj_1.2/rt.jar @cheerpj.pro` +7. Convert this new JAR using `cheerpjfy.py` + +## Reduce the size of the JAR file + +`cheerpjfy.py` supports a command line option (`--pack-jar`) to generate a minimised JAR for deployment. + +This smaller JAR is stripped of all original Java bytecode and can no longer be used to run the application on the JVM. The JAR is however necessary for CheerpJ to support Java reflection. + +Usage example: + +```shell + +/cheerpj_2.3/cheerpjfy.py yourInput.jar --pack-jar yourOutput.jar + +``` + +> It is important to use the same name on your input and output `.jar` files for your application to work. This action will overwrite your original `.jar` file with the packed one. We recommend backing up your original files somewhere else to keep their state in case you need to use them again. + +To use this command you will require to have java installed on your machine. + +More details are available [here](/cheerpj3/reference/Command-Line-Options#pack-jarpackjar) + +## Preload resources + +CheerpJ cannot predict which runtime resources will be required by an arbitrary application. CheerpJ runtime resources are therefore loaded on demand, one after the other, depending on the requirements of the application at run time. + +To take advantage of parallel downloads, and reduce download and startup time of a specific application in production, CheerpJ allows to pre-specify a list of resources (CheerpJ runtime modules) to be loaded at startup. + +This list of resources is to be specified manually when starting the CheerpJ environment in an HTML page. We also provide a simple profiling tool to automatically record and output a list of used resources during the execution of an application. + +By combining the use of this profiler together with the preloader, one can highly optimise the initial download and startup time of a converted application. Taking advantage of this is a simple 2-step process: + +1. Run the application normally using CheerpJ. After the application is loaded, open the JavaScript console of the browser (e.g. Ctrl+Shift+I on many browsers), and type: + +```js +cjGetRuntimeResources(); +``` + +The result will look like this: + +```js +["/lts/file1", "/lt/file2"]; +``` + +If the output is not visible fully, you can use: + +```js +document.write(cjGetRuntimeResources()); +``` + +The JavaScript console may enclose the string between quotes (`"`), which you should ignore. See [here](/cheerpj3/reference/Runtime-API#cjgetruntimeresources) for more information. + +2. Modify the CheerpJ integration to enable preloading. You will only need to change the `cheerpjInit` call, to pass the `preloadResources` option. For example: + +```js +cheerpjInit({ preloadResources: ["/lts/file1", "/lt/file2"] }); +``` + +See [here](/cheerpj3/reference/Runtime-API#preloadresources) for more information. + +When preloading is enabled CheerpJ will be able to download multiple resources in parallel with the execution of the program. This will greatly improve loading time. diff --git a/src/content/docs/cheerpj3/04-guides/Using-web-workers.md b/src/content/docs/cheerpj3/04-guides/Using-web-workers.md new file mode 100644 index 00000000..02066254 --- /dev/null +++ b/src/content/docs/cheerpj3/04-guides/Using-web-workers.md @@ -0,0 +1,72 @@ +--- +title: Using Web Workers +--- + +## Using the JavaScript Web Workers API + +CheerpJ supports running Java code in the background using Web Workers. To use this functionality you need to include the `loader.js` script as usual (e.g. `https://cjrtnc.leaningtech.com/latest/loader.js`). The script exposes the APIs described in [JavaScript Web Worker API](/cheerpj3/reference/WebWorker-API#javascript-web-worker-api). You can use CheerpJ in the main thread at the same time. + +All code in a Worker runs in parallel and asynchronously with the main thread. All the methods below return standard JavaScript `Promise`s, and you can use `.then(...)`, `.catch(...)` and `async/await` with them. + +### Creating and initializing a CheerpJ worker + +The main entry point for CheerpJ workers is the `CheerpJWorker` JS interface. It is a normal JS object and it is possible to instantiate it multiple times. + +```js +var w = new CheerpJWorker(); +w.cheerpjInit().then(function (e) { + console.log("CheerpJWorker is ready"); +}); +``` + +This starts the WebWorker and initializes CheerpJ in that context. All workers need to be initialized in this way. As a general rule the `CheerpJWorker` exposes the same API as CheerpJ in the main thread. + +### Parameters and return values + +Web Workers do not share any memory with the main threads, and all interactions happen through messages. This imposes limitations on the type of data that can be passed around. + +| Data type | Limitations | +| -------------------------------------------- | ------------------------------------------- | +| byte/short/char/int/float/double | Fully supported in params and return values | +| byte[]/short[]/char[]/int[]/float[]/double[] | Fully supported in params and return values | +| JavaScript String | Supported in params, not return values | +| Any Java object | Not supported in params or return values | + +Java arrays can either come from another Java method or they can be generated from a JS TypedArray using [cjTypedArrayToJava](/cheerpj3/reference/Runtime-API#cjtypedarraytojava). + +It is possible to move Java arrays from the main thread and others `CheerpJWorker`s. Please note that Java arrays are not copied, but _transferred_ across contexts. This increases efficiency, but also means that the data is not available any more from the calling thread. If the data needs be preserved you must manually make a copy. + +Java Strings, being Java objects, cannot be passed or returned. But JavaScript strings can be used as parameters and will be converted to Java Strings directly in the WebWorker context. + +## Using the Java API for Web Workers + +CheerpJ exposes a custom API to access this feature directly from Java code. The API is equivalent in terms of capabilities. This API is blocking, so to actually take advantage of concurrency between the main thread and Web Workers it is necessary to use this API from a Java thread. + +The Java version of the API is also extended to support `long`s in parameters and returned values. Currently they are converted to native JS values when passed to Workers, so their range is limited to +/-2^52. + +See the reference for [Java Web Worker API](/cheerpj3/reference/WebWorker-API#java-web-worker-api) + +Example usage: + +```java title="WW.java" +import com.leaningtech.cheerpj.Worker; + +public class WW +{ + public static void main(String[] args) + { + Worker w = new Worker(); + w.runMain("Hello", ""); + } +} +``` + +To build the class you need to add `cheerpj-public.jar` to the classpath + +```shell +javac -cp cheerpj_install_dir/cheerpj-public.jar WW.java +``` + +## Further reading + +- [Web Worker APIs (reference)](/cheerpj3/reference/WebWorker-API) diff --git a/src/content/docs/cheerpj3/05-reference/02-Command-Line-Options.md b/src/content/docs/cheerpj3/05-reference/02-Command-Line-Options.md new file mode 100644 index 00000000..fa293689 --- /dev/null +++ b/src/content/docs/cheerpj3/05-reference/02-Command-Line-Options.md @@ -0,0 +1,103 @@ +--- +title: Command line options +--- + +The basic usage of the `cheerpjfy.py` build script is: + +```shell +./cheerpjfy.py application.jar +``` + +For more information about this script, see [AOT optimization](/cheerpj2/guides/AOT-optimization). + +### `--help` + +Shows all the command line options + +### `-v` + +Shows the CheerpJ version and the recommend `loader.js` to use in deployment. + +### `--split` + +Splits generated JS into smaller modules. + +### `--no-runtime` + +Do not automatically add the runtime to the class path. + +### `--natives=NATIVESPATH` + +Root of the native JS implementations for classes in this JAR file. +Assuming the `/natives` directory exists: + +```shell +cheerpjfy.py --natives=native/ some.jar +``` + +### `--deps=DEPSPATHS` + +List of `:` separated JARs that this JAR depends on. Please note that all the listed JAR paths should be either relative to the target JAR or absolute. + +```shell +cheerpjfy.py --deps dependency1.jar:dependency2.jar my_application_archive.jar +``` + +### `--work-dir=WORKDIRPATH` + +A directory where all the JARs are unpacked. This is useful to speed up multiple compilations of the same JARs and to select a different disk when not enough free space is available in the temporary directory. Keep in mind that the directory passed to the option must be manually created _before_ the command is run. + +### `--core-classes-list=CORECLASSESLIST` + +File containing a list of classes that should be in the core module. + +### `--strip-jar=STRIPJAR` + +Generates a stripped version of the input JAR with all code replaced by nops for improved compression + +### `--pack-jar=PACKJAR` + +Generate a packed version of the input JAR using the pack200 utility. Debug information and code are removed. +To use this command you will require to have java installed on your machine. + +```shell +cheerpjfy.py yourInput.jar --pack-jar yourOutput.jar +``` + +> This action will overwrite your original .jar file with the packed one when using the same filename (necessary for your app to work). We recommend backing up your original files somewhere else to keep their state in case you need to use them again. + +### `--stub-natives=NATIVESPATH` + +Generates stubs for all native methods from classes in this JAR. The parameter must be an existing directory, it will be populated with new JavaScript files for each class having native methods. + +```shell +mkdir native/ +cheerpjfy.py --stub-natives=native/ some.jar + +``` + +> **Note**: Existing files in the passed directory will be overwritten. + +CheerpJ uses a compression scheme to encode mangled signatures. The `CHEERPJ_COMPRESS` macro is used automatically by this command, but can also be used manually. + +| macro | Description | +| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | +| `CHEERPJ_COMPRESS` | Encode the argument in parenthesis following such scheme. | +| `CHEERPJ_SET_CLASS` | Set the current internal class for resolving fields when using `CHEERPJ_FIELD` and `CHEERPJ_STATIC_FIELD` macros. | +| `CHEERPJ_FIELD` and `CHEERPJ_STATIC_FIELD` | The compiler replaces this macro with the encoded field name, it assumes the current class has been set by `CHEERPJ_SET_CLASS`. | + +### `--pack-classes-list=PACKCLASSESLIST` + +File containing a list of classes that should be compacted to the beginning and end of JAR file + +### `--pack-strip-binaries` + +Drop all dll/so/jnilib files from the JAR + +### `--ignore-classes=IGNORECLASSES` + +List of ',' separated classes that should not be compiled. Example --ignore-classes com.a.b.ClassOne,org.c.d.ClassTwo + +### `-j NUMJOBS` + +Number of parallel compilation jobs diff --git a/src/content/docs/cheerpj3/05-reference/Runtime-API.md b/src/content/docs/cheerpj3/05-reference/Runtime-API.md new file mode 100644 index 00000000..2ef05f85 --- /dev/null +++ b/src/content/docs/cheerpj3/05-reference/Runtime-API.md @@ -0,0 +1,444 @@ +--- +title: Runtime API +--- + +CheerpJ exposes a simple JavaScript API to interact with a Java application converted to JavaScript. This API can be use to initialise CheerpJ, invoke Java methods, convert data and to enable/disable certain debugging features. + +## Runtime initialization + +### cheerpjInit + +`cheerpjInit(options)` + +`cheerpjInit` must be called once in the page to setup and initialise the CheerpJ runtime environment. `cheerpjInit` accepts an optional object argument which can be used to set options. + +This method is to be invoked as follows: + +```js +cheerpjInit({ option: "value" }); +``` + +All the supported options are described below. + +#### `clipboardMode` + +By default CheerpJ supports an internal clipboard which is local to the Java application and is not integrated with the system clipboard. To change this behaviour you can initialize CheerpJ in the following way: + +```js +cheerpjInit({ clipboardMode: "system" }); +``` + +In `system` mode CheerpJ will share the clipboard with the system. Browsers enforce serious limitations on how the system clipboard can be accessed. In practice it is generally accessible when the `Ctrl+C` and `Ctrl+V` shortcuts are used (`Cmd+C` and `Cmd+V` on MacOSX). Due to these limitations the UX when using `clipboardMode:"system"` is: + +- `Ctrl+C`/`Cmd+C`: the user has to press the shortcut twice to give CheerpJ access to the system clipboard. CheerpJ will block the execution while waiting for the second `Ctrl+C`. +- `Ctrl+V`/`Cmd+V`: this shortcut behaves normally, there is no difference with native execution. +- Menu based Copy/Paste: `Ctrl+C`/`Ctrl+V` are needed to access the clipboard. CheerpJ will block the execution while waiting the appropriate shortcut. + +Commercial users adopting this integration have so far reported that this change in UX is not a significant burden for users. Moreover, in the future we plan to add an additional clipboard mode to take advantage of a new permission-based browser API which is currently being standardized. This future mode will provide native like user experience in all cases. + +#### `disableErrorReporting` + +CheerpJ automatically reports errors at runtime. Setting this option to `true` disables this system. + +Example: + +```js +cheerpjInit({ disableErrorReporting: true }); +``` + +#### `disableLoadTimeReporting` + +CheerpJ automatically get data about loading time. Setting this option to `true` disables this system. + +Example: + +```js +cheerpjInit({ disableLoadTimeReporting: true }); +``` + +#### `enableInputMethods` + +When this option is set to `true` CheerpJ will be able to receive text input from the input method framework of the platform. This is useful to support text input for languages such as Chinese, Japanese and Korean. + +```js +cheerpjInit({ enableInputMethods: true }); +``` + +#### `enableProguardTrace` + +When this option is set to `true` CheerpJ will automatically keep track of the classes actually used at runtime. Moreover, it will also keep track of classes which are accessed by reflection. After the application has been fully tested you can use the `cjGetProguardConfiguration()` function from the browser console to download a ProGuard configuration file (`cheerpj.pro`) that you can directly use with ProGuard to remove unneeded classes, methods and fields from the application, greatly reducing the download size and startup time. + +```js +cheerpjInit({ enableProguardTrace: true }); +``` + +#### `javaProperties` + +An array of Java properties in the form `"key=value"`. They will be defined on the System object (System properties). This option should be used if command line arguments in the form `-Dkey=value` are required when using native Java. + +Example usage: + +```js +cheerpjInit({ javaProperties: ["prop1=value1", "prop2=value2"] }); +``` + +#### `listener` + +An object containing callbacks that CheerpJ will use to report various information to the user. Currently only the `jsLoadReason` and `preloadProgress` callbacks are supported. + +```js +cheerpjInit({ listener: cheerpjListener }); +``` + +#### `jsLoadReason` + +> **Warning:** enabling this listener may have significant performance impact and should not be used in production. + +For each new .jar.js to be loaded, CheerpJ will call this function. This can be useful to debug the reason why some parts of the runtime are loaded, if unexpected. + +**Parameters:** + +- `scriptName`: The name of the JS file being loaded +- `directReason`: A CheerpJ uncompressed and mangled symbol. The method that most directly caused the load. This might not be very useful since it will most often be a `java.lang.ClassLoader` method. Can be `(Internal)` if it could not be detected. +- `userReason`: A CheerpJ uncompressed and mangled symbol. The last non-runtime method in the stack before the loading. This should be more useful in understanding the user code that introduces the dependency. Can be `(Internal)` if it could not be detected. + +Example: + +```js +var cheerpjListener = {jsLoadReason:function(scriptName, directReason, userReason){ ... }}; +cheerpjInit({listener:cheerpjListener}); +``` + +#### `preloadProgress` + +This listener may be used in combination with [`preloadResources`](#preloadresources) to monitor the loading of an application. The information provided is useful, for example, to display a loading/progress bar. + +**Parameters:** + +- `loadedFiles`: How many files have been preloaded so far +- `totalFiles`: How many files needs to be preloaded in total. This number may increment during the loading phase. CheerpJ has a prediction mechanism and may preload additional resources depending on application behaviour + +Example: + +```js +function showPreloadProgress(loadedFiles, totalFiles) { + console.log("Percentage loaded " + (loadedFiles * 100) / totalFiles); +} +var cheerpjListener = { preloadProgress: showPreloadProgress }; +cheerpjInit({ listener: cheerpjListener }); +``` + +#### `logCanvasUpdates` + +When set to `true`, it enables logs on the console about the display areas which are being updated. Useful to debug overdrawing. + +Example: + +```js +cheerpjInit({ logCanvasUpdates: true }); +``` + +#### `overrideShortcuts` + +Some applications needs to internally handle keyboard shortcuts which are also used by the browser, for example Ctrl+F. Most users expect the standard browser behavior for these shortcuts and CheerpJ does not, by default, override them in any way. + +A CheerpJ-converted application can take control of additional shortcuts by providing a callback function as the `overrideShortcuts` options of `cheerpjInit`. This callback receives the `KeyboardEvent` coming from the browser and should return `true` if the default browser behaviour should be prevented. + +Whenever possible we recommend _not_ to use browser reserved shortcuts, to maintain a consistent user experience. In any case, the following limitations apply: + +- Some shortcuts (Ctrl+T, Ctrl+N, Ctrl+W) are reserved by the browser and never received by the page itself. These _cannot_ be overridden +- Overriding (Ctrl+C/Ctrl+V) will prevent `clipboardMode:"system"` from working correctly. + +Example: + +```js +cheerpjInit({ + overrideShortcuts: function (e) { + // Let Java handle Ctrl+F + if (e.ctrlKey && e.keyCode == 70) return true; + return false; + }, +}); +``` + +#### `preloadResources` + +By using `preloadResources`, you can provide CheerpJ with a list of runtime files which you know in advance will be required for the specific application. The list should be given as a JavaScript array of strings. + +Example: + +```js +cheerpjInit({ preloadResources: ["/lts/file1", "/lt/file2"] }); +``` + +See also [cjGetRuntimeResources](#cjGetRuntimeResources). + +#### `status` + +This option determines the level of verbosity of CheerpJ in reporting status updates. + +- `"default"`: Enables status reporting during initialization and short-lived "Loading..." messages every time new runtime code is being downloaded. +- `"splash"`: Enabled status reporting only during initialization. There will be no feedback after the first window is shown on screen. +- `"none"`: Disable all status reporting. + +Example: + +```js +cheerpjInit({ status: "splash" }); +``` + +#### `appletParamFilter` + +Some applications may need to have some parameter modified before getting those inside the applet. + +Example: + +```js +cheerpjInit({ + appletParamFilter: function (name, value) { + if (name === "httpServer") return value.replace("http", "https"); + return value; + }, +}); +``` + +#### `enablePreciseAppletArchives` + +Boolean option which makes the classloader behavior similar to the native Java plugin. For better performance it is recommended to upgrade to CheerpJ 3. + +Example: + +```js +cheerpjInit({ enablePreciseAppletArchives: true }); +``` + +## Graphics + +### cheerpjCreateDisplay + +`cheerpjCreateDisplay(w, h, oldElem, useLoadingAnimation)` + +This method will create the HTML element that will contain all Java windows. It is only required to run graphical applications. + +```js +cheerpjCreateDisplay(width, height, /*optional*/ parent); +``` + +The `width` and `height` parameter represent the display area size in CSS pixels. It is also possible to specify a parent element if required, if a parent element is not specified the display area will be appended to the page `body` element. If a parent is specified it is also possible to pass `-1` to both `width` and `height`, in that case the size will correspond to the parent size and it will also change dynamically if the parent is modified by either CSS changes or browser window resize. + +## Running applications and `.jar`(s) + +**Warning**: CheerpJ does not support opening the HTML pages directly from disk. If the URL in your browser starts with `file://`, CheerpJ will not run. You _must_ use a local Web server. + +### cheerpjRunMain + +`cheerpjRunMain(className, classPath, ...)` + +The most common way of starting an application is to use the `cheerpjRunMain` API, which lets you execute the static main method of a Java class in the classpath. + +```js +cheerpjRunMain( + "fully.qualified.class.name", + "/app/my_application_archive.jar:/app/my_dependency_archive.jar", + arg1, + arg2, +); +``` + +### cheerpjRunJar + +`cheerpjRunJar(jarName, ...)` + +Alternatively, if your JAR is designed to be executed with `java -jar my_application_archive.jar`, you can use this simpler API. + +```js +cheerpjRunJar("/app/my_application_archive.jar", arg1, arg2); +``` + +### cheerpjRunJarWithClasspath + +`cheerpjRunJarWithClasspath(jarName, classPath, ...)` + +Optionally, if your JAR also need additional dependencies, you can use. + +```js +cheerpjRunJarWithClasspath( + "/app/my_application_archive.jar", + "/app/my_dependency_archive.jar", + arg1, + arg2, +); +``` + +In all cases the arguments should be JavaScript Strings. + +## Calling Java from JS + +These functions make it possible to conveniently call Java code from JS. Java code is always run asynchronously, so the returned values are `Promise`s. See below for details. + +Both `cjNew` and `cjCall` return standard JavaScript `Promise`s. They can be transparently used in other calls to `cjNew/cjCall` or you can use `.then(...)` and `.catch(...)` to access the resulting value and handle errors. It is also possible to use `async/await` (either natively or through a JS transpiler) to write sync-like code using `cjNew/cjCall` as async primitives. + +### cjCall + +`cjCall(objOrClassNameOrInvoker, methodName, ...)` + +Call static Java methods from JavaScript. + +Example 1: + +```js +/* Equivalent Java code: int returnVal = com.my.Java.package.myClass.method(argument1, argument2, argument3); */ +var returnVal = cjCall( + "com.my.Java.package.myClass", + "method", + argument1, + argument2, + argument3, +); +``` + +Example 2: + +```js +/* Equivalent Java code: int returnVal = object.method(argument1, argument2, argument3); */ +var returnVal = cjCall(object, "method", argument1, argument2, argument3); +``` + +### cjNew + +`cjNew(classNameOrInvoker, ...)` + +Calls Java constructors from JavaScript. + +Example: + +```js +/* Equivalent Java code: myClass object = com.my.Java.package.myClass(argument1) */ +var object = cjNew("com.my.Java.package.myClass", argument1); +``` + +### cjResolveCall / cjResolveNew + +`cjResolveCall(className, methodName, types)` + +`cjResolveNew(className, types)` + +Using `cjCall/cjNew` is convenient, but under the hood Java reflection APIs are used, which may have a significant performance impact if used heavily. If you plan to use `cjCall/cjNew` many times it is convenient to go through reflection APIs only once by using the `cjResolveCall/cjResolveNew` API. + +Examples: + +```js +var promise1 = cjResolveCall("com.something.ClassName", "methodName", [ + "java.lang.String", + "int", + "double", +]); +var promise2 = cjResolveNew("com.something.ClassName", [ + "java.lang.String", + "int", + "double", +]); +``` + +`cjResolveCall` supports both instance and static methods of classes. The third parameter (for both APIs) is an array of Java types and it is only required if the methodName is not unique in the class (i.e. it is overloaded). The third parameter can be omitted (be null) if the method name (or constructor) is unique. For example: + +```js +var promise = cjResolveCall( + "com.something.ClassName", + "uniqueMethodName", + null, +); +``` + +`cjResolveCall/cjResolveNew` are async, like most of CheerpJ's APIs. To get the actual result you can either use .then() or the async/await functionality of JS. For example: + +```js +var resolvedMethod = await cjResolveCall("com.something.ClassName", "uniqueMethodName", null); +cjResolveCall("com.something.ClassName", "uniqueMethodName", null).then(function(resolvedMethod) { ... }); +``` + +The returned value is an opaque handle to the desired method (or constructor), which can now be called an arbitrary number of times without going through Java reflection. + +```js +cjCall(resolvedMethod, arg1, arg2, arg3); +cjNew(resolvedConstructor, arg1, arg2, arg3); +``` + +Alternatively resolvedMethod can also be used _directly as a function_, for example: + +```js +resolvedMethod(arg1, arg2, arg3); +``` + +Please note that this convenient form can unfortunately only be used on the main thread, not on Workers. For more information see [WebWorker API](/cheerpj3/reference/WebWorker-API) + +## Data conversion + +### cjStringJavaToJs + +`cjStringJavaToJs(javaString)` + +```js +var jsString = cjStringJavaToJs(javaString); +``` + +This converts a Java string into a JavaScript string. This operation implies a copy. + +### cjStringJsToJava + +`cjStringJsToJava(jsString)` + +```java +String javaString = cjStringJStoJava(jsString); +``` + +This converts a JavaScript string into a Java string. This operations also implies a copy. String parameters passed to `cheerpjRunMain`, `cjCall` and `cjNew` are automatically converted so it is not necessary to use this methods in that case. + +### cjTypedArrayToJava + +`cjTypedArrayToJava(array)` + +Converts a TypedArray to a Java compatible primitive array. This operation implies a copy. Data is converted as follows: + +| Typed Array | Java array | +| ------------ | ---------- | +| Int8Array | byte[] | +| Uint8Array | byte[] | +| Int16Array | short[] | +| Uint16Array | char[] | +| Int32Array | int[] | +| Uint32Array | int[] | +| Float32Array | float[] | +| Float64Array | double[] | + +## Preloading + +### cjGetRuntimeResources + +Returns a JavaScript string representing the data that should be passed to [preloadResources](#preloadResources). It is a list of files that have been loaded from the runtime up to the time this function is called. + +## Filesystem + +### cjFileBlob + +`cjFileBlob(fileName)` + +Used to download files from the CheerpJ filesystem. It returns a promise that eventually resolve to a Blob object, which can be downloaded with standard HTML5 techniques. + +### cheerpjAddStringFile + +`cheerpjAddStringFile(fileName, str)` + +Used to add files into the `/str/` mount point filesystem. + +Example: + +```js +cheerpjAddStringFile("/str/fileName.txt", "Some text in a JS String"); +``` + +## Tracing + +### cjGetProguardConfiguration + +To be used on the browser console to download a ProGuard configuration file (`cheerpj.pro`). See [enableProguardTrace](/cheerpj3/reference/Runtime-API#enableproguardtrace). diff --git a/src/content/docs/cheerpj3/05-reference/WebWorker-API.md b/src/content/docs/cheerpj3/05-reference/WebWorker-API.md new file mode 100644 index 00000000..0b7d8783 --- /dev/null +++ b/src/content/docs/cheerpj3/05-reference/WebWorker-API.md @@ -0,0 +1,69 @@ +--- +title: Web Worker APIs +--- + +## JavaScript Web Worker API + +### CheerpJWorker + +The main entry point for CheerpJ workers is the `CheerpJWorker` JS interface. It is a normal JS object and it is possible to instantiate it multiple times. + +```js +var w = new CheerpJWorker(); +w.cheerpjInit().then(function (e) { + console.log("CheerpJWorker is ready"); +}); +``` + +For more information visit the [Using Web Workers](/cheerpj3/guides/Using-web-workers) guide. + +### CheerpJWorker.cheerpjRunMain + +`cheerpjRunMain(className, classPath, ...)` + +Runs a Java main method in the WebWorker context + +```js +w.cheerpjRunMain("ClassName", classPath, arg1, arg2).then(...) +``` + +### CheerpJWorker.cjCall + +`cjCall(objOrClassNameOrInvoker, methodName, ...)` + +Executes a static Java method in the WebWorker content + +```js +w.cjCall("ClassName", "methodName", arg1, arg2).then(...) +``` + +### CheerpJWorker.cjResolveCall + +`cjResolveCall(className, methodName, types)` + +Uses Java reflection to resolve the method and returns an opaque handle to it. This handle can then be used multiple times without using Java reflection again. + +```js +w.cjResolveCall("ClassName", "methodName", null).then( // or array of parameter types if methodName is not unique + function(resolvedMethod) { + w.cjCall(resolvedMethod, arg1, arg2); + ... + } +); +``` + +### CheerpJWorker.cjFileBlob + +`cjFileBlob(fileName)` + +Used to download files from the CheerpJ filesystem. It returns a promise that eventually resolve to a Blob object, which can be downloaded with standard HTML5 techniques. + +### CheerpJWorkercheerpj.AddStringFile + +`AddStringFile(fileName, str)` + +Used to add files into the `/str/` mount point filesystem. + +## Further reading + +- [Using Web Workers (guide)](/cheerpj3/guides/Using-web-workers) diff --git a/src/content/docs/cheerpj3/index.mdx b/src/content/docs/cheerpj3/index.mdx index 13f1f292..f91520f7 100644 --- a/src/content/docs/cheerpj3/index.mdx +++ b/src/content/docs/cheerpj3/index.mdx @@ -3,11 +3,72 @@ title: CheerpJ subtitle: JVM replacement for the browser --- -import BlogPostCard from "@/components/BlogPostCard.astro"; import LatestBlogPostPill from "@/components/LatestBlogPostPill.astro"; -**Coming soon!** +CheerpJ is a **drop-in replacement** for the JVM, and is compatible with 100% of Java 8, including Swing, reflection and dynamic class loading. - +![](/cheerpj2/assets/cheerpj_visual_2.png) + +With CheerpJ, you can: + +- Run existing **Java applications** in the browser with no changes +- Include **Java applets** in webpages without legacy plugins +- Migrate **Java Web Start / JNLP** applications to work on modern systems +- Use Java libraries in JavaScript/TypeScript seamlessly + +## Getting started + +Know what you're building? Jump straight to the relevant tutorial: + + + +## What is CheerpJ? + +**CheerpJ is constituted of two components:** + +1. The CheerpJ runtime library, a full Java SE runtime in WebAssembly and JavaScript. The CheerpJ runtime is cloud-hosted and accessed by the community free of charge for non-commercial purposes only. For self-hosting and commercial please visit our [licensing page](https://cheerpj.com/licensing/). +2. The CheerpJ on-the-fly Java-to-JavaScript compiler, a reduced JavaScript version of the CheerpJ compiler that can be distributed with applications compiled with CheerpJ to enable dynamic features of Java such as reflection. + +## What is unique about CheerpJ? + +1. CheerpJ can handle 100% of Java 8, including Swing, reflection and dynamic class loading with no manual intervention on the code. +2. CheerpJ works directly on Java bytecode, and does not require access to the Java source code. +3. CheerpJ comes with a full Java SE runtime, inclusive of Swing/AWT. It supports audio, printing, and any other Java SE features. The runtime supports WebAssembly for optimal performance and size. +4. The JavaScript code generated by CheerpJ is highly optimised and garbage-collectible. +5. CheerpJ enables bidirectional Java-JavaScript interoperability. JavaScript libraries, as well as the DOM, can be called and manipulated from Java. Converted Java modules can be invoked from JavaScript. +6. CheerpJ supports Java multi-threading. In addition, it allows to create concurrent applications by using WebWorkers. + +## Licensing + +CheerpJ is free for technical evaluation and non-commercial use. See [licensing](https://cheerpj.com/licensing/) for details. + +## Demos + +Several demos of CheerpJ can be found [here](https://leaningtech.com/demo/). + +## Feedback + +[Report issues on GitHub](https://github.com/leaningtech/cheerpj-meta/issues) + +[Join the Discord server](https://discord.leaningtech.com/) From 25316ce9bfe477ccb34481cd500b4c745bfa7133 Mon Sep 17 00:00:00 2001 From: Alex Bates Date: Fri, 29 Sep 2023 17:28:17 +0100 Subject: [PATCH 02/33] remove mention of cheerpjify.py, update JNI guide, use type=module --- src/content/docs/cheerpj3/00-faq.md | 48 ++------ .../03-getting-started/00-Java-app.md | 11 +- .../03-getting-started/01-Java-applet.mdx | 7 +- .../03-getting-started/02-Java-library.md | 9 +- ...nting-Java-native-methods-in-JavaScript.md | 61 +++-------- .../04-guides/Startup-time-optimization.md | 20 ---- .../05-reference/02-Command-Line-Options.md | 103 ------------------ src/content/docs/cheerpj3/index.mdx | 10 +- 8 files changed, 44 insertions(+), 225 deletions(-) delete mode 100644 src/content/docs/cheerpj3/05-reference/02-Command-Line-Options.md diff --git a/src/content/docs/cheerpj3/00-faq.md b/src/content/docs/cheerpj3/00-faq.md index 8681d7d1..7b4cf0e6 100644 --- a/src/content/docs/cheerpj3/00-faq.md +++ b/src/content/docs/cheerpj3/00-faq.md @@ -6,14 +6,14 @@ title: FAQ CheerpJ is a solution for converting unmodified Java client applications into browser-based HTML5/JavaScript web applications. CheerpJ consists of a full Java runtime environment in JavaScript, and of a on-the-fly compiler for dynamic class generation, to be deployed alongside the application. -## What does the CheerpJ compiler do? - -The CheerpJ compiler, based on LLVM/Clang, as well as on parts of [Cheerp](https://github.com/leaningtech/cheerp-meta), converts Java bytecode into JavaScript, without requiring the Java source. CheerpJ can be invoked on whole Java archives (.jar) or on single .class files. - ## What parts of the Java SE runtime are supported? The CheerpJ runtime environment is a full Java SE runtime in JavaScript. Differently from other technologies which provide a partial re-implementation written manually in JavaScript, we opted to convert the entire OpenJDK Java SE runtime to JavaScript using CheerpJ. The CheerpJ runtime is constituted of both JavaScript files and .jar archives. All CheerpJ runtime components are dynamically downloaded on demand by the application to minimise total download size. The CheerpJ runtime library is hosted by us on a dedicated CDN-backed domain, and we invite users to link to it in order to take advantage of caching and cross-application resource sharing. +## Can I self-host the CheerpJ runtime? + +Please [contact us](https://cheerpj.com/contact/) to discuss self-hosting CheerpJ and its runtime on your infrastructure. + ## Can I use CheerpJ to convert my legacy Java application? I have no longer access to the source code. Yes, you can convert any Java SE application with CheerpJ without touching the source code. You only need all the .jar archives of your application. @@ -26,43 +26,19 @@ Yes. Java methods can be exposed to JavaScript with an asynchronous interface. A Yes, CheerpJ allows you to interoperate with any JavaScript or browser API. -## How does CheerpJ support reflection? - -In order to support reflection, CheerpJ, similarly to a JVM, utilizes the metadata available in the original .jar file. A converted application, to be deployed on a web server, comprises both the converted .jar.js JavaScript files and the .jar archives. After having converted a .jar archive, it is possible to remove all the bytecode from them prior to deployment, in order to minimize download time (we provide a simple tool to do so). The combined size of the pruned .jar archive and the output JavaScript, after compression, is comparable to the original .jar. - -Optionally, .jar archives can be split into multiple segments (size to be defined at compile time) before being deployed. The application will only load the required segments at run time, thus further reducing download time. - -## How does CheerpJ support dynamic class generation? - -One component of CheerpJ is the CheerpJ on-the-fly compiler (cheerpJ.js), a minimalistic Java-bytecode-to-JavaScript compiler written in C++ and compiled to JavaScript. CheerpJ.js needs to be distributed alongside any converted Java application that makes use of dynamic constructs such as proxy classes, which get compiled on the fly at run time directly on the browser. - -## What is the size of the output of CheerpJ - -The combined size of the .jar to be served (pruned of its bytecode) and of the resulting JavaScript is similar to that of the original .jar archive. Anecdotally, an overhead of 20% seems to be the average. +## Does CheerpJ support reflection? -## The size of the output is too big! Why doesn't CheerpJ remove "dead code"? +Yes. -In Java there is no "dead code". Java supports reflection, so all code and classes can be potentially used at runtime. For this reason CheerpJ cannot automatically remove any code. +## Does CheerpJ support dynamic class generation? -This said, depending on the application, it is often possible to remove a lot of code using ProGuard: an industry standard open source tool. CheerpJ provides support to automatically generate a ProGuard configuration file to make sure that classes used via reflection are not removed. For more information see: [here](/cheerpj3/guides/Startup-time-optimization#use-proguard-to-remove-unused-code) - -## Can JavaScript code produced by Cheerp be plugged into Node.js? - -Yes, it should. However, this has not been one of our areas of focus so far. +Yes. ## When compiling my application I see the message `Failure compiling MyFile.class`, but cheerpjfy continues to execute with no errors This means that it was not possible to use the new codegen. CheerpJ will use, for this class, the legacy codegen. This might happen for multiple classes in the same .jar, -## My Java application needs to get data over the network, but I only get `SocketException`s - -In the browser environment it is not possible to use sockets to connect to arbitrary ports. As a special exception CheerpJ provides a custom HTTP/HTTPS handler (based on XHR) that can be used to get data over HTTP and use REST APIs. To enable this handler please set the property `java.protocol.handler.pkgs=com.leaningtech.handlers` during the `cheerpjInit` call, for example: - -`cheerpjInit({javaProperties:["java.protocol.handler.pkgs=com.leaningtech.handlers"]});` - -Please note that when using CheerpJ to run applets the custom handlers are enabled by default. - -## When I run an application compiled with CheerpJ I see 404 errors in the browser console. What's going on? +## When I run CheerpJ I see 404/403 errors in the browser console. What's going on? Ignore those errors. CheerpJ provides a filesystem implementation on top of HTTP. In this context it is absolutely ok for some files to be missing. CheerpJ will correctly interpret 404 errors as a file not found condition. @@ -83,12 +59,6 @@ The cross origin message you see happens as part of our automatic bug reporting Not yet. The main problem is that RuneScape requires low level network connections primitives (sockets) which are not provided by browsers at this time due to security concerns. In the future we might provide a paid add-on to the CheerpJ Applet Runner extension to support this use case via tunneling. -## How can I use CheerpJ to generate WebAssembly code instead of JavaScript? - -CheerpJ cannot be used to generate WebAssembly code at the moment. - -CheerpJ uses WebAssembly internally for some components of the runtime, but Java bytecode can only be compiled to JavaScript at this time since WebAssembly currently is not an efficient target for Java. CheerpJ will support WebAssembly output when the platform matures. - ## What is the status of CheerpJ? CheerpJ is actively developed by [Leaning Technologies Ltd](https://leaningtech.com), a British-Dutch company focused on compile-to-JavaScript and compile-to-WebAssembly solutions. diff --git a/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md b/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md index 4be1b833..e8a0f0a9 100644 --- a/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md +++ b/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md @@ -35,13 +35,10 @@ Let's create a basic HTML file like the following example. Please notice the Che - diff --git a/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx b/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx index 442fcba6..c1b5cdb9 100644 --- a/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx +++ b/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx @@ -38,11 +38,8 @@ CheerpJ can run Java applets in the browser seamlessly. This page will help you >
- ``` diff --git a/src/content/docs/cheerpj3/03-getting-started/02-Java-library.md b/src/content/docs/cheerpj3/03-getting-started/02-Java-library.md index ca2e70ab..771a78ad 100644 --- a/src/content/docs/cheerpj3/03-getting-started/02-Java-library.md +++ b/src/content/docs/cheerpj3/03-getting-started/02-Java-library.md @@ -12,8 +12,8 @@ subtitle: Use Java classes in JavaScript ## 2. Initialize CheerpJ and load your Java library ```js -cheerpjInit(); -cheerpjRunJar("/app/library.jar"); +await cheerpjInit(); +const cj = await cheerpjRunLibrary("/app/library.jar"); ``` This will load `library.jar` from the root of your web server. @@ -21,8 +21,9 @@ This will load `library.jar` from the root of your web server. ## 3. Call Java from JavaScript ```js -let obj = await cjNew("com.library.MyClass"); -await cjCall(obj, "myMethod"); +const MyClass = await cj.com.library.MyClass; +const obj = await new MyClass(); +await obj.myMethod(); ``` ## Further reading diff --git a/src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md b/src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md index ce2280d6..e84599a8 100644 --- a/src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md +++ b/src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md @@ -1,57 +1,32 @@ --- title: Implementing native methods +subtitle: Java Native Interface (JNI) with CheerpJ --- With CheerpJ, it is possible to implement Java 'native' methods (that would normally be implemented in C/C++ or other AOT-compiled language) in JavaScript, similarly to what would be done in regular Java using the Java Native Interface (JNI). -## Java Native Methods +As an example, consider the following Java class: -Take as an example the following Java class - -```java title="SomeClass.java" -public class SomeClass { - public static void someStaticMethod() { - ... - } - public float someInstanceMethod() { - ... - } - public native int someNativeMethod(); +```java title="TestClass.java" +public class TestClass { + public native void alert(String str); } ``` -Java will search for the implementation of `someNativeMethod` using the JNI. - -When compiling this class with CheerpJ, a JavaScript implementation of this method will need to be provided. Implementing native Java methods in JavaScript can be useful to use browser functionalities that are not currently exposed at the Java level. - -## Java Native Methods in CheerpJ - -Implementing native methods is simply a matter of adding a JavaScript function in the global scope with a correctly mangled signature. +To provide an implementation of `someNativeMethod` in JavaScript, pass it to the `cheerpjInit` function as a property of the `natives` object: -Since this is a rather involved process, the `cheerpjfy.py` script provides functionality to simplify the process by using the `--stub-natives=destinationDir` command line option. - -Assume the previous class has been compiled and packaged in `some.jar`, to generate a directory tree for JS native code you can do: - -```shell -mkdir native/ -cheerpjfy.py --stub-natives=native/ some.jar +```js +cheerpjInit({ + natives: { + Java_TestClass_alert(lib, str) { + alert(str); + }, + }, +}); ``` -This will generate a tree of directories under the `native` folder, which will replicate the Java package structure. Each class with at least one native method will generate a `ClassName_native.js` stub file ready to be implemented. - -```js title= "Someclass_native.js" -function _CHEERPJ_COMPRESS(ZN9Someclass16someNativeMethodEVEI)(a0,p) -{ - /*instance*/ - debugger -} - -``` - -Once all have been implemented, native methods can be packaged with the compiled code using the following command: - -```shell -cheerpjfy.py --natives=native/ some.jar -``` +> [!todo] TODO +> Explanation of lib parameter, also consider calling it env to match native JNI -CheerpJ uses a compression scheme to encode mangled signatures. The `CHEERPJ_COMPRESS` macro is used automatically by the `cheerpjfy.py --stub-natives=` command, but can also be used manually. For more information about macros visit [this page](/cheerpj3/reference/Command-Line-Options#--stub-nativesnativespath). +> [!todo] TODO +> Explanation of how method names are resolved ([it's not the same as native JNI](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#resolving_native_method_names)) diff --git a/src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md b/src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md index e7669274..9e4d0bdd 100644 --- a/src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md +++ b/src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md @@ -38,26 +38,6 @@ When initialized with this option CheerpJ will keep track of the classes used at 6. Run `proguard` on the `uber-JAR` using the generated configuration file to generate a smaller JAR with only the needed classes. `proguard -dontwarn -injars uber.jar -outjars uber-stripped.jar -libraryjars ~/cheerpj_1.2/rt.jar @cheerpj.pro` 7. Convert this new JAR using `cheerpjfy.py` -## Reduce the size of the JAR file - -`cheerpjfy.py` supports a command line option (`--pack-jar`) to generate a minimised JAR for deployment. - -This smaller JAR is stripped of all original Java bytecode and can no longer be used to run the application on the JVM. The JAR is however necessary for CheerpJ to support Java reflection. - -Usage example: - -```shell - -/cheerpj_2.3/cheerpjfy.py yourInput.jar --pack-jar yourOutput.jar - -``` - -> It is important to use the same name on your input and output `.jar` files for your application to work. This action will overwrite your original `.jar` file with the packed one. We recommend backing up your original files somewhere else to keep their state in case you need to use them again. - -To use this command you will require to have java installed on your machine. - -More details are available [here](/cheerpj3/reference/Command-Line-Options#pack-jarpackjar) - ## Preload resources CheerpJ cannot predict which runtime resources will be required by an arbitrary application. CheerpJ runtime resources are therefore loaded on demand, one after the other, depending on the requirements of the application at run time. diff --git a/src/content/docs/cheerpj3/05-reference/02-Command-Line-Options.md b/src/content/docs/cheerpj3/05-reference/02-Command-Line-Options.md deleted file mode 100644 index fa293689..00000000 --- a/src/content/docs/cheerpj3/05-reference/02-Command-Line-Options.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Command line options ---- - -The basic usage of the `cheerpjfy.py` build script is: - -```shell -./cheerpjfy.py application.jar -``` - -For more information about this script, see [AOT optimization](/cheerpj2/guides/AOT-optimization). - -### `--help` - -Shows all the command line options - -### `-v` - -Shows the CheerpJ version and the recommend `loader.js` to use in deployment. - -### `--split` - -Splits generated JS into smaller modules. - -### `--no-runtime` - -Do not automatically add the runtime to the class path. - -### `--natives=NATIVESPATH` - -Root of the native JS implementations for classes in this JAR file. -Assuming the `/natives` directory exists: - -```shell -cheerpjfy.py --natives=native/ some.jar -``` - -### `--deps=DEPSPATHS` - -List of `:` separated JARs that this JAR depends on. Please note that all the listed JAR paths should be either relative to the target JAR or absolute. - -```shell -cheerpjfy.py --deps dependency1.jar:dependency2.jar my_application_archive.jar -``` - -### `--work-dir=WORKDIRPATH` - -A directory where all the JARs are unpacked. This is useful to speed up multiple compilations of the same JARs and to select a different disk when not enough free space is available in the temporary directory. Keep in mind that the directory passed to the option must be manually created _before_ the command is run. - -### `--core-classes-list=CORECLASSESLIST` - -File containing a list of classes that should be in the core module. - -### `--strip-jar=STRIPJAR` - -Generates a stripped version of the input JAR with all code replaced by nops for improved compression - -### `--pack-jar=PACKJAR` - -Generate a packed version of the input JAR using the pack200 utility. Debug information and code are removed. -To use this command you will require to have java installed on your machine. - -```shell -cheerpjfy.py yourInput.jar --pack-jar yourOutput.jar -``` - -> This action will overwrite your original .jar file with the packed one when using the same filename (necessary for your app to work). We recommend backing up your original files somewhere else to keep their state in case you need to use them again. - -### `--stub-natives=NATIVESPATH` - -Generates stubs for all native methods from classes in this JAR. The parameter must be an existing directory, it will be populated with new JavaScript files for each class having native methods. - -```shell -mkdir native/ -cheerpjfy.py --stub-natives=native/ some.jar - -``` - -> **Note**: Existing files in the passed directory will be overwritten. - -CheerpJ uses a compression scheme to encode mangled signatures. The `CHEERPJ_COMPRESS` macro is used automatically by this command, but can also be used manually. - -| macro | Description | -| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | -| `CHEERPJ_COMPRESS` | Encode the argument in parenthesis following such scheme. | -| `CHEERPJ_SET_CLASS` | Set the current internal class for resolving fields when using `CHEERPJ_FIELD` and `CHEERPJ_STATIC_FIELD` macros. | -| `CHEERPJ_FIELD` and `CHEERPJ_STATIC_FIELD` | The compiler replaces this macro with the encoded field name, it assumes the current class has been set by `CHEERPJ_SET_CLASS`. | - -### `--pack-classes-list=PACKCLASSESLIST` - -File containing a list of classes that should be compacted to the beginning and end of JAR file - -### `--pack-strip-binaries` - -Drop all dll/so/jnilib files from the JAR - -### `--ignore-classes=IGNORECLASSES` - -List of ',' separated classes that should not be compiled. Example --ignore-classes com.a.b.ClassOne,org.c.d.ClassTwo - -### `-j NUMJOBS` - -Number of parallel compilation jobs diff --git a/src/content/docs/cheerpj3/index.mdx b/src/content/docs/cheerpj3/index.mdx index f91520f7..89659e9f 100644 --- a/src/content/docs/cheerpj3/index.mdx +++ b/src/content/docs/cheerpj3/index.mdx @@ -45,10 +45,12 @@ Know what you're building? Jump straight to the relevant tutorial: ## What is CheerpJ? -**CheerpJ is constituted of two components:** +CheerpJ is a combination of two components: -1. The CheerpJ runtime library, a full Java SE runtime in WebAssembly and JavaScript. The CheerpJ runtime is cloud-hosted and accessed by the community free of charge for non-commercial purposes only. For self-hosting and commercial please visit our [licensing page](https://cheerpj.com/licensing/). -2. The CheerpJ on-the-fly Java-to-JavaScript compiler, a reduced JavaScript version of the CheerpJ compiler that can be distributed with applications compiled with CheerpJ to enable dynamic features of Java such as reflection. +1. An optimising Java-to-JavaScript JIT compiler. +2. A full Java SE 8 runtime. + +Both are written in C++ and are compiled to WebAssembly & JavaScript using [Cheerp](/cheerp). ## What is unique about CheerpJ? @@ -61,7 +63,7 @@ Know what you're building? Jump straight to the relevant tutorial: ## Licensing -CheerpJ is free for technical evaluation and non-commercial use. See [licensing](https://cheerpj.com/licensing/) for details. +CheerpJ is free for technical evaluation and non-commercial use. For commercial use, see [licensing](https://cheerpj.com/licensing/) for details. ## Demos From 4866c29b99186449b2ed2ce3c467c6caba541fc6 Mon Sep 17 00:00:00 2001 From: Alex Bates Date: Fri, 29 Sep 2023 17:33:31 +0100 Subject: [PATCH 03/33] fix line numbers of codeblocks --- .../docs/cheerpj3/03-getting-started/00-Java-app.md | 2 +- .../cheerpj3/03-getting-started/01-Java-applet.mdx | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md b/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md index e8a0f0a9..327f06bc 100644 --- a/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md +++ b/src/content/docs/cheerpj3/03-getting-started/00-Java-app.md @@ -26,7 +26,7 @@ mkdir directory_name Let's create a basic HTML file like the following example. Please notice the CheerpJ runtime environment has been integrated and initialized. In this example we are assuming your HTML file and your `.jar` files are under the project directory you just created. -```html title="index.html" {6, 9-16} +```html title="index.html" {6, 9-13} diff --git a/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx b/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx index c1b5cdb9..60daac84 100644 --- a/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx +++ b/src/content/docs/cheerpj3/03-getting-started/01-Java-applet.mdx @@ -21,7 +21,7 @@ CheerpJ can run Java applets in the browser seamlessly. This page will help you ### 1. Create a basic HTML file -```html title="index.html" {6, 9-15, 17-22} +```html title="index.html" {6, 9-17} @@ -35,12 +35,11 @@ CheerpJ can run Java applets in the browser seamlessly. This page will help you code="ExamplePath.ExampleApplet" height="900" width="900" - > - + > + - ``` From cc7b701e6ce355e01bb824d8bd03d58dc63a63c7 Mon Sep 17 00:00:00 2001 From: Alex Bates Date: Fri, 29 Sep 2023 17:41:02 +0100 Subject: [PATCH 04/33] fix sidebar backdrop appearing below codeblocks --- src/layouts/DocsArticle.astro | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/layouts/DocsArticle.astro b/src/layouts/DocsArticle.astro index 43fe52c6..ef1ca5f2 100644 --- a/src/layouts/DocsArticle.astro +++ b/src/layouts/DocsArticle.astro @@ -38,12 +38,15 @@ const contributeLinks = [ -