Issue
I am new to Vert.x and I want to run multiple verticles through jar. I have two files, one is MyFirstVertice.java and it routes the path "/q1/" and return something. The second is MySecondVertice.java which routes the path "/q2/". The second vertice is deployed in the first vertice.
MyFirstVertice.java
public class MyFirstVerticle extends AbstractVerticle {
@Override
public void start(Future<Void> fut) throws Exception {
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route("/q1/*").handler(routingContext -> {
HttpServerRequest request = routingContext.request();
String Y = request.getParam("key");
String cipherText = request.getParam("message");
HttpServerResponse response = routingContext.response();
response.setChunked(true);
response.putHeader("content-type", "text/plain");
response.write(Y + "\n");
response.write(cipherText + "\n");
response.end();
vertx.deployVerticle(new MySecondVerticle(), stringAsyncResult -> {
System.out.println("Second verticle is deployed successfully.");
});
});
server.requestHandler(router::accept).listen(8080, httpServerAsyncResult -> {
if (httpServerAsyncResult.succeeded()) {
fut.complete();
} else {
fut.fail(httpServerAsyncResult.cause());
}
});
}
}
MySecondVetice.java
public class MySecondVerticle extends AbstractVerticle {
@Override
public void start(Future<Void> fut) throws Exception {
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route("/q2/*").handler(routingContext -> {
HttpServerResponse response = routingContext.response();
response.setChunked(true);
response.putHeader("content-type", "text/plain");
response.end("q2");
});
server.requestHandler(router::accept).listen(8080, httpServerAsyncResult -> {
if (httpServerAsyncResult.succeeded()) {
fut.complete();
} else {
fut.fail(httpServerAsyncResult.cause());
}
});
}
}
My pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>io.vertx.core.Starter</Main-Class>
<Main-Verticle>tutorial.diluo.MyFirstVerticle</Main-Verticle>
</manifestEntries>
</transformer>
</transformers>
<artifactSet/>
<outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
I run it through java -jar xxx-fat.jar
.
When I type localhost:8080/q1/xxx in the browser, it can return desired content. But when I am trying to visit localhost:8080/q2/xxx, it says "Resource Not Found". Can you tell me how to deploy two verticles that route different paths? I know that I can route different pathe in the same verticle, I just want to know how to deploy and run multiple vertices. Thanks in advance!
Solution
The problem you have is that both Verticles
are attempting to bind to the same port (8080
) which you can't do.
So the second Verticle
is likely throwing a BindException
and failing to come up. The first Verticle
then, doesn't have a resource at /q2
which is why you're getting the Resource Not Found
.
Updated as per comment from tsegismont:
Vert.x
allows multiple Verticles to start on the same port in a feature known as server sharing. When this happens, Vert.x
will use a round robin strategy to send requests to each Verticle
in turn. So, you should see 50% of requests working for /q1
and 50% of request for /q2
. But - as noted by tsegismont, your browser uses persistent connections
so it maintains a connection to a single Verticle
. You should find that using curl, or another browser may give you a better result. Either way, this isn't probably what you want.
You should have a think if you need 2 Verticles
. Generally you want to think of a Verticle
as an entry point in to your application - it's a way of bootstrapping
your application / microservice.
If you really need 2 Verticles
then you will have to choose separate ports or run on separate boxes. If you don't, then just create 2 routes
on the same router
.
See http://vertx.io/docs/vertx-web/java/ for more info on Vert.x Web
Answered By - Will