Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ydoc native image #10783

Merged
merged 23 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
545a8c3
DRAFT: native image
4e6 Aug 9, 2024
341dbba
Cannot use musl on Linux
JaroslavTulach Aug 9, 2024
5f38c34
DRAFT: native image config update
4e6 Aug 9, 2024
3722b83
fix: js resources loading
4e6 Aug 9, 2024
daea3be
add: test helidon native image build
4e6 Aug 12, 2024
50b9ba6
add: helidon native image+js
4e6 Aug 12, 2024
16a10c1
Useful NI debugging options for ydoc-server
JaroslavTulach Aug 15, 2024
ede2794
Debug ydoc server in VSCode
JaroslavTulach Aug 15, 2024
aabf41e
Print stack trace of WebServer initialization exception
JaroslavTulach Aug 15, 2024
c032d9d
Use Thread.ofPlatform() to workaround native image artificial limitat…
JaroslavTulach Sep 20, 2024
7f7738b
Adjusting to future Helidon changes accepted in https://github.com/he…
JaroslavTulach Sep 24, 2024
546ac9c
Making the ExecutorsFactory substitutions conditional
JaroslavTulach Sep 24, 2024
f87d467
Avoid non-substitution fields in Target_ExecutorsFactory
JaroslavTulach Sep 24, 2024
ee82801
Updating to Helidon 4.1.2 fixes ydoc-server/buildNativeImage
JaroslavTulach Oct 7, 2024
3fe6861
Resolving conflicts with develop
JaroslavTulach Oct 7, 2024
ac023d7
Legal review for Helidon 4.1.2
JaroslavTulach Oct 7, 2024
a6af5c3
Merge branch 'develop' into wip/db/10757-ydoc-native-image
4e6 Oct 29, 2024
d0b954b
fix: after merge
4e6 Oct 30, 2024
f8c878c
update: native-image configs
4e6 Oct 30, 2024
b3df0a8
fix: override helidon-client loom executor
4e6 Oct 30, 2024
5440ed6
misc: cleanup
4e6 Oct 30, 2024
e272cb1
update: legal review
4e6 Oct 30, 2024
d5a0c6c
misc: cleanup
4e6 Oct 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"type": "nativeimage",
"request": "launch",
"name": "Launch Native Image",
"nativeImagePath": "${workspaceFolder}/runner",
"args": "--run ${file}"
"nativeImagePath": "${workspaceFolder}/ydoc",
// "args": ""
}
]
}
107 changes: 102 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -1255,12 +1255,83 @@ lazy val searcher = project
.dependsOn(testkit % Test)
.dependsOn(`polyglot-api`)

lazy val `helidon-test` = project
.in(file("lib/java/helidon-test"))
.enablePlugins(JPMSPlugin)
.settings(
javaModuleName := "org.enso.ht",
Compile / exportJars := true,
crossPaths := false,
autoScalaLibrary := false,
// GraalVM and helidon modules (3rd party modules)
modulePath := {
JPMSUtils.filterModulesFromUpdate(
update.value,
GraalVM.modules ++ GraalVM.jsPkgs ++ helidon,
streams.value.log,
shouldContainAll = true
)
},
libraryDependencies ++= Seq(
"org.graalvm.truffle" % "truffle-api" % graalMavenPackagesVersion % "provided",
"org.graalvm.polyglot" % "js-community" % graalMavenPackagesVersion % "runtime",
"io.helidon.webclient" % "helidon-webclient-websocket" % helidonVersion,
"io.helidon.webserver" % "helidon-webserver-websocket" % helidonVersion
)
)
// `Compile/run` settings are necessary for the `run` task to work.
.settings(
Compile / run / fork := true,
Compile / run / connectInput := true,
Compile / run / javaOptions := Seq(
"-ea"
//"-agentlib:native-image-agent=config-merge-dir=/home/dbushev/projects/luna/enso/lib/java/ydoc-server/src/main/resources/META-INF/native-image/org/enso/ydoc"
),
// We need to assembly the cmd line options here manually, because we need
// to add path to this module, and adding that directly to the `modulePath` setting
// would result in an sbt caught in an infinite recursion.
//
Compile / run / javaOptions ++= {
val mp = modulePath.value
val jar = (Compile / exportedProductJars).value.head
val modName = javaModuleName.value
val allMp = mp ++ Seq(jar.data.absolutePath)
val mainKlazz = (Compile / mainClass).value.get
val args = Seq(
"--module-path",
allMp.mkString(File.pathSeparator),
"--module",
modName + "/" + mainKlazz
)
args
}
)
.settings(
NativeImage.smallJdk := None,
NativeImage.additionalCp := Seq.empty,
rebuildNativeImage := NativeImage
.buildNativeImage(
"ht",
staticOnLinux = false,
includeRuntime = false,
mainClass = Some("org.enso.ht.Main"),
additionalOptions = Seq("--enable-preview")
)
.value,
buildNativeImage := NativeImage
.incrementalNativeImageBuild(
rebuildNativeImage,
"ht"
)
.value
)

lazy val `ydoc-server` = project
.in(file("lib/java/ydoc-server"))
.enablePlugins(JPMSPlugin)
.configs(Test)
.settings(
frgaalJavaCompilerSetting,
customFrgaalJavaCompilerSettings("21"),
javaModuleName := "org.enso.ydoc",
Compile / exportJars := true,
crossPaths := false,
Expand All @@ -1287,14 +1358,15 @@ lazy val `ydoc-server` = project
),
libraryDependencies ++= Seq(
"org.graalvm.truffle" % "truffle-api" % graalMavenPackagesVersion % "provided",
"org.graalvm.polyglot" % "inspect" % graalMavenPackagesVersion % "runtime",
"org.graalvm.polyglot" % "js" % graalMavenPackagesVersion % "runtime",
"org.graalvm.polyglot" % "inspect-community" % graalMavenPackagesVersion % "runtime",
"org.graalvm.polyglot" % "js-community" % graalMavenPackagesVersion % "runtime",
"org.slf4j" % "slf4j-api" % slf4jVersion,
"io.helidon.webclient" % "helidon-webclient-websocket" % helidonVersion,
"io.helidon.webserver" % "helidon-webserver-websocket" % helidonVersion,
"junit" % "junit" % junitVersion % Test,
"com.github.sbt" % "junit-interface" % junitIfVersion % Test,
"com.fasterxml.jackson.core" % "jackson-databind" % jacksonVersion % Test
"com.fasterxml.jackson.core" % "jackson-databind" % jacksonVersion % Test,
"org.graalvm.sdk" % "nativeimage" % graalMavenPackagesVersion % "provided"
)
)
// `Compile/run` settings are necessary for the `run` task to work.
Expand All @@ -1305,6 +1377,7 @@ lazy val `ydoc-server` = project
Compile / run / connectInput := true,
Compile / run / javaOptions := Seq(
"-ea"
//"-agentlib:native-image-agent=config-merge-dir=/home/dbushev/projects/luna/enso/lib/java/ydoc-server/src/main/resources/META-INF/native-image/org/enso/ydoc"
),
// We need to assembly the cmd line options here manually, because we need
// to add path to this module, and adding that directly to the `modulePath` setting
Expand Down Expand Up @@ -1336,9 +1409,33 @@ lazy val `ydoc-server` = project
)
.taskValue
)
.settings(
NativeImage.smallJdk := None,
NativeImage.additionalCp := Seq.empty,
rebuildNativeImage := NativeImage
.buildNativeImage(
"ydoc",
staticOnLinux = false,
includeRuntime = false,
mainClass = Some("org.enso.ydoc.Main"),
additionalOptions = Seq(
// useful perf & debug switches:
// "-g",
// "-H:+SourceLevelDebug",
// "-H:-DeleteLocalSymbols",
)
)
.value,
buildNativeImage := NativeImage
.incrementalNativeImageBuild(
rebuildNativeImage,
"ydoc"
)
.value
)
.dependsOn(`syntax-rust-definition`)
.dependsOn(`logging-service-logback`)
.dependsOn(`profiling-utils`)
//.dependsOn(`profiling-utils`)

lazy val `persistance` = (project in file("lib/java/persistance"))
.settings(
Expand Down
6 changes: 6 additions & 0 deletions lib/java/helidon-test/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module org.enso.ht {
requires io.helidon.webclient;
requires io.helidon.webclient.websocket;
requires io.helidon.webserver;
requires io.helidon.webserver.websocket;
}
18 changes: 18 additions & 0 deletions lib/java/helidon-test/src/main/java/org/enso/ht/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.enso.ht;

import io.helidon.webserver.WebServer;

public class Main {

private Main() {}

public static void main(String[] args) throws Exception {
System.setProperty(
"helidon.serialFilter.pattern",
"javax.management.**;java.lang.**;java.rmi.**;javax.security.auth.Subject;!*");

var server = WebServer.builder().host("localhost").port(1235).build().start();

System.out.println("WebServer started.");
}
}
1 change: 1 addition & 0 deletions lib/java/ydoc-server/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
requires org.enso.syntax;
requires org.graalvm.polyglot;
requires org.slf4j;
requires static org.graalvm.nativeimage;

opens org.enso.ydoc.polyfill.web;

Expand Down
2 changes: 0 additions & 2 deletions lib/java/ydoc-server/src/main/java/org/enso/ydoc/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ public static void main(String[] args) throws Exception {
"helidon.serialFilter.pattern",
"javax.management.**;java.lang.**;java.rmi.**;javax.security.auth.Subject;!*");

Sampling.init();

var ydocHost = System.getenv(ENSO_YDOC_HOST);
var ydocPort = System.getenv(ENSO_YDOC_PORT);

Expand Down
39 changes: 0 additions & 39 deletions lib/java/ydoc-server/src/main/java/org/enso/ydoc/Sampling.java

This file was deleted.

2 changes: 1 addition & 1 deletion lib/java/ydoc-server/src/main/java/org/enso/ydoc/Ydoc.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public Ydoc build() {
}

if (contextBuilder == null) {
contextBuilder = WebEnvironment.createContext().allowIO(IOAccess.ALL);
contextBuilder = WebEnvironment.createContext().allowIO(IOAccess.ALL).allowAllAccess(true);
}

if (hostname == null) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.enso.ydoc.polyfill.web;

import org.enso.ydoc.Polyfill;
import org.enso.ydoc.polyfill.Arguments;
import org.enso.ydoc.polyfill.PolyfillBase;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.proxy.ProxyExecutable;
import org.slf4j.Logger;
Expand All @@ -12,13 +14,17 @@
* href="https://nodejs.org/api/globals.html#class-abortcontroller">AbortController</a> Node.js
* interface.
*/
final class AbortController extends PolyfillBase implements ProxyExecutable {
final class AbortController implements Polyfill, ProxyExecutable {

private static final Logger log = LoggerFactory.getLogger(AbortController.class);
private static final String ABORT_CONTROLLER_JS = "abort-controller.js";

AbortController() {
super(ABORT_CONTROLLER_JS);
@Override
public void initialize(Context ctx) {
Source jsSource =
Source.newBuilder("js", getClass().getResource(ABORT_CONTROLLER_JS)).buildLiteral();

ctx.eval(jsSource).execute(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
package org.enso.ydoc.polyfill.web;

import java.util.UUID;
import org.enso.ydoc.Polyfill;
import org.enso.ydoc.polyfill.Arguments;
import org.enso.ydoc.polyfill.PolyfillBase;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.proxy.ProxyExecutable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Implements the <a href="https://nodejs.org/api/crypto.html">Crypto</a> Node.js interface. */
final class Crypto extends PolyfillBase implements ProxyExecutable {
final class Crypto implements Polyfill, ProxyExecutable {

private static final Logger log = LoggerFactory.getLogger(Crypto.class);

private static final String RANDOM_UUID = "random-uuid";

private static final String CRYPTO_JS = "crypto.js";

Crypto() {
super(CRYPTO_JS);
@Override
public void initialize(Context ctx) {
Source jsSource = Source.newBuilder("js", getClass().getResource(CRYPTO_JS)).buildLiteral();

ctx.eval(jsSource).execute(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.enso.ydoc.Polyfill;
import org.enso.ydoc.polyfill.Arguments;
import org.enso.ydoc.polyfill.PolyfillBase;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.proxy.ProxyExecutable;
import org.slf4j.Logger;
Expand All @@ -15,7 +17,7 @@
* Implements the <a href="https://nodejs.org/api/events.html#class-eventemitter">EventEmitter</a>
* Node.js interface.
*/
final class EventEmitter extends PolyfillBase implements ProxyExecutable {
final class EventEmitter implements Polyfill, ProxyExecutable {

private static final Logger log = LoggerFactory.getLogger(EventEmitter.class);

Expand All @@ -27,8 +29,12 @@ final class EventEmitter extends PolyfillBase implements ProxyExecutable {

private static final String EVENT_EMITTER_JS = "event-emitter.js";

EventEmitter() {
super(EVENT_EMITTER_JS);
@Override
public void initialize(Context ctx) {
Source jsSource =
Source.newBuilder("js", getClass().getResource(EVENT_EMITTER_JS)).buildLiteral();

ctx.eval(jsSource).execute(this);
}

@Override
Expand Down
Loading
Loading