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

Graal.js and JavaFX WebView? #326

Closed
up-to-you opened this issue Mar 25, 2018 · 18 comments
Closed

Graal.js and JavaFX WebView? #326

up-to-you opened this issue Mar 25, 2018 · 18 comments
Assignees
Labels

Comments

@up-to-you
Copy link

Can Graal.js replace JavaScriptCore in WebKit engine ? Or can it be used for some another abstract implementation of WebView with zero overhead during interoperation ?
It's not very interesting to use npm packets or modules on server side along with Java, because there are a lot more libraries for JVM rather than for Nodejs, i.e. everything you can do using Nodejs - you can do greatly using Java libs with performance gain (especially considering the technologies difference in age and maturity).
So, the only case i see application of Graal.js - is a dedicated "browser", or some part of "browser".

@woess
Copy link
Member

woess commented Mar 27, 2018

We currently have no plans for integrating Graal.js into a browser.
Today's browser engines are tightly coupled with their respective JS engines and thus won't cooperate with other engines very well. Not saying it can't be done.

@tarsa
Copy link

tarsa commented Apr 4, 2018

It's not very interesting to use npm packets or modules on server side along with Java, because there are a lot more libraries for JVM rather than for Nodejs, i.e. everything you can do using Nodejs - you can do greatly using Java libs with performance gain (especially considering the technologies difference in age and maturity).

You forgot about frontend development pipelines and various tools for producing JavaScript (and other types of) files. I'm programming in Scala so my example will be: https://github.com/scala-js/scala-js It compiles Scala to JavaScript and that applies also to tests. Currently it's using external processes like Node.js to run them. That incurs communication overhead and there have to be multiple Node.js instances running (so memory is wasted and management is sometimes tricky). Having an option to run Node.js based JavaScript tests inside single JVM would probably make things much more efficient.

@thomaswue thomaswue assigned thomaswue and unassigned woess Apr 13, 2018
@eliasvasylenko
Copy link

eliasvasylenko commented Mar 19, 2019

Servo may be worth exploring for this in the long term. It's almost entirely Rust afaiu, so can hopefully be targeted to Sulong, and apparently "pluggable engines is a long-term, low-priority goal". (Though that document appears to be pretty outdated and I can't find anything in the issue tracker about it.)

Maybe this could be the basis of a JVM/GraalVM-based alternative to Electron some day...

@thomaswue
Copy link
Member

We are currently exploring the possibility of a GraalVM-based Electron.

@eliasvasylenko
Copy link

Interesting. So is what you're exploring something like a drop-in replacement? That is, fork Electron with whatever modifications may be necessary to swap V8 out for GraalJS and target to Sulong?

In the spirit of the original issue/question then, facilitating integration with JavaFX (and other non-node-based applications) is not necessarily a goal for you internally. Does that sound like a reasonable assumption?

Having Electron running on JVM/GraalVM would at least be a solid proof-of-concept for exposing a more general API over the Chromium renderer, but I assume it would take significant work to decouple it from the rest of the Electron infrastructure.

I appreciate that it may be a bit early to comment.

@errikos
Copy link
Contributor

errikos commented Mar 21, 2019

Hi. As @thomaswue said, we are currently exploring how we can integrate GraalVM with Electron.

I would say that the problem is not Electron itself, but mostly the tight coupling of Chromium and V8.

Electron is developed upon (and built against) the Chromium infrastructure. This means that it depends on most of the Chromium dependencies, one of them being V8. Electron also depends on Node, but merely as a library. On startup, Electron orchestrates the initialisation of V8, Node, etc. Notice that Node comes with it's own version (branch) of V8, but Electron chooses to build everything against Chromium's V8. The reason for this is the very tight coupling of Chromium with V8.

Therefore, as @woess said, the challenging part is to decouple Chromium from V8 and make it work with GraalJS. To be able to do that we need to implement a set of the V8 API calls that Chromium/Electron use but are not yet implemented in GraalJS. We are working on identifying that missing functionality.

@mutech
Copy link

mutech commented Feb 21, 2020

I would find it more important to have graal available on the node side to be able to easily integrate both java libraries and modules from other platforms (clang/ruby, etc.). Having the browser use graaljs would probably bring more problems than benefits. It's easier to have the browser be chrome/v8 instead of introducing all kinds of incompatibilities with UI code.

@mauricioszabo
Copy link

Is there any issue, feature request, or branch were we can follow up this integration with Electron? I'm really interested in doing alpha tests with it :)

@wdanilo
Copy link

wdanilo commented Apr 25, 2020

