[[Getting_Started_Developing_Applications_Presentation_Demo]] = Getting Started Developing Applications Presentation & Demo This document is a "script" for use with the quickstarts associated with the link:Getting_Started_Developing_Applications_Guide.html[Getting Started Developing Applications Guide]. It can be used as the basis for demoing/explaining the Java EE 6 programming model with JBoss AS 7. There is an associated presentation – JBoss AS - Getting Started Developing Applications – which can be used to introduce the Java EE 6 ecosystem. The emphasis here is on the programming model, not on OAM/dev-ops, performance etc. [[prerequisites-for-using-the-script]] == Prerequisites for using the script * JBoss AS 7 downloaded and installed * Eclipse Indigo with m2eclipse and JBoss Tools installed * The quickstarts downloaded and imported into Eclipse * Make sure `$JBOSS_HOME` is set. * Make sure `src/test/resources/arquillian.xml` has the correct path to your JBoss AS install for kitchensink * Make sure your font size is set in Eclipse so everyone can read the text! [[import-examples-into-eclipse-and-set-up-jboss-as]] == Import examples into Eclipse and set up JBoss AS TODO [[the-helloworld-quickstart]] == The Helloworld Quickstart [[introduction-1]] === Introduction This quickstart is extremely basic, and is really useful for nothing more than showing than the app server is working properly, and our deployment mechanism is working. We recommend you use this quickstart to demonstrate the various ways you can deploy apps to JBoss AS 7. [[using-maven]] === Using Maven 1. Start JBoss AS 7 from the console + [source, java] ---- $JBOSS_HOME/bin/standalone.sh ---- * Deploy the app using Maven + [source, java] ---- mvn clean package jboss-as:deploy ---- [IMPORTANT] The quickstarts use the jboss-as maven plugin to deploy and undeploy applications. This plugin uses the JBoss AS Native Java Detyped Management API to communicate with the server. The Detyped API is used by management tools to control an entire domain of servers, and exposes only a small number of types, allowing for backwards and forwards compatibility. Show the app has deployed in the terminal Visit http://localhost:8080/jboss-as-helloworld Undeploy the app using Maven [source, java] ---- mvn jboss-as:undeploy ---- [[using-the-command-line-interface-cli]] === Using the Command Line Interface (CLI) 1. Start JBoss AS 7 from the console (if not already running) + [source, java] ---- $JBOSS_HOME/bin/standalone.sh ---- Build the war [source, java] ---- mvn clean package ---- Start the CLI [source, java] ---- $JBOSS_HOME/bin/jboss-admin.sh --connect ---- [IMPORTANT] The command line also uses the Deptyped Management API to communicate with the server. It's designed to be as "unixy" as possible, allowing you to "cd" into nodes, with full tab completion etc. The CLI allows you to deploy and undeploy applications, create JMS queues, topics etc., create datasources (normal and XA). It also fully supports the domain node. Deploy the app [source, java] ---- deploy target/jboss-as-helloworld.war ---- Show the app has deployed [source, java] ---- undeploy jboss-as-helloworld.war ---- [[using-the-web-management-interface]] === Using the web management interface 1. Start JBoss AS 7 from the console (if not already running) + [source, java] ---- $JBOSS_HOME/bin/standalone.sh ---- Build the war [source, java] ---- mvn clean package ---- Open up the web management interface http://localhost:9990/console [IMPORTANT] The web maangement interface offers the same functionality as the CLI (and again uses the Detyped Management API), but does so using a pretty GWT interface! You can set up virtual servers, interrogate sub systems and more. Navigate `Manage Deployments -> Add content`. Click on choose file and locate `helloworld/target/jboss-as-helloworld.war`. Click `Next` and `Finish` to upload the war to the server. Now click `Enable` and `Ok` to start the application Switch to the console to show it deployed Now click `Remove` [[using-the-filesystem]] === Using the filesystem 1. Start JBoss AS 7 from the console (if not already running) + [source, java] ---- $JBOSS_HOME/bin/standalone.sh ---- Build the war [source, java] ---- mvn clean package ---- [IMPORTANT] Of course, you can still use the good ol' file system to deploy. Just copy the file to `$JBOSS_HOME/standalone/deployments`. Copy the war [source, java] ---- cp target/jboss-as-helloworld.war $JBOSS_HOME/standalone/deployments ---- Show the war deployed [IMPORTANT] The filesystem deployment uses marker files to indicate the status of a deployment. As this deployment succeeded we get a `$JBOSS_HOME/standalone/deployments/jboss-as-helloworld.war.deployed` file. If the deployment failed, you would get a `.failed` file etc. Undeploy the war [source, java] ---- rm $JBOSS_HOME/standalone/deployments/jboss-as-helloworld.war.deployed ---- Show the deployment stopping! Start and stop the appserver, show that the deployment really is gone! [IMPORTANT] This gives you much more precise control over deployments than before [[using-eclipse]] === Using Eclipse . Add a JBoss AS server .. Bring up the Server view .. Right click in it, and choose `New -> Server` . Choose JBoss AS 7.0 and hit Next .. Locate the server on your disc .. Hit Finish . Start JBoss AS in Eclipse .. Select the server .. Click the Run button .. Deploy the app . right click on the app, choose `Run As -> Run On Server` .. Select the AS 7 instance you want to use .. Hit finish . Load the app at http://localhost:8080/jboss-as-helloworld [[digging-into-the-app]] === Digging into the app 1. Open up the helloworld quickstart in Eclipse, and open up `src/main/webapp`. 2. Point out that we don't require a `web.xml` anymore! 3. Show `beans.xml` and explain it's a marker file used to JBoss AS to enable CDI (open it, show that it is empty) 4. Show `index.html`, and explain it is just used to kick the user into the app (open it, show the meta-refresh) 5. Open up the `pom.xm` - and emphasise that it's pretty simple. .. There is no parent pom, everything for the build is *here* .. Show that we are enabling the JBoss Maven repo - explain you can do this in your POM or in system wide ( `settings.xml`) .. Show the `dependencyManagement` section. Here we import the JBoss AS 7 Web Profile API. Explain that this gives you all the versions for all of the JBoss AS 7 APIs that are in the web profile. Explain we could also depend on this directly, which would give us the whole set of APIs, but that here we've decided to go for slightly tighter control and specify each dependency ourselves .. Show the import for CDI, JSR-250 and Servlet API. Show that these are all provided - we are depending on build in server implementations, not packaging this stuff! .. Show the plugin sections - nothing that exciting here, the war plugin is out of date and requires you to provide `web.xml` icon:smile-o[role="yellow"] , configure the JBoss AS Maven Plugin, set the Java version to 6. 6. Open up `src/main/java` and open up the `HelloWorldServlet`. .. Point out the `@WebServlet` - explain this one annotation removes about 8 lines of XML - no need to separately map a path either. This is much more refactor safe .. Show that we can inject services into a Servlet .. Show that we use the service (line 41) + #Cmd-click on `HelloService` .. This is a CDI bean - very simple, no annotations required! .. Explain injection ... Probably used to string based bean resolution ... This is typesafe (refactor safe, take advantage of the compiler and the IDE - we just saw that!) ... When CDI needs to inject something, the first thing it looks at is the type - and if the type of the injection point is assignable from a bean, CDI will inject that bean [[the-numberguess-quickstart]] == The numberguess quickstart [[introduction-2]] === Introduction This quickstart adds in a "complete" view layer into the mix. Java EE ships with a JSF. JSF is a server side rendering, component orientated framework, where you write markup using an HTML like language, adding in dynamic behavior by binding components to beans in the back end. The quickstart also makes more use of CDI to wire the application together. [[run-the-app]] === Run the app . Start JBoss AS in Eclipse . Deploy it using Eclipse - just right click on the app, choose `Run As -> Run On Server` . Select the AS 7 instance you want to use . Hit finish . Load the app at http://localhost:8080/jboss-as-numberguess . Make a few guesses [[deployment-descriptors-srcmainwebappweb-inf]] === Deployment descriptors src/main/webapp/WEB-INF Emphasize the lack of them! No need to open any of them, just point them out 1. `web.xml` - don't need it! 2. `beans.xml` - as before, marker file 3. `faces-config.xml` - nice feature from AS7 - we can just put `faces-config.xml` into the WEB-INF and it enables JSF (inspiration from CDI) 4. `pom.xml` we saw this before, this time it's the same but adds in JSF API [[views]] === Views . `index.html` - same as before, just kicks us into the app . `home.xhtml` .. Lines 19 - 25 – these are messages output depending on state of beans (minimise coupling between controller and view layer by interrogating state, not pushing) . Line 20 – output any messages pushed out by the controller . Line 39 - 42 – the input field is bound to the guess field on the game bean. We validate the input by calling a method on the game bean. . Line 43 - 45 – the command button is used to submit the form, and calls a method on the game bean . Line 48, 49, The reset button again calls a method on the game bean [[beans]] === Beans . `Game.java` – this is the main controller for the game. App has no persistence etc. .. `@Named` – As we discussed CDI is typesafe, (beans are injected by type) but sometimes need to access in a non-typesafe fashion. @Named exposes the Bean in EL - and allows us to access it from JSF .. `@SessionScoped` – really simple app, we keep the game data in the session - to play two concurrent games, need two sessions. This is not a limitation of CDI, but simply keeps this demo very simple. CDI will create a bean instance the first time the game bean is accessed, and then always load that for you .. `@Inject maxNumber` – here we inject the maximum number we can guess. This allows us to externalize the config of the game .. `@Inject rnadomNumber` – here we inject the random number we need to guess. Two things to discuss here .. Instance - normally we can inject the object itself, but sometimes it's useful to inject a "provider" of the object (in this case so that we can get a new random number when the game is reset!). Instance allows us to `get()` a new instance when needed .. Qualifiers - now we have two types of Integer (CDI auto-boxes types when doing injection) so we need to disambiguate. Explain qualifiers and development time approach to disambiguation. You will want to open up `@MaxNumber` and `@Random` here. .. `@PostConstruct` – here is our reset method - we also call it on startup to set up initial values. Show use of `Instance.get()`. . `Generator.java` This bean acts as our random number generator. . `@ApplicationScoped` explain about other scopes available in CDI + extensibility. .. `next()` Explain about producers being useful for determining bean instance at runtime .. `getMaxNumber()` Explain about producers allowing for loose coupling [[the-login-quickstart]] == The login quickstart [[introduction-3]] === Introduction The login quickstart builds on the knowledge of CDI and JSF we have got from numberguess. New stuff we will learn about is how to use JPA to store data in a database, how to use JTA to control transactions, and how to use EJB for declarative TX control. [[run-the-app-1]] === Run the app 1. Start JBoss AS in Eclipse 2. Deploy it using Eclipse - just right click on the app, choose `Run As -> Run On Server` 3. Select the AS 7 instance you want to use 4. Hit finish 5. Load the app at http://localhost:8080/jboss-as-login 6. Login as admin/admin 7. Create a new user [[deployment-descriptors]] === Deployment Descriptors . Show that we have the same ones we are used in `src/main/webapp` – `beans.xml`, `faces-config.xml` . We have a couple of new ones in `src/main/resources` .. `persistence.xml`. Not too exciting. We are using a datasource that AS7 ships with. It's backed by the H2 database and is purely a sample datasource to use in sample applications. We also tell Hibernate to auto-create tables - as you always have. .. `import.sql` Again, the same old thing you are used to in Hibernate - auto-import data when the app starts. . `pom.xml` is the same again, but just adds in dependencies for JPA, JTA and EJB [[views-1]] === Views . `template.xhtml` One of the updates added to JSF 2.0 was templating ability. We take advantage of that in this app, as we have multiple views .. Actually nothing too major here, we define the app "title" and we could easily define a common footer etc. (we can see this done in the kitchensink app) .. The `ui:insert` command inserts the actual content from the templated page. + # `home.xhtml` .. Uses the template .. Has some input fields for the login form, button to login and logout, link to add users. .. Binds fields to credentials bean}} .. Buttons link to login bean which is the controller . `users.xhtml` .. Uses the template .. Displays all users using a table .. Has a form with input fields to add users. .. Binds fields to the newUser bean .. Methods call on userManager bean [[beans-1]] === Beans . `Credentials.java` Backing bean for the login form field, pretty trivial. It's request scoped (natural for a login field) and named so we can get it from JSF. . `Login.java` .. Is session scoped (a user is logged in for the length of their session or until they log out}} .. Is accessible from EL .. Injects the current credentials .. Uses the userManager service to load the user, and sends any messages to JSF as needed .. Uses a producer method to expose the @LoggedIn user (producer methods used as we don't know which user at development time) . `User.java` Is a pretty straightforward JPA entity. Mapped with `@Entity`, has an natural id. . `UserManager.java` This is an interface, and by default we use the ManagedBean version, which requires manual TX control . `ManagedBeanUserManager.java` - accessible from EL, request scoped. .. Injects a logger (we'll see how that is produced in a minute) .. Injects the entity manager (again, just a min) .. Inject the UserTransaction (this is provided by CDI) .. `getUsers()` standard JPA-QL that we know and love - but lots of ugly TX handling code. .. Same for `addUser()` and `findUser()` methods - very simple JPA but... .. Got a couple of producer methods. ... `getUsers()` is obvious - loads all the users in the database. No ambiguity - CDI takes into account generic types when injecting. Also note that CDI names respect JavaBean naming conventions ... `getNewUser()` is used to bind the new user form to from the view layer - very nice as it decreases coupling - we could completely change the wiring on the server side (different approach to creating the newUser bean) and no need to change the view layer. . `EJBUserManager.java` .. It's an alternative – explain alternatives, and that they allow selection of beans at deployment time .. Much simple now we have declarative TX control. .. Start to see how we can introduce EJB to get useful enterprise services such as declarative TX control . `Resources.java` .. `{EntityManager}` - explain resource producer pattern [[the-kitchensink-quickstart]] == The kitchensink quickstart [[introduction-4]] === Introduction The kitchensink quickstart is generated from an archetype available for JBoss AS (tell people to check the link:/pages/createpage.action?spaceKey=WFLY&title=Getting+Started+Developing+Applications&linkCreation=true&fromPageId=557131[Getting Started Developing Applications] Guide for details). It demonstrates CDI, JSF, EJB, JPA (which we've seen before) and JAX-RS and Bean Validation as well. We add in Arquillian for testing. [[run-the-app-2]] === Run the app 1. Start JBoss AS in Eclipse 2. Deploy it using Eclipse - just right click on the app, choose `Run As -> Run On Server` 3. Select the AS 7 instance you want to use 4. Hit finish 5. Load the app at http://localhost:8080/jboss-as-kitchensink 6. Register a member - make sure to enter an invalid email and phone - show bean validation at work 7. Click on the member URL and show the output from JAX-RS [[bean-validation]] === Bean Validation . Explain the benefits of bean validation - need your data always valid (protect your data) AND good errors for your user. BV allows you to express once, apply often. . `index.xhtml` .. Show the input fields – no validators attached .. Show the message output . `Member.java` ... Hightlight the various validation annotations . Java EE automatically applies the validators in both the persistence layer and in your views [[jax-rs]] === JAX-RS . `index.xhtml` - Show that URL generation is just manual . `JaxRsActivator.java` - simply activates JAX-RS . `Member.java` - add JAXB annotation to make JAXB process the class properly . `MemberResourceRESTService.java` .. `@Path` sets the JAX-RS resource .. JAX-RS services can use injection .. `@GET` methods are auto transformed to XML using JAXB . And that is it! [[arquillian]] === Arquillian 1. Make sure JBoss AS is running 2. [source, bash] ---- mvn clean test -Parq-jbossas-remote ---- 1. Explain the difference between managed and remote Make sure JBoss AS is stopped [source, bash] ---- mvn clean test -Parq-jbossas-managed ---- Start JBoss AS in Eclipse Update the project to use the `arq-jbossas-remote` profile Run the test from Eclipse 1. Right click on test, `Run As -> JUnit Test` `MemberRegistrationTest.java` 1. Discuss micro deployments 2. Explain Arquilian allows you to use injection 3. Explain that Arquillian allows you to concentrate just on your test logic