Red Hat Training

A Red Hat training course is available for Red Hat JBoss Enterprise Application Platform

1.4. Run Your First Application

1.4.1. Download the Quickstart Code Examples

1.4.1.1. Access the Quickstarts

Summary

JBoss EAP 6 comes with a series of quickstart examples designed to help users begin writing applications using the Java EE 6 technologies.

Prerequisites

Procedure 1.4. Download the Quickstarts

  1. Find "Quickstarts" in the list.
  2. Click the Download button to download a Zip archive containing the examples.
  3. Unzip the archive in a directory of your choosing.
Result

The JBoss EAP Quickstarts have been downloaded and unzipped. Refer to the README.md file in the top-level directory of the Quickstart archive for instructions about deploying each quickstart.

1.4.2. Run the Quickstarts

1.4.2.1. Run the Quickstarts in Red Hat JBoss Developer Studio

This section describes how to use Red Hat JBoss Developer Studio to deploy the quickstarts and run the Arquillian tests.

Procedure 1.5. Import the quickstarts into Red Hat JBoss Developer Studio

Each quickstart ships with a POM (Project Object Model) file that contains project and configuration information for the quickstart. Using this POM file, you can easily import the quickstart into Red Hat JBoss Developer Studio.

Important

If your quickstart project folder is located within the IDE workspace when you import it into Red Hat JBoss Developer Studio, the IDE generates an invalid project name and WAR archive name. Be sure your quickstart project folder is located outside the IDE workspace before you begin!
  1. Start Red Hat JBoss Developer Studio.
  2. From the menu, select FileImport.
  3. In the selection list, choose MavenExisting Maven Projects, then click Next.
    Import Existing Maven Projects

    Figure 1.7. Import Existing Maven Projects

  4. Browse to the directory of the quickstart you plan to test, for example the helloworld quickstart, and click OK. The Projects list box is populated with the pom.xml file of the selected quickstart project.
    Select Maven Projects

    Figure 1.8. Select Maven Projects

  5. Click Finish.

Procedure 1.6. Build and Deploy the helloworld quickstart

The helloworld quickstart is one of the simplest quickstarts and is a good way to verify that the JBoss server is configured and running correctly.
  1. If you do not see a Servers tab or have not yet defined a server, follow the instructions here: Section 1.3.1.5, “Add the JBoss EAP Server Using Define New Server”. If you plan to deploy a quickstart that requires the full profile or additional startup arguments, be sure to create the server runtime environment as noted in the quickstart instructions.
  2. Right-click on the jboss-helloworld project in the Project Explorer tab and select Run As. You are provided with a list of choices. Select Run on Server.
    Run As - Run on Server

    Figure 1.9. Run As - Run on Server

  3. Select JBoss EAP 6.1+ Runtime Server from the server list and click Next.
    Run on Server

    Figure 1.10. Run on Server

  4. The next screen displays the resources that are configured on the server. The jboss-helloworld quickstart is configured for you. Click Finish to deploy the quickstart.
    Modify Resources Configured on the Server

    Figure 1.11. Modify Resources Configured on the Server

  5. Review the results.
    • In the Server tab, the JBoss EAP 6.x Runtime Server status changes to [Started, Republish] .
    • The server Console tab shows messages detailing the JBoss EAP 6.x server start and the helloworld quickstart deployment.
    • A helloworld tab appears displaying the URL http://localhost:8080/jboss-helloworld/HelloWorld and the text "Hello World!".
    • The following messages in the Console confirm deployment of the jboss-helloworld.war file:
      JBAS018210: Register web context: /jboss-helloworld
      JBAS018559: Deployed "jboss-helloworld.war" (runtime-name : "jboss-helloworld.war")
      
      The registered web context is appended to http://localhost:8080 to provide the URL used to access the deployed application.
  6. To verify the helloworld quickstart deployed successfully to the JBoss server, open a web browser and access the application at this URL: http://localhost:8080/jboss-helloworld

Procedure 1.7. Run the bean-validation quickstart Arquillian tests

Some quickstarts do not provide a user interface layer and instead provide Arquillian tests to demonstrate the code examples. The bean-validation quickstart is an example of a quickstart that provides Arquillian tests.
  1. Follow the procedure above to import the bean-validation quickstart into Red Hat JBoss Developer Studio.
  2. In the Servers tab, right-click on the server and choose Start to start the JBoss EAP server. If you do not see a Servers tab or have not yet defined a server, follow the instructions here: Section 1.3.1.5, “Add the JBoss EAP Server Using Define New Server”.
  3. Right-click on the jboss-bean-validation project in the Project Explorer tab and select Run As. You are provided with a list of choices. Select Maven Build.
  4. In the Goals input field of the Edit Configuration dialog, type: clean test -Parq-jbossas-remote
    Then click Run.
    Edit Configuration

    Figure 1.12. Edit Configuration

  5. Review the results.
    The server Console tab shows messages detailing the JBoss EAP server start and the output of the bean-validation quickstart Arquillian tests.
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running org.jboss.as.quickstarts.bean_validation.test.MemberValidationTest
    Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.189 sec
    
    Results :
    
    Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
    
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    

1.4.2.2. Run the Quickstarts Using a Command Line

Procedure 1.8. Build and Deploy the Quickstarts Using a Command Line

You can easily build and deploy the quickstarts using a command line. Be aware that, when using a command line, you are responsible for starting the JBoss server if it is required.
  1. Review the README.html file in the root directory of the quickstarts.
    This file contains general information about system requirements, how to configure Maven, how to add users, and how to run the Quickstarts. Be sure to read through it before you get started.
    It also contains a table listing the available quickstarts. The table lists each quickstart name and the technologies it demonstrates. It gives a brief description of each quickstart and the level of experience required to set it up. For more detailed information about a quickstart, click on the quickstart name.
    Some quickstarts are designed to enhance or extend other quickstarts. These are noted in the Prerequisites column. If a quickstart lists prerequisites, you must install them first before working with the quickstart.
    Some quickstarts require the installation and configuration of optional components. Do not install these components unless the quickstart requires them.
  2. Run the helloworld quickstart.
    The helloworld quickstart is one of the simplest quickstarts and is a good way to verify that the JBoss server is configured and running correctly. Open the README.html file in the root of the helloworld quickstart. It contains detailed instructions on how to build and deploy the quickstart and access the running application
  3. Run the other quickstarts.
    Follow the instructions in the README.html file located in the root folder of each quickstart to run the example.

1.4.3. Review the Quickstart Tutorials

1.4.3.1. Explore the helloworld Quickstart

Summary

The helloworld quickstart shows you how to deploy a simple Servlet to JBoss EAP 6. The business logic is encapsulated in a service which is provided as a CDI (Contexts and Dependency Injection) bean and injected into the Servlet. This quickstart is very simple. All it does is print "Hello World" onto a web page. It is a good starting point to be sure you have configured and started your server properly.

Detailed instructions to build and deploy this quickstart using a command line can be found in the README.html file at the root of the helloworld quickstart directory. Here we show you how to use Red Hat JBoss Developer Studio to run the quickstart. This topic assumes you have installed Red Hat JBoss Developer Studio, configured Maven, and imported and successfully run the helloworld quickstart.
Prerequisites

Procedure 1.9. Examine the Directory Structure

The code for the helloworld quickstart can be found in the QUICKSTART_HOME/helloworld directory. The helloworld quickstart is comprised of a Servlet and a CDI bean. It also includes an empty beans.xml file which tells JBoss EAP 6 to look for beans in this application and to activate the CDI.
  1. The beans.xml file is located in the WEB-INF/ folder in the src/main/webapp/ directory of the quickstart.
  2. The src/main/webapp/ directory also includes an index.html file which uses a simple meta refresh to redirect the user's browser to the Servlet, which is located at http://localhost:8080/jboss-helloworld/HelloWorld.
  3. All the configuration files for this example are located in WEB-INF/, which can be found in the src/main/webapp/ directory of the example.
  4. Notice that the quickstart doesn't even need a web.xml file!

Procedure 1.10. Examine the Code

The package declaration and imports have been excluded from these listings. The complete listing is available in the quickstart source code.
  1. Review the HelloWorldServlet code

    The HelloWorldServlet.java file is located in the src/main/java/org/jboss/as/quickstarts/helloworld/ directory. This Servlet sends the information to the browser.
    42.  @SuppressWarnings("serial")
    43.  @WebServlet("/HelloWorld")
    44.  public class HelloWorldServlet extends HttpServlet {
    45.  
    46.      static String PAGE_HEADER = "<html><head><title>helloworld</title></head><body>";
    47.  
    48.      static String PAGE_FOOTER = "</body></html>";
    49.  
    50.      @Inject
    51.      HelloService helloService;
    52.  
    53.      @Override
    54.      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    55.          resp.setContentType("text/html");
    56.          PrintWriter writer = resp.getWriter();
    57.          writer.println(PAGE_HEADER);
    58.          writer.println("<h1>" + helloService.createHelloMessage("World") + "</h1>");
    59.          writer.println(PAGE_FOOTER);
    60.          writer.close();
    61.      }
    62.  
    63.  }
    

    Table 1.1. HelloWorldServlet Details

    Line Note
    43 Before Java EE 6, an XML file was used to register Servlets. It is now much cleaner. All you need to do is add the @WebServlet annotation and provide a mapping to a URL used to access the servlet.
    46-48 Every web page needs correctly formed HTML. This quickstart uses static Strings to write the minimum header and footer output.
    50-51 These lines inject the HelloService CDI bean which generates the actual message. As long as we don't alter the API of HelloService, this approach allows us to alter the implementation of HelloService at a later date without changing the view layer.
    58 This line calls into the service to generate the message "Hello World", and write it out to the HTTP request.
  2. Review the HelloService code

    The HelloService.java file is located in the src/main/java/org/jboss/as/quickstarts/helloworld/ directory. This service is very simple. It returns a message. No XML or annotation registration is required.
    public class HelloService {
    
        String createHelloMessage(String name) {
            return "Hello " + name + "!"; 
        }
    }
    

1.4.3.2. Explore the numberguess Quickstart

Summary

This quickstart shows you how to create and deploy a simple application to JBoss EAP 6. This application does not persist any information. Information is displayed using a JSF view, and business logic is encapsulated in two CDI (Contexts and Dependency Injection) beans. In the numberguess quickstart, you get 10 attempts to guess a number between 1 and 100. After each attempt, you're told whether your guess was too high or too low.

The code for the numberguess quickstart can be found in the QUICKSTART_HOME/numberguess directory. The numberguess quickstart is comprised of a number of beans, configuration files and Facelets (JSF) views, packaged as a WAR module.
Detailed instructions to build and deploy this quickstart using a command line can be found in the README.html file at the root of the numberguess quickstart directory. Here we show you how to use Red Hat JBoss Developer Studio to run the quickstart. This topic assumes you have installed Red Hat JBoss Developer Studio, configured Maven, and imported and successfully run the numberguess quickstart.
Prerequisites

Procedure 1.11. Examine the Configuration Files

All the configuration files for this example are located in WEB-INF/ directory which can be found in the src/main/webapp/ directory of the quickstart.
  1. Examine the faces-config.xml file.
    This quickstart uses the JSF 2.0 version of faces-config.xml filename. A standardized version of Facelets is the default view handler in JSF 2.0, so there's really nothing that you have to configure. JBoss EAP 6 goes above and beyond Java EE here. It will automatically configure the JSF for you if you include this configuration file. As a result, the configuration consists of only the root element:
    19. <faces-config version="2.0"
    20.    xmlns="http://java.sun.com/xml/ns/javaee"
    21.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    22.    xsi:schemaLocation="
    23.       http://java.sun.com/xml/ns/javaee>
    24.       http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
    25.      
    26. </faces-config>
    
  2. Examine the beans.xml file.
    There's also an empty beans.xml file, which tells JBoss EAP 6 to look for beans in this application and to activate the CDI.
  3. There is no web.xml file
    Notice that the quickstart doesn't even need a web.xml file!

