- Hands-On Cloud Development with WildFly
- Tomasz Adamski
- 852字
- 2021-08-27 19:38:47
Fractions
In the preceding example, we did the following: we annotated our classes with JAX-RS annotations, built the code using Swarm Maven plugin, and obtained a runnable Swarm-based JAR. The resulting JAR is much smaller than a full application server. The reason for that is that Swarm has wrapped our code in only those parts of WildFly that it needs to work. Now, we will look in greater detail at this statement.
Let's run the application created in the preceding chapter again:
mvn wildfly-swarm:run
Let's look at the beginning of the console output:
Take a look at the lines of the log in the red rectangle. Swarm is informing us that it has installed four fractions: JAX-RS, Undertow, Elytron, and Logging. However, what does it mean by that and what actually is a fraction?
The fraction is a part of the functionality needed by an application. To be more precise, fraction gathers the code and the configuration necessary for some part of the enterprise functionality to work.
As we have used JAX-RS in our service, we have added the JAX-RS fraction as a Maven dependency. To recall, this was the following dependency in the pom.xml:
(...)
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jaxrs</artifactId>
<version>${version.wildfly.swarm}</version>
</dependency>
(...)
As a result, Swarm has built a service that contains this fraction. However, by looking again at the preceding screenshot, we can see that JAX-RS is not the only fraction installed as there are also Undertow, Elytron, and Logging fractions present.
The reason for the Logging fraction presence is that there are some fractions that are necessary for all configurations—logging is one among them. What about Undertow fraction? Fractions can depend on other fractions. As you probably know, JAX-RS needs to use a web server to serve web pages that it generates, and as a result, the JAX-RS fraction requires the dependency on the Undertow plugin. Swarm has discovered that we are using JAX-RS, so it included it in the generated application, but it also had to analyze dependencies of that fraction. The result of this analysis showed that another fraction, namely Undertow, has to be included. Similarly, both JAX-RS and Undertow depend on the Elytron fraction, which is responsible for implementing the security. As a result, it too was added to the created service.
Now, let's take a look at what happens if we decide to refactor our catalog service and use CDI.
Let's move the search functionality from the JAX-RS resource to the CDI service:
package org.packt.swarm.petstore.catalog;
import org.packt.swarm.petstore.catalog.model.Item;
import javax.enterprise.context.ApplicationScoped;
import java.util.HashMap;
import java.util.Map;
//1
@ApplicationScoped
public class CatalogService {
private Map<String, Item> catalog = new HashMap<>();
public CatalogService(){
Item turtle = new Item();
turtle.setItemId("turtle");
turtle.setName("turtle");
turtle.setQuantity(5);
turtle.setDescription("Slow, friendly reptile. Let your busy self see how it spends 100 years of his life laying on sand and swimming.");
catalog.put("turtle", turtle);
}
//2
public Item searchById(String itemId){
return catalog.get(itemId);
}
}
We created an application-scoped bean (1) and provided the Search method as the part of its API (2). Also, we have to modify the CatalogResource:
package org.packt.swarm.petstore.catalog;
import org.packt.swarm.petstore.catalog.model.Item;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/")
public class CatalogResource {
//1
@Inject
private CatalogService catalogService;
@GET
@Path("item/{itemId}")
@Produces(MediaType.APPLICATION_JSON)
public Response searchByName(@PathParam("itemId") String itemId) {
try {
//2
Item item = catalogService.searchById(itemId);
return Response.ok(item).build();
} catch (Exception e) {
return
Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
}
We injected the CatalogService that we have just created to it (1) and used it to look for the pet (2). Finally, we have to modify the pom.xml:
(...)
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jaxrs</artifactId>
<version>${version.wildfly.swarm}</version>
</dependency>
<!-- 1 -->
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>cdi</artifactId>
<version>${version.wildfly.swarm}</version>
</dependency>
</dependencies>
(...)
We have to add Swarm's CDI fraction (2).
After doing all of the things mentioned previously in this chapter, we can build our application and see a result that is similar to the one in the preceding example.
Let's look at the WildFly-Swarm plugin's log again:
We now have eight fractions present. Apart from the ones that were introduced in the preceding application, CDI, CDI-config, Bean Validation, and Transactions have been added. Again, Swarm has scanned the application and found out that it relies on JAX-RS and CDI; it has added those fractions and all their dependencies.
As you probably noted, the fractions that we see now are tightly related to Java EE specification. Can we then think of them as particular Java EE specification implementations added to the server core on demand? No. As we already know, Swarm is based on the Java EE server and part of its use case is to enable the transition from the monolith applications to microservices, there is a large group of fractions that map to the implementation of some Java EE functionalities. They are not limited to that, though. There is another group of fractions that provide functionality outside the Java EE. What is more, you are also able to implement your own fraction if you need it in your use case.
Look under WildFly's hood to understand how WildFly plugin works internally to create your lean Swarm application. Let's start by explaining how fraction detection works and how you can change its behavior by modifying Swarm's configuration parameters.