Skip to content

Commit

Permalink
CJ docs updates (#202)
Browse files Browse the repository at this point in the history
  • Loading branch information
epanholz authored Jan 31, 2025
1 parent 2190329 commit bf90d8a
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: Intercept external commands
description: How to intercept external system commands that are executed in a Java application
---

When a Java program needs to execute an external system command, it often uses methods like `Runtime.getRuntime().exec(command)` or `ProcessBuilder(command)`. For example, a Java application might run a command to open a new browser window, launch a script, or execute a platform-specific utility. By default, these commands would execute directly on the system where the Java application runs.

With the [`execCallback`] [`cheerpjInit`] option, you can redirect those external commands to a JavaScript callback function. This allows you to control how commands are handled, enabling you to implement equivalent functionality in JavaScript.

> [!note] Important
> The `execCallback` option is supported in CheerpJ 3.1 and later versions.
## execCallback option

The [`execCallback`] option takes a function as a parameter, which will be called by CheerpJ whenever an external command is intercepted. CheerpJ automatically forwards all the necessary information about the intercepted command to this callback, allowing you to implement its behavior in JavaScript.

The JavaScript callback function accepts two parameters:

- `cmdPath`: The command that would have been executed in Java.
- `argsArray`: An array containing any additional arguments that were passed to the command.

These parameters provide all the context you need to handle the intercepted command.

## Example walkthrough

Let's walk through a simple example in Java:

```java title="Example.java"
import java.io.IOException;

public class Example
{
public static void main(String[] a) throws IOException, InterruptedException
{
String url = "http://www.example.com";
// The xdg-open command opens a URL in the default browser on Linux
String command = "xdg-open " + url;
Runtime.getRuntime().exec(command);
}
}
```

In this example, the Java program uses `Runtime.getRuntime().exec(command)` to open a URL in the default web browser on a Linux system. The command `xdg-open` is typically used to launch a URL in the browser. On Windows, a similar behavior is achieved with the command `cmd /c start`.

We can now implement the same behavior in JavaScript, here’s how:

```ts title="Index.html"
function execCb(cmdPath, argsArray) {
// Check for the xdg-open command
if (cmdPath == "xdg-open") {
// Open a new browser window
// argsArray will be "http://www.example.com" in our case
window.open(argsArray, "_blank");
}
}
```

In this JavaScript function, we check if the incoming command is `xdg-open`. If it matches, we use `window.open()` to open a new browser tab with the specified URL.

We can now pass this function to [`cheerpjInit`] using the [`execCallback`] option. This ensures that the function is invoked whenever an external command is executed in Java.

```ts title="index.html"
function execCb(cmdPath, argsArray) {
if (cmdPath == "xdg-open") {
window.open(argsArray, "_blank");
}
}

(async function () {
await cheerpjInit({ execCallback: execCb });
await cheerpjRunMain("/app/Example");
})();
```

By doing this, we successfully intercept the `Runtime.getRuntime().exec(command)` call from the Java application and implemented the same functionality using JavaScript to open a new browser window.

[`execCallback`]: /docs/reference/cheerpjInit#execcallback
[`cheerpjInit`]: /docs/reference/cheerpjInit
12 changes: 12 additions & 0 deletions sites/cheerpj/src/content/docs/11-guides/cheerpj-debug.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ If your application passes all these checks but still isn't working correctly, y

If you do so, make sure to provide additional context, such as a HAR file and the browser's console output. This will make it easier for us to assist you. Instructions on how to generate these are provided in the following steps.

## Enable advanced debug logs in CheerpJ

Before saving the browser console output, it's important to enable advanced debug logs in CheerpJ using the [`enableDebug`] CheerpJ [`initOption`].

```js
cheerpjInit({ enableDebug: true });
```

This option enables advanced debug logging, which is helpful for troubleshooting issues with CheerpJ. It provides a lot of extra information in case an actual error occurs and will speed up the process of solving the problem you are encountering.

## Saving the browser console output

You can follow these steps to save the browser console output:
Expand Down Expand Up @@ -57,3 +67,5 @@ You can save a HAR following these steps:
[`cheerpjRunJar`]: /docs/reference/cheerpjRunJar
[`cheerpjRunMain`]: /docs/reference/cheerpjRunMain
[virtual filesystem]: /docs/guides/File-System-support
[`enableDebug`]: /docs/reference/cheerpjInit#enableDebug
[`initOption`]: /docs/reference/cheerpjInit
49 changes: 49 additions & 0 deletions sites/cheerpj/src/content/docs/12-reference/00-cheerpjInit.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ async function cheerpjInit(options?: {
tailscaleLoginUrlCb?: (url: string) => void;
tailscaleIpCb?: (ip: string) => void;
licenseKey?: string;
execCallback?: (cmdPath: string, argsArray: string[]) => void;
enableDebug?: boolean;
}): Promise<void>;
```

Expand Down Expand Up @@ -373,6 +375,53 @@ Example of usage:
cheerpjInit({ licenseKey: "YourLicenseKey" });
```

### `execCallback`

```ts
execCallback?: (cmdPath: string, argsArray: string []) => void;
```

> [!note] Important
> The `execCallback` option is supported in CheerpJ 3.1 and later versions.
This option allows you to intercept and handle external system commands or program executions that initiated from a Java application. Such commands are typically executed using methods like `Runtime.getRuntime().exec(command)` or `new ProcessBuilder(command)` in Java.

The callback function accepts two parameters:

- `cmdPath`: The command that would have been executed in Java.
- `argsArray`: An array of additional arguments passed to that command.

Example of usage:

```js
cheerpjInit({
execCallback: function (cmdPath, argsArray) {
debugger;
},
});
```

Learn more about the `execCallback` option in our [intercept external commands guide](/docs/guides/Intercept-external-commands).

### `enableDebug`

```ts
enableDebug?: boolean;
```

> [!note] Important
> The `enableDebug` option is supported in CheerpJ 3.1 and later versions.
This option enables advanced debug logging, which is helpful for troubleshooting issues with CheerpJ.

Example of usage:

```js
cheerpjInit({ enableDebug: true });
```

Learn more about how to debug CheerpJ in our [Debugging CheerpJ guide](/docs/guides/cheerpj-debug).

[cjGetRuntimeResources]: /docs/reference/cjGetRuntimeResources
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[`java`]: /docs/reference/cheerpjInit#java-mode
Expand Down

0 comments on commit bf90d8a

Please sign in to comment.