Procedure 1.12. Examine the JSF Code

JSF uses the .xhtml file extension for source files, but serves up the rendered views with the .jsf extension.
  • Examine the home.xhtml code.
    The home.xhtml file is located in the src/main/webapp/ directory.
    19. <html xmlns="http://www.w3.org/1999/xhtml"
    20.    xmlns:ui="http://java.sun.com/jsf/facelets"
    21.    xmlns:h="http://java.sun.com/jsf/html"
    22.    xmlns:f="http://java.sun.com/jsf/core">
    23.
    24. <head>
    25. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    26. <title>Numberguess</title>
    27. </head>
    28.
    29. <body>
    30.    <div id="content">
    31.       <h1>Guess a number...</h1>
    32.       <h:form id="numberGuess">
    33.
    34.          <!-- Feedback for the user on their guess -->
    35.          <div style="color: red">
    36.             <h:messages id="messages" globalOnly="false" />
    37.             <h:outputText id="Higher" value="Higher!"
    38.                rendered="#{game.number gt game.guess and game.guess ne 0}" />
    39.             <h:outputText id="Lower" value="Lower!"
    40.                rendered="#{game.number lt game.guess and game.guess ne 0}" />
    41.          </div>
    42.
    43.          <!-- Instructions for the user -->
    44.          <div>
    45.             I'm thinking of a number between <span
    46.                id="numberGuess:smallest">#{game.smallest}</span> and <span
    47.                id="numberGuess:biggest">#{game.biggest}</span>. You have
    48.             #{game.remainingGuesses} guesses remaining.
    49.          </div>
    50.
    51.          <!-- Input box for the users guess, plus a button to submit, and reset -->
    52.          <!-- These are bound using EL to our CDI beans -->
    53.          <div>
    54.             Your guess:
    55.             <h:inputText id="inputGuess" value="#{game.guess}"
    56.                required="true" size="3"
    57.                disabled="#{game.number eq game.guess}"
    58.                validator="#{game.validateNumberRange}" />
    59.             <h:commandButton id="guessButton" value="Guess"
    60.                action="#{game.check}"
    61.                disabled="#{game.number eq game.guess}" />
    62.          </div>
    63.          <div>
    64.             <h:commandButton id="restartButton" value="Reset"
    65.                action="#{game.reset}" immediate="true" />
    66.          </div>
    67.       </h:form>
    68.
    69.    </div>
    70.
    71.    <br style="clear: both" />
    72.
    73. </body>
    74. </html>
    

    Table 1.2. JSF Details

    Line Note
    36-40 These are the messages which can be sent to the user: "Higher!" and "Lower!"
    45-48 As the user guesses, the range of numbers they can guess gets smaller. This sentence changes to make sure they know the number range of a valid guess.
    55-58 This input field is bound to a bean property using a value expression.
    58 A validator binding is used to make sure the user does not accidentally input a number outside of the range in which they can guess. If the validator was not here, the user might use up a guess on an out of bounds number.
    59-61 There must be a way for the user to send their guess to the server. Here we bind to an action method on the bean.

Procedure 1.13. Examine the Class Files

All of the numberguess quickstart source files can be found in the src/main/java/org/jboss/as/quickstarts/numberguess/ directory. The package declaration and imports have been excluded from these listings. The complete listing is available in the quickstart source code.
  1. Review the Random.java qualifier code.
    A qualifier is used to remove ambiguity between two beans, both of which are eligible for injection based on their type. For more information on qualifiers, refer to Section 11.2.3.3, “Use a Qualifier to Resolve an Ambiguous Injection”
    The @Random qualifier is used for injecting a random number.
    @Target({ TYPE, METHOD, PARAMETER, FIELD })
    @Retention(RUNTIME)
    @Documented
    @Qualifier
    public @interface Random {
    
    }
  2. Review the MaxNumber.java qualifier code.
    The @MaxNumberqualifier is used for injecting the maximum number allowed.
    @Target({ TYPE, METHOD, PARAMETER, FIELD })
    @Retention(RUNTIME)
    @Documented
    @Qualifier
    public @interface MaxNumber {
    
    }
  3. Review the Generator.java code.
    The Generator class is responsible for creating the random number via a producer method. It also exposes the maximum possible number via a producer method. This class is application scoped so you don't get a different random each time.
    @SuppressWarnings("serial")
    @ApplicationScoped
    public class Generator implements Serializable {
    
        private java.util.Random random = new java.util.Random(System.currentTimeMillis());
    
        private int maxNumber = 100;
    
        java.util.Random getRandom() {
            return random;
        }
    
        @Produces
        @Random
        int next() {
            // a number between 1 and 100
            return getRandom().nextInt(maxNumber - 1) + 1;
        }
    
        @Produces
        @MaxNumber
        int getMaxNumber() {
            return maxNumber;
        }
    }
  4. Review the Game.java code.
    The session scoped class Game is the primary entry point of the application. It is responsible for setting up or resetting the game, capturing and validating the user's guess, and providing feedback to the user with a FacesMessage. It uses the post-construct lifecycle method to initialize the game by retrieving a random number from the @Random Instance<Integer> bean.
    Notice the @Named annotation in the class. This annotation is only required when you want to make the bean accessible to a JSF view via Expression Language (EL), in this case #{game}.
    @SuppressWarnings("serial")
    @Named
    @SessionScoped
    public class Game implements Serializable {
    
        /**
         * The number that the user needs to guess
         */
        private int number;
    
        /**
         * The users latest guess
         */
        private int guess;
    
        /**
         * The smallest number guessed so far (so we can track the valid guess range).
         */
        private int smallest;
    
        /**
         * The largest number guessed so far
         */
        private int biggest;
    
        /**
         * The number of guesses remaining
         */
        private int remainingGuesses;
    
        /**
         * The maximum number we should ask them to guess
         */
        @Inject
        @MaxNumber
        private int maxNumber;
    
        /**
         * The random number to guess
         */
        @Inject
        @Random
        Instance<Integer> randomNumber;
    
        public Game() {
        }
    
        public int getNumber() {
            return number;
        }
    
        public int getGuess() {
            return guess;
        }
    
        public void setGuess(int guess) {
            this.guess = guess;
        }
    
        public int getSmallest() {
            return smallest;
        }
    
        public int getBiggest() {
            return biggest;
        }
    
        public int getRemainingGuesses() {
            return remainingGuesses;
        }
    
        /**
         * Check whether the current guess is correct, and update the biggest/smallest guesses as needed. Give feedback to the user
         * if they are correct.
         */
        public void check() {
            if (guess > number) {
                biggest = guess - 1;
            } else if (guess < number) {
                smallest = guess + 1;
            } else if (guess == number) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Correct!"));
            }
            remainingGuesses--;
        }
    
        /**
         * Reset the game, by putting all values back to their defaults, and getting a new random number. We also call this method
         * when the user starts playing for the first time using {@linkplain PostConstruct @PostConstruct} to set the initial
         * values.
         */
        @PostConstruct
        public void reset() {
            this.smallest = 0;
            this.guess = 0;
            this.remainingGuesses = 10;
            this.biggest = maxNumber;
            this.number = randomNumber.get();
        }
    
        /**
         * A JSF validation method which checks whether the guess is valid. It might not be valid because there are no guesses left,
         * or because the guess is not in range.
         * 
         */
        public void validateNumberRange(FacesContext context, UIComponent toValidate, Object value) {
            if (remainingGuesses <= 0) {
                FacesMessage message = new FacesMessage("No guesses left!");
                context.addMessage(toValidate.getClientId(context), message);
                ((UIInput) toValidate).setValid(false);
                return;
            }
            int input = (Integer) value;
    
            if (input < smallest || input > biggest) {
                ((UIInput) toValidate).setValid(false);
    
                FacesMessage message = new FacesMessage("Invalid guess");
                context.addMessage(toValidate.getClientId(context), message);
            }
        }
    }

1.4.4. Replace the Default Welcome Web Application

JBoss EAP 6 includes a Welcome application, which displays when you open the URL of the server at port 8080. You can replace this application with your own web application by following this procedure.

Procedure 1.14. Replace the Default Welcome Web Application With Your Own Web Application

  1. Disable the Welcome application.

    Use the Management CLI script EAP_HOME/bin/jboss-cli.sh to run the following command. You may need to change the profile to modify a different managed domain profile, or remove the /profile=default portion of the command for a standalone server.
    /profile=default/subsystem=web/virtual-server=default-host:write-attribute(name=enable-welcome-root,value=false)
  2. Configure your Web application to use the root context.

    To configure your web application to use the root context (/) as its URL address, modify its jboss-web.xml, which is located in the META-INF/ or WEB-INF/ directory. Replace its <context-root> directive with one that looks like the following.
    <jboss-web>
        <context-root>/</context-root>
    </jboss-web>
  3. Deploy your application.

    Deploy your application to the server group or server you modified in the first step. The application is now available on http://SERVER_URL:PORT/.

1.4.5. Using WS-AtomicTransaction

The wsat-simple quickstart demonstrates the deployment of a WS-AT (WS-AtomicTransaction) enabled JAX-WS Web Service bundled in a WAR archive for deployment to Red Hat JBoss Enterprise Application Platform.
The Web service is offered by a Restaurant for making bookings. The Service allows bookings to be made within an Atomic Transaction. This example demonstrates the basics of implementing a WS-AT enabled Web service. It is beyond the scope of this quick start to demonstrate more advanced features. In particular:
  • The Service does not implement the required hooks to support recovery in the presence of failures.
  • It also does not utilize a transactional back end resource.
  • Only one Web service participates in the protocol. As WS-AT is a 2PC coordination protocol, it is best suited to multi-participant scenarios.
For a more complete example, refer the XTS demonstrator application that ships with the Narayana project: http://www.jboss.org/narayana.
It is also assumed that you have an understanding of WS-AtomicTransaction. For more details, read the XTS documentation that ships with the Narayana project, which can be downloaded here: http://www.jboss.org/narayana/documentation/4174_Final.
The application consists of a single JAX-WS web service that is deployed within a WAR archive. It is tested with a JBoss Arquillian enabled JUnit test.
When running the org.jboss.as.quickstarts.wsat.simple.ClientTest#testCommit() method, the following steps occur:
  1. A new Atomic Transaction (AT) is created by the client.
  2. An operation on a WS-AT enabled Web service is invoked by the client.
  3. The JaxWSHeaderContextProcessor in the WS Client handler chain inserts the WS-AT context into the outgoing SOAP message.
  4. When the service receives the SOAP request, the JaxWSHeaderContextProcessor in its handler chain inspects the WS-AT context and associates the request with this AT.
  5. The Web service operation is invoked.
  6. A participant is enlisted in this AT. This allows the Web Service logic to respond to protocol events, such as Commit and Rollback.
  7. The service invokes the business logic. In this case, a booking is made with the restaurant.
  8. The backend resource is prepared. This ensures that the Backend resource can undo or make permanent the change when told to do so by the coordinator.
  9. The client can then decide to commit or rollback the AT. If the client decides to commit, the coordinator will begin the 2PC protocol. If the participant decides to rollback, all participants will be told to rollback.
There is another test that shows what happens if the client decides to rollback the AT.