reactiverse / es4x

🚀 fast JavaScript 4 Eclipse Vert.x
https://reactiverse.io/es4x/
Apache License 2.0
884 stars 75 forks source link

Include js verticles in Java code #577

Open tpfau opened 2 years ago

tpfau commented 2 years ago

This is somewhat related to #223. I'm currently trying to include some js verticles into a bigger java project. As a minimal example I have a helloVert.js :

vertx.eventbus().consumer("hello.vertx", function(msg){
        msg.reply("Hello Vertx World");
});

And a ServerVerticle.java:

package my.test;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;

public class ServerVerticle extends AbstractVerticle {

    @Override
    public void start() {
        HttpServerOptions http_opts = new HttpServerOptions();
        DeploymentOptions opts = new DeploymentOptions();
        vertx.deployVerticle("helloVert.js", opts);
        HttpServer server = vertx.createHttpServer(http_opts);
        int httpPort = 8080;                
        server.listen(httpPort);    
    }

}

I'm using a maven build file including :

        <dependency>
            <groupId>io.reactiverse</groupId>
            <artifactId>es4x-vertx-stack</artifactId>
            <version>0.17.0</version>
        </dependency>

And I get the following error:

Exception in thread "main" java.util.ServiceConfigurationError: io.vertx.core.spi.VerticleFactory: io.reactiverse.es4x.impl.JSVerticleFactory Unable to get public no-arg constructor
        ...
Caused by: java.lang.NoClassDefFoundError: org/graalvm/polyglot/io/FileSystem
    ... 
Caused by: java.lang.ClassNotFoundException: org.graalvm.polyglot.io.FileSystem
        ...

Am I just missing dependencies, or should those be added to es4x? Or am I doing something absolutely wrong here (which is entirely possible)?

pmlopes commented 2 years ago

@tpfau You need:

 <dependency>
            <groupId>io.reactiverse</groupId>
            <artifactId>es4x</artifactId>
            <version>0.17.0</version>
        </dependency>

Perhaps I should fix that pom to require the main jar too. That dependency is just the generated code, all the vertx stack modules, so you don't need to pull them from NPM.

pmlopes commented 2 years ago

TASK: Investigate if we can add a dependency to the main jar, of if this would create a huge circular dependency problem.

tpfau commented 2 years ago

Thanks for the quick response. This still causes the same error message.

Exception in thread "main" java.util.ServiceConfigurationError: io.vertx.core.spi.VerticleFactory: io.reactiverse.es4x.impl.JSVerticleFactory Unable to get public no-arg constructor

Interestingly, when I remove the es4x dependency completely, the deployment succeeds (well vertx starts to run), however, when then trying to access the verticle via the eventbus it fails, indicating that there was no consumer registered at the given address.

tpfau commented 2 years ago

@pmlopes are there any examples using vert.x 4 with es4x combining Java and Javascript verticles using maven as a build tool?
The only example I have found that actually combined js and java was for vert.x 3 by Devon Philipps in his Introduction to Vert.x. youtube series. Following that example and replacing the old lang-js dependency by es4x I end up with the above issue.

tpfau commented 2 years ago

Hi, Coming back to this: I managed to get the js verticle to work.

What I needed to add were dependencies for graalvm:

<dependency>
    <groupId>org.graalvm.sdk</groupId>
    <artifactId>graal-sdk</artifactId>
    <version>22.0.0.2</version>
</dependency>
<dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js</artifactId>
    <version>22.0.0.2</version>
</dependency>

Which es4x does not seem to depend on (should it)? However, this gives me the following warning when launching the server:

The polyglot context is using an implementation that does not support runtime compilation.
The guest application code will therefore be executed in interpreted mode only.
Execution only in interpreted mode will strongly impact the guest application performance.
For more information on using GraalVM see https://www.graalvm.org/java/quickstart/.
To disable this warning the '--engine.WarnInterpreterOnly=false' option or use the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.

I assume this is due to it running on java and not graalvm, but I'm currently not sure how best to change this (and actually if I should change this).