Skip to content

Latest commit

 

History

History
408 lines (297 loc) · 16.1 KB

lab1-instructions.adoc

File metadata and controls

408 lines (297 loc) · 16.1 KB

Lab 1: Your first WildFly Swarm Project

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.

WildFly Swarm Logo WildFly Swarm Logo

Requirements
  • 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

Conventions
  • 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.

1. Clone the Repository

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.

1.1. If you get stuck during the labs

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:

  1. 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.

  2. Next, run git checkout solution to switch to the solution branch. Files in your working directory should now be the solution’s files.

  3. Proceed with the lab (e.g. do a build, run a command, whatever is required in the lab after changing source code)

  4. 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

2. Open lab1 using the IDE

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.

3. Examine the Project

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

4. Examine the REST endpoint

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.

5. Examine the Maven POM file

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.

6. Build the (non-WildFly Swarm) Java EE project

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!

7. Getting started with WildFly Swarm

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:

  1. Open the pom.xml file

  2. 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>
  3. 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>
  4. 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>
  5. 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!

7.1. Building and running the Uberjar

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 bom-all allows us to use any WildFly Swarm fraction, including experimental and deprecated fractions. Some projects may only wish to reference a subset (for example bom-stable) to avoid using experimental or deprecated fractions. See more information in the docs.

8. Test the REST endpoint

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!

9. Explicitly Declare Dependencies

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.

  1. Replace the entire <dependencies>…​</dependencies> section in pom.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 the javaee-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.

  2. Next, re-build the application:

    $ mvn clean package
  3. And re-run the project:

    % java -jar target/inventory-1.0.0-SNAPSHOT-swarm.jar
  4. 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.

10. Stop the service

To stop the service, simply press CTRL-C in the terminal window where the service is executing.

Caution
Be careful to not leave services running that you are no longer using in this course, as port conflicts may arise later on.