@thomaswue @errikos, I remember Thomas mentioned one day on Twitter that there are plans for GraalVM to be run on WASM, is this still true? For us, this would be a killer thing, as we are building a SaaS product, and being able to just run the compiler on the client-side would be our dream come true (this would allow us for a much more interactive experience). I know it's hard and I appreciate the incredible work you guys did here with Graal. I just believe that if GraalVM would not run on WASM, a very, very important target would be missing, definitely important enough to heavily influence the success of the whole project here.

I'm asking it in this thread because in such a scenario, GraalVM could just run in Electron without any electron modifications. Moreover, this enables a much more compelling (at least to me) scenario - ability to distribute GraalVM based languages as web-apps.

@thomaswue
Copy link
Member

We had an early attempt of translating a native image into JavaScript (https://www.davidleopoldseder.com/publications/aotjs_dsl_paper_authorversion.pdf). The main resulting challenge was the size of the code and how to best minify it.

The issue with WebAssembly at this point is that it is missing the necessary functionality to perform garbage collection (e.g., missing stack walking); and generally it is more designed to run languages like C/C++ rather than ones with managed objects.

We are planning to continue explorations this summer via an internship project.

@wdanilo
Copy link

wdanilo commented Apr 26, 2020

@thomaswue thank you for the answer! I highly appreciate it ❤️

[...] and generally it is more designed to run languages like C/C++ rather than ones with managed objects.

I have seen such statements across the internet but TBH, I'm highly surprised to hear that from you. Please correct me if I'm wrong, but to me, it sounds like "hey, normal assembly doesn't support GC out of the box, so it's more designed to run languages like C/C++ rather than Python/JS/Ruby/Java/...". WASM in a similar fashion to normal assembly provides low-level abstraction only. A lot of things, like automatic memory management, need to be built on top of it. In my opinion, this is a very good choice. In the current form, WASM gives us a framework to build things from the ground up, including both things that manage memory manually and automatically (by implementing/porting GCs to it or using GCs delivered by WASM engines in the future to minimize the size of apps). If WASM was built on top of had a GC'ed engine, then it would not be so flexible as it is now. In such a context, I do not really understand why "WASM is more designed to run languages like C/C++ than those build on top of GraalVM". Sure, the garbage collector needs to be implemented / ported, but it should rather not stand on our way to make GraalVM languages be available in the browser.

The issue with WebAssembly at this point is that it is missing the necessary functionality to perform garbage collection

One more question, if I might. I was sure that the native image has its own GC implementation. If so, why compiling it (the GC) to WASM is not the right path to follow?

We are planning to continue explorations this summer via an internship project.

I'm excited to hear that! Both me and many developers I'm working with, believe that if GraalVM could run with high performance in the browser, together with its incredible performance for various languages and seamless interoperability, it will become the "holy grail" of computing. In such a scenario, Graal could really define the future of "computer language development" in general. Not to mention gaining massive interest from all people involved in web dev.

@tarsa
Copy link

tarsa commented Apr 27, 2020

Please correct me if I'm wrong, but to me, it sounds like "hey, normal assembly doesn't support GC out of the box, so it's more designed to run languages like C/C++ rather than Python/JS/Ruby/Java/...". WASM in a similar fashion to normal assembly provides low-level abstraction only.

WASM is not an ordinary close to metal assembly, it's a sandboxed and limited assembly. Java bytecode is somewhat similar in that it's also restricted (you can't do arbitrary memory management in any of them) and it also has assembly form (just run javap to disassembly bytecode). Java even had hardware implementations https://en.wikipedia.org/wiki/Jazelle while WASM doesn't have any (but that doesn't really matter).

One thing that looks infeasible to me is JIT written in WASM. JIT requires fine-grained low-level control over generated code during the whole execution time, but WASM is more suited for AOT compilation. GraalVM can't AOT JavaScript, Python, Ruby, R, etc so we'll be left with interpreter compiled to WASM which will be interpreting JavaScript, Python, Ruby, R, etc. Is that correct?

OTOH there's a proposal of "Platform-independent Just-in-Time (JIT) compilation" for WASM: https://github.com/WebAssembly/design/blob/master/FutureFeatures.md#platform-independent-just-in-time-jit-compilation . Will it be flexible enough for all of GraalVM needs? Time will tell.

<just an opinion>Judging by WASM enthusiasm over the Internet I would say that WASM is currently overhyped. It's in the stage of inflated expectation in https://en.wikipedia.org/wiki/Hype_cycle </just an opinion>

What could be feasible is to have a slow GraalVM (interpreter mode, simple GC, etc) inside a browser and a compatible standalone version that runs on desktop and has full speed (so GraalVM would need e.g. Electron integration). People would try out apps inside a browser and if they like them they would install them on their machines.

@wdanilo
Copy link

wdanilo commented Apr 27, 2020

you can't do arbitrary memory management in any of them

What do you mean by arbitrary memory management here? WASM allows you to manage memory on a very low level. For example, if you compile Rust to WASM you can choose among different memory allocator implementations for WASM (e.g. this one). It delivers you a linear memory model where you can normally allocate or free memory according to your needs.

One thing that looks infeasible to me is JIT written in WASM.

Why? If we can compile any code written in C, including even games, to almost native performance, why compiling JIT to WASM is infeasible? The main point I don't understand here is why WASM is "more suited for AOT compilation". If you can run JIT natively, you can also run it on WASM. You can compile for example any C-based JIT implementation to it, you can define your own memory managers / allocators there, so why its not suitable for it?

What could be feasible is to have a slow GraalVM (interpreter mode, simple GC, etc) inside a browser and a compatible standalone version that runs on desktop and has full speed (so GraalVM would need e.g. Electron integration). People would try out apps inside a browser and if they like them they would install them on their machines.

This has several downsides:

  1. It breaks one of the most beautiful visions of the future of software, where you do not need to install software on your computer at all.
  2. It actually has some serious business implications. For example, we are delivering enterprise software for banks and pharma companies, and they are switching from anything installed on computers of their employees to browser-based whenever possible. The main reason for that is that you can much easier maintain even hundreds of thousands of workstations with updated software (no need to update it per-user).
  3. There are many use cases where this would not work. For example, we allow to define in our language how WebGL widgets work (sliders, buttons, etc). We want these to run in the browser with full speed (incl. event management and the logic defined). One of the most frequent request we hear from our customers is if we would allow to create web-apps / web-widgets with the tools we provide. As we are crunching big amount of data, this would not be possible with big performance drop.

Anyway, let's leave the last point for now (installation on user computers). The most important point here is "WASM not being suitable for JIT implementation". If JIT could be implemented efficiently on WASM, then the ability to just run GraalVM in the browser delivers much greater flexibility then requiring users to install it to get full speed.

@tarsa
Copy link

tarsa commented Apr 27, 2020

What do you mean by arbitrary memory management here? WASM allows you to manage memory on a very low level. For example, if you compile Rust to WASM you can choose among different memory allocator implementations for WASM (e.g. this one). It delivers you a linear memory model where you can normally allocate or free memory according to your needs.

WASM doesn't let you e.g. unmap a memory page. Page fault trapping is the common method in JVM world for reaching a safepoint (unless info on the Internet is dated) and safepoints are required for various purposes. More info:
http://blog.ragozin.info/2012/10/safepoints-in-hotspot-jvm.html
https://medium.com/software-under-the-hood/under-the-hood-java-peak-safepoints-dd45af07d766
https://shipilev.net/jvm/anatomy-quarks/22-safepoint-polls/

You can do safepoint polls using other methods, but they will likely be significantly slower.

Why? If we can compile any code written in C, including even games, to almost native performance, why compiling JIT to WASM is infeasible? The main point I don't understand here is why WASM is "more suited for AOT compilation". If you can run JIT natively, you can also run it on WASM. You can compile for example any C-based JIT implementation to it, you can define your own memory managers / allocators there, so why its not suitable for it?

All WASM examples are about AOT compilation. Where is a JIT running on WASM? The problem is that a full-fledged JIT produces in fact a self-modifying code that changes throughout execution. And it needs to do executable code patching at a very fine-grained level to avoid swapping large chunks of code due to a single optimization-related assertion no longer holding up. Just look at bullet points under: https://github.com/WebAssembly/design/blob/master/FutureFeatures.md#platform-independent-just-in-time-jit-compilation

Applications expect a wide variety of JIT-compilation capabilities. WebAssembly should support:

  • Producing a dynamic library and loading it into the current WebAssembly module.
  • Define lighter-weight mechanisms, such as the ability to add a function to an existing module.
  • Support explicitly patchable constructs within functions to allow for very fine-grained JIT-compilation. This includes:
    • Code patching for polymorphic inline caching;
    • Call patching to chain JIT-compiled functions together;
    • Temporary halt-insertion within functions, to trap if a function start executing while a JIT-compiler's runtime is performing operators dangerous to that function.
  • Provide JITs access to profile feedback for their JIT-compiled code.
  • Code unloading capabilities, especially in the context of code garbage collection and defragmentation.

WebAssembly's JIT interface would likely be fairly low-level. However, there are use cases for higher-level functionality and optimization too. One avenue for addressing these use cases is a JIT and Optimization library.

Even without a full-fledged JIT there could still be benefits. What could be AOT compiled (e.g. Java bytecode, LLVM bitcode, etc) would be AOT compiled. The rest would be either interpreted or JITed using the limited features that future WASM APIs would provide.

Also look at what @thomaswue wrote:

The issue with WebAssembly at this point is that it is missing the necessary functionality to perform garbage collection (e.g., missing stack walking);

Thread stacks are a crucial part of root set during GC, i.e. you start checking for objects' reachability starting from references on root set. If you can't do that directly (i.e. you can't scan thread stacks directly) then something else needs to be done. Shadow stack (i.e. duplicating the native one)? Hybrid GC like reference counting + tracing GC (IIRC Python does that)? Probably a special GC just for WASM would be needed and in that case special GC API built into WASM make sense, so GC would be implemented natively inside WASM runtime instead of in WASM bytecode.

The biggest lie about WebAssembly is stating that it gives you almost complete freedom, i.e. the restrictions it imposes (vs real assembly language) are negligible. In fact WASM (at least in current state) is severely restricted and that lie comes from misunderstanding about its capabilities. Working around these limitations requires hard work and results aren't guaranteed to be satisfactory. That's what I'm trying to convey here.

@frank-dspeed
Copy link

frank-dspeed commented Jun 3, 2022

Hello my frinds i want to make some of my efforts and results more visible and public so lets start the show:

  • GraalVM offers graal-node a nodejs fork which is in fact using GraalVM and not v8 ok
  • Chromium Firefox and all do use a diffrent js implementation and that is ok
  • All GraalVM and the other Browsers do offer the so called devtools:// Protocol a \0 terminated string

how does this algin?

install:

  • GraalVM Community edition including node-graal
  • create a new npm project
  • to make it simple npm i playwright (this is not needed but i do not want to post as much code examples here)

index.js

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: false });

  const page = await browser.newPage();
  // Expose function `myFunction` on window object this runs on GRAALVM 
  await page.exposeBinding('myFunction', ({ page }, question) => {
    console.log('Web page is asking: ' + question);
    return 42; 
  });

  // Load a simple page that calls this `handleClick`
  await page.setContent(`
    <script>
      async function onClick() {
        // Call into Node
        const result = await myFunction('What is the ...?');
        alert(result); // Result from GraalVM
      }
    </script>
    <button onclick="onClick()">What is the ...?</button>
  `);
})();

i will soon upgrade the tutorials and materials how to start for example the browser window as PWA App mode window to eliminate the tabs and that we also got window positioning and all that

the devtools api works via websockets and also pipes it is able to control the whole browser or even many browsers and we are able to expose functions listners and handlers in any Chromium or browser context but i need to write more about it.

but that is a electron/nwjs replacement that works with any modern browser + graalvm

Happy coding

Advanced notes

playwright installs the lates chromium binarys to your project use playwright-core to do not install a additional browser and directly use the existing!

@humbinal
Copy link

humbinal commented Jul 30, 2022

@thomaswue In 2019, you mentioned that you are exploring a GraalVM-based Electron, So on today, Is there a solution available ?

I'm trying to find a solution for desktop/native apps in java community but failed. meanwhile, I find that some excellent solutions like wails2 on go, tauri on rust, their executables are very lightweight and development model is very modern.

I think with GraalVM's power, If has a solution like wails or tauri, It can provides great convenience for Java developers, it will be succeed !

thank you ~

@frank-dspeed
Copy link

@humbinal at present there is a way to do that
but i did not finish publishing a nodejs compatible graaljs context. so you need to stick around with the following solution https://github.com/frank-dspeed/chromitex/blob/main/README.md

if you want to help as i am total alone simply create a issue there and write: hi i want to help

then i invest time to schedule easy tasks.

the core concept is easy we use chrome or chromium in the demo we install chromium current version but we could also invest into a function that detects a already installed browser

the example loads a page and injects a preload script it also shows what i call appMode that displays a app like window with the current browser

the example is a video player for a german platform that i wrote as demo and for own use it removes the need to click on some popups.

when you need help i got functions for everything that electron can do but i need to know what you need so open issues and ask there like: How can i create a stream in a Page and read it from the Host

something like that good luck may the force be with you

the IPC of the puppeteer solution by the way works via process pipe if you wonder how that works internal
as we spawn chrome or chromium from our GraalVM process we are able to use devtools to interact from the host with the view.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests