Skip to content

Commit

Permalink
remove mention of cheerpjify.py, update JNI guide, use type=module
Browse files Browse the repository at this point in the history
  • Loading branch information
bates64 committed Sep 29, 2023
1 parent e0fb784 commit 25316ce
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 225 deletions.
48 changes: 9 additions & 39 deletions src/content/docs/cheerpj3/00-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.

Expand All @@ -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.
11 changes: 4 additions & 7 deletions src/content/docs/cheerpj3/03-getting-started/00-Java-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,10 @@ Let's create a basic HTML file like the following example. Please notice the Che
<script src="https://cjrtnc.leaningtech.com/3_20230819_174/cj3loader.js"></script>
</head>
<body>
<script>
async function myInit() {
await cheerpjInit();
await cheerpjCreateDisplay(800, 600);
await cheerpjRunJar("/app/my_application_archive.jar");
}
myInit();
<script type="module">
await cheerpjInit();
await cheerpjCreateDisplay(800, 600);
await cheerpjRunJar("/app/my_application_archive.jar");
</script>
</body>
</html>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,8 @@ CheerpJ can run Java applets in the browser seamlessly. This page will help you
>
</cheerpj-applet>
</body>
<script>
async function myInit() {
await cheerpjInit();
}
myInit();
<script type="module">
await cheerpjInit();
</script>
</html>
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ 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.

## 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
Expand Down
Original file line number Diff line number Diff line change
@@ -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

Check failure on line 29 in src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md#L29

[Vale.Spelling] Did you really mean 'env'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'env'?", "location": {"path": "src/content/docs/cheerpj3/04-guides/Implementing-Java-native-methods-in-JavaScript.md", "range": {"start": {"line": 29, "column": 58}}}, "severity": "ERROR"}
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))
20 changes: 0 additions & 20 deletions src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Check failure on line 41 in src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md#L41

[Vale.Terms] Use 'preload' instead of 'Preload'.
Raw output
{"message": "[Vale.Terms] Use 'preload' instead of 'Preload'.", "location": {"path": "src/content/docs/cheerpj3/04-guides/Startup-time-optimization.md", "range": {"start": {"line": 41, "column": 4}}}, "severity": "ERROR"}

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.
Expand Down
103 changes: 0 additions & 103 deletions src/content/docs/cheerpj3/05-reference/02-Command-Line-Options.md

This file was deleted.

10 changes: 6 additions & 4 deletions src/content/docs/cheerpj3/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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?

Expand All @@ -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

Expand Down

0 comments on commit 25316ce

Please sign in to comment.