Skip to content

Conversation

@jtulach
Copy link
Contributor

@jtulach jtulach commented Jan 10, 2025

To support use of HTML/Java API in GraalVM's native-image tool:

  • the @JavaScriptBody and @JavaScriptResource annotation need to be available in runtime
  • however they have RetentionType.CLASS
  • let's patch the bytecode then

It is necessary to change the bytecode of:

  • all classes using these annotations need to duplicate their usage into runtimeVisibleAnnotation class file attribute
  • all these annotations need to be patched to declare RetentionType.RUNTIME

With such changes we should be able to use the JVM agent of HTML/Java to make these annotation available at GraalVM's native image build time.

  • Write a test to verify behavior of the -agentlib option
  • Update documentation

@jtulach jtulach self-assigned this Jan 10, 2025
@jtulach
Copy link
Contributor Author

jtulach commented Jan 10, 2025

This PR properly implements the ideas discussed at oracle/graal#8177 (comment)

@jtulach
Copy link
Contributor Author

jtulach commented Jan 11, 2025

net.java.html.boot-2.0-SNAPSHOT.jar.gz JAR (after gzip -d) contains the Agent-Class attribute in its manifest:

/graalvm-21/bin/java \
    -javaagent:net.java.html.boot-2.0-SNAPSHOT.jar  \
    -cp net.java.html.boot-2.0-SNAPSHOT.jar \
    App.java

can be used to change the retention of the @JavaScriptBody & co. annotations as following App.java sample code demonstrates:

import net.java.html.js.JavaScriptBody;

class App {
  @JavaScriptBody(args={}, body="")
  public static native void hello();

  public static void main(String... args) throws Exception {
    var hello = App.class.getMethod("hello");
    System.err.println("method: " + hello);
    System.err.println("ann: " + hello.getAnnotation(JavaScriptBody.class));
  }
}

Executing the program should print: ann: [JavaScriptBody](method: @net.java.html.js.JavaScriptBody(wait4js=true, wait4java=true, javacall=false, keepAlive=true, args={}, body="")).

@jtulach
Copy link
Contributor Author

jtulach commented Jun 20, 2025

Testing with Native Image

The primary goal of this change is to allow integration with GraalVM. Let's do a small test. Take GraalVM repository at release/graalvm-25.0 branch, in particular commit bb84380ba769081088ed5a95c2a4f3df9f1ac652:

graal/web-image$ mx build
graal/web-image$ graal/web-image$ mx web-image
Error: Please specify class (or <module>/<mainclass>) containing the main entry point method. (see --help)

With the mx web-image tool functioning. Let's create netbeans-html4j-test.sh file with the following content:

#!/bin/bash
set -e

mkdir -p hi

V=2.0-SNAPSHOT
CP=$1

if ! [ -e "$CP" ]; then
  echo Usage $0 '<path_to_net.java.html.boot.jar>'
  echo    - typical path may be: $HOME/.m2/repository/org/netbeans/html/net.java.html.boot/$V/net.java.html.boot-$V.jar
  exit 1
fi


cat >hi/Hi.java <<KONEC
class Hi {
  @net.java.html.js.JavaScriptBody(args="txt", body="""
    console.log(txt);
    return "...returning back from JavaScript...";
  """)
  private static native String hello(String txt);

  public static void main(String... args) {
    System.out.println("In JVM");
    var hi = hello("Hi from JavaScript");
    System.out.println(hi);
    System.out.println("Back in JVM");
  }
}
KONEC

javac -cp $CP hi/Hi.java -d hi

mx web-image -H:+UnlockExperimentalVMOptions  -o hi  -H:Path=hi \
 -H:+SILENT_COMPILE  -H:-ClosureCompiler  -H:+DumpPreClosure \
 -H:+VerificationPhases  -H:JSRuntime=Generic  -H:Class=Hi \
 -cp hi \
 -J-javaagent:$CP

node hi/hi.js

and then just launch it with
net.java.html.boot-2.0-SNAPSHOT.jar.gz after uncompressing it with gzip -d:

graal/web-image$ ./netbeans-html4j-test.sh net.java.html.boot-2.0-SNAPSHOT.jar
======================
GraalVM Native Image: Generating 'hi' (executable)...
======================
...
In JVM
Hi from JavaScript
...returning back from JavaScript...
Back in JVM

Heuréka. CCing @Pziegler, @toni-epple, @fniephaus - everything seems to be working. The next version of NetBeans/HTML API will easily generate the right code with mx web-image tool (with the help of -javaagent:net.java.html.boot.jar)!

@jtulach jtulach merged commit 3967480 into apache:master Jun 20, 2025
0 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant