- Lab 1: Your first WildFly Swarm Project
- 1. Clone the Repository
- 2. Open
lab1
using the IDE - 3. Examine the Project
- 4. Examine the REST endpoint
- 5. Examine the Maven POM file
- 6. Build the (non-WildFly Swarm) Java EE project
- 7. Getting started with WildFly Swarm
- 8. Test the REST endpoint
- 9. Explicitly Declare Dependencies
- 10. Stop the service
In this lab, you will take an existing Java EE application and modify it to create your first WildFly Swarm Java application, understand its structure, and use the WildFly Maven Plugin to build and run the project. Later labs will introduce you to OpenShift and containerized microservices.
-
Knowledge of Java language
-
Familiarity with Java EE and OpenShift
-
Basic Linux/Unix shell script knowledge
-
Developer environment with a modern web browser, Git, Maven, a text editor or IDE, and the OpenShift
oc
command line utility
-
Commands that you execute in the Linux shell are preceeded by a
%
character. Do not include this when you are typing or copying/pasting the commands. -
Hostnames, usernames and passwords, and OpenShift resource names will be different for each participant. Take care to substitute the correct values for your environment when doing the exercises.
-
Screenshots may differ slightly from actual product.
To get started, use git
to copy the necessary lab files to your local environment:
$ cd $HOME $ git clone https://github.com/rhoar-enablement/wildfly-swarm
This will create a copy of the lab materials in the wildfly-swarm
subdirectory.
$ cd $HOME/wildfly-swarm $ ls lab1 lab2 lab3 lab4 ...
Each lab is self-contained within each of the subdirectories.
Note
|
You can choose any directory to house your lab code, these instructions use $HOME as an example.
|
At the beginning of each lab you will start with working source code, and make modifications yourself to demonstrate features of the software, ending with working source code that you modified.
If you get stuck and can’t figure out why something isn’t working or compiling or you are getting strange errors,
you can always compare your project and the contents of the files you are modifying with a pre-created solution
in the solution
branch of the git repository.
Note
|
You can also just browse the solution in your browser at https://github.com/rhoar-enablement/wildfly-swarm/tree/solution
|
For example, suppose you are on Lab 3 and editing the pom.xml
file and your build fails. You show the differences
between the "official" solution and YOUR code using:
% cd $HOME/wildfly-swarm/lab3
% git diff solution:lab3/pom.xml ./pom.xml
To compare the entire source tree between your code and the Lab 3 code:
% cd $HOME/wildfly-swarm/lab3
% git diff solution:lab3/src ./src
This uses the git
command line to perform file comparisons using the named branch solution
and your working
directory of changes. Use the output from git diff
to see if you’ve forgotten a step or mis-typed something.
You can also get the entire solution and use that in case you simply want to fast-forward to the end of the lab. For example, suppose you are stuck on Lab 3 and time is running out, but you want to see the final solution before moving to lab 4. In this case you can follow these steps:
-
If you want to save the changes you’ve made, run
git stash save
. This will save your changes and then reset your working directory back to the beginning of the mab. -
Next, run
git checkout solution
to switch to the solution branch. Files in your working directory should now be the solution’s files. -
Proceed with the lab (e.g. do a build, run a command, whatever is required in the lab after changing source code)
-
When you’re done, don’t forget to go back to the
master
branch so you can start the next lab at the beginning!% git reset --hard % git checkout master % git stash apply # optional, only needed if you saved your changes earlier
Each lab in this course is housed in separate directories. Using the command line, find and observe the files for this lab:
% cd $HOME/rhoar-enablement/lab1
Load the first lab into your favorite code editor or IDE:
$ cd lab1 $ code . # or vim, emacs, JBoss Developer Studio, IntelliJ IDEA, etc.
Once loaded, you should see the lab files and be able to navigate amongst the files. The components of this first project are laid out in different subdirectories according to Maven best practices:
-
src/main/java
- The source code to the project -
src/main/resources
- The static resource files referenced in the code -
docs/lab1-instructions.adoc
- This file -
pom.xml
- The Maven project file
Tip
|
WildFly Swarm projects can also be managed using other tools besides Maven, such as Gradle, JBoss Forge, or Swarmtool. Consult the docs for more detail. |
This is a minimal Java EE project which implements a simple RESTful microservice which implements a retail store inventory service.
The major components of the service within the src/main/java/com/redhat/coolstore
directory are:
-
model/
- The data model for an inventory item, represented as POJOs (Plain old Java Objects) -
rest/
- The RESTful endpoints using JAX-RS -
service/
- Handles persistence to and from the database using JPA
Within the resources/
subdirectory are:
-
META-INF/*
- JPA-related files defining database structure and initialization
This project exposes a single RESTful application defined in src/main/java/com/redhat/coolstore/rest/RestApplication.java
:
@ApplicationPath("/api")
public class RestApplication extends Application {
}
Then within InventoryEndpoint.java
in the same package a single endpoint is defined:
@GET
@Path("/{itemId}")
@Produces(MediaType.APPLICATION_JSON)
public Inventory getAvailability(@PathParam("itemId") String itemId) {
return inventoryService.getInventory(itemId);
}
Combining these two definitions results in an endpoint that can be accessed via an HTTP GET request. For example: GET /api/inventory/329299 to retrieve the inventory count for a product identified by 329299. You will do this many times in later labs.
The Maven POM file pom.xml
defines the structure of the project and how to build and run it. The major components of the POM file include:
<project>
-
Identifiers and descriptions of the project
<properties>
-
Maven directives and project values (such as versions) referenced later in the POM file
<build>
-
Directives for building the project.
<dependencies>
-
Defines the needed components for the app. The example app we start with simply contains a Java EE dependency, and once built can be deployed to any Java EE app server.
Later on you will add additional elements to the POM file, but for now this is rather simple.
To build the project, use Maven:
% mvn clean package
Depending on how populated your local maven repository is, this command may take several minutes to download the necessary bits.
This command will delete any previous builds and re-package the project into a standard Java EE web archive
(a .war
file). You should get a BUILD SUCCESS
message (if you do not, your build failed, and you should
figure out why before proceeding). Once built, the resulting war is located in the target/
directory:
% ls target/*.war target/inventory-1.0.0-SNAPSHOT.war
This is a standard Java EE web app that could be deployed to any Java EE app server (for example, JBoss EAP, or its upstream WildFly project).
WildFly Swarm offers an innovative approach to packaging and running Java EE applications by packaging them with just enough of the server runtime to "java -jar" your application. It’s MicroProfile compatible, too. And, it’s all much, much cooler than that, which you’ll soon discover. Let’s convert our app to use it!
In many cases (and in this case) you have an existing Java EE application that you want to convert to a WildFly Swarm app. The easiest way to get started is to simply add in the WildFly Swarm dependencies and let it auto-detect which fractions (app server components and libraries) it needs, resulting in an Uberjar containing your app and the dependencies it needs.
To build an initial WildFly Swarm app:
-
Open the
pom.xml
file -
Just after the end of the
<properties>…</properties>
section, add a new<dependencyManagement>
section below the<!-- Add dependency management here -->
comment:<dependencyManagement> <dependencies> <dependency> <groupId>org.wildfly.swarm</groupId> <artifactId>bom-all</artifactId> <version>${version.wildfly.swarm}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
-
Within the
<build> → <plugins>
section, add in the WildFly Swarm Maven Plugin as a new<plugin>
element immediately after the existing<plugin>…</plugin>
entry. Look for the<!-- Add additional <plugin>..</plugin> here -->
comment and add below it:<plugin> <groupId>org.wildfly.swarm</groupId> <artifactId>wildfly-swarm-plugin</artifactId> <version>${version.wildfly.swarm}</version> <executions> <execution> <goals> <goal>package</goal> </goals> </execution> </executions> </plugin>
-
Inside of the the
<properties>
section, below the<!-- Add additional properties here -->
line, add a new property and value:<version.wildfly.swarm>2017.8.1</version.wildfly.swarm>
-
Finally, you’ll need to define the data source used by the app (this is normally done through your app server, but in this case you are running outside of a traditional Java EE App server, so you’ll need to define it. Create a new file at
src/main/resources/project-defaults.yml
with the following content:
swarm:
logging: INFO
datasources:
data-sources:
InventoryDS:
driver-name: h2
connection-url: jdbc:h2:mem:inventory;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
user-name: sa
password: sa
This file is a YAML file that externalizes the runtime environment. For example, you may want to run the same project using a different database (one for testing, one for production). This file enables you to reconfigure the application without changing its source code. More information can be found in the WildFly Swarm documentation. We’ll re-visit this in later exercises.
Caution
|
YAML files are sensitive to indentation level for each line, so be sure to maintain the indentation level found in the snippet above! |
With all that done, it’s time to run your first WildFly Swarm Uberjar:
$ mvn clean package
You’ll see several lines of output, and see that WildFly Swarm will auto-detect the necessary components needed to run the app later:
[INFO] Detected fractions: cdi:2017.8.1, ejb:2017.8.1, jaxrs:2017.8.1, jpa:2017.8.1
After a BUILD SUCCESS
, in addition to the .war
file, WildFly Swarm creates an Uberjar
:
% ls target/*.jar
target/inventory-1.0.0-SNAPSHOT-swarm.jar
This file contains our project along with the necessary runtime to execute it. Let’s run the project using plain Java:
% java -jar target/inventory-1.0.0-SNAPSHOT-swarm.jar
You’ll see a lot of output, including the fractions that were loaded and output from the various fractions as they startup. If successful, you should see:
2017-07-12 08:37:28,615 INFO [org.wildfly.swarm] (main) WFSWARM99999: WildFly Swarm is Ready
This is your indication that the project is now running and ready to accept requests.
Note
|
In addition to using java -jar to run the project, you can equally use the Maven plugin.
For example, mvn wildfly-swarm:run . There are a number of features of the plugin that can be used
with WildFly Swarm to ease the developer burden of remembering complex command lines. See more information
in the docs.
|
Tip
|
In this project, we are referencing the WildFly Swarm Bill of Materials using: <groupId>org.wildfly.swarm</groupId>
<artifactId>bom-all</artifactId>
<version>${version.wildfly.swarm}</version> Using |
At this point, you should be able to access the RESTful endpoint. Let’s test it out using curl:
% curl http://localhost:8080/api/inventory/329299
{"itemId":"329299","location":"Raleigh","quantity":736,"link":"http://maps.google.com/?q=Raleigh"}
The RESTful endpoint returned a JSON object representing the inventory count for this product. Congratulations!
Stop the service by pressing CTRL-C in the terminal window.
Congratulations! You’ve just built your first WildFly Swarm app!
In some cases, autodetection will fail to detect some dependencies depending on which fractions you need. Longer term, it may make sense for you to maintain an explicit list of the fractions you need. In this exercise, you will add in the specific dependencies. In this example app, we are using a small set of Java EE features, and will need fractions for them.
-
Replace the entire
<dependencies>…</dependencies>
section inpom.xml
with the following content. Be sure you are NOT changing dependencies inside of the<dependencyManagement>
section. Only replace the dependencies section near the end of the file, that originally contained thejavaee-api
dependency:<dependencies> <dependency> <groupId>org.wildfly.swarm</groupId> <artifactId>jaxrs</artifactId> </dependency> <dependency> <groupId>org.wildfly.swarm</groupId> <artifactId>cdi</artifactId> </dependency> <dependency> <groupId>org.wildfly.swarm</groupId> <artifactId>ejb</artifactId> </dependency> <dependency> <groupId>org.wildfly.swarm</groupId> <artifactId>jpa</artifactId> </dependency> <dependency> <groupId>org.wildfly.swarm</groupId> <artifactId>datasources</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>${version.h2}</version> </dependency> </dependencies>
By declaring explicit fractions, WildFly Swarm will not attempt to auto-detect. In addition, since we’ve removed the Java EE API dependency, modern Java IDEs will be able to detect missing fractions when you’re developing new code.
-
Next, re-build the application:
$ mvn clean package
-
And re-run the project:
% java -jar target/inventory-1.0.0-SNAPSHOT-swarm.jar
-
And re-exercise the RESTful endpoint:
% curl http://localhost:8080/api/inventory/329299 {"itemId":"329299","location":"Raleigh","quantity":736,"link":"http://maps.google.com/?q=Raleigh"}
The resulting Uberjar will most likely be virtually identical, as the fractions we are using have good autodetection functionality, and were detected earlier as well as being explicitly included now.