$JBOSS_HOME/bin/standalone.sh
This document is a “script” for use with the quickstarts associated with the 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.
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!
TODO
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.
Start JBoss AS 7 from the console
$JBOSS_HOME/bin/standalone.sh
Deploy the app using Maven
mvn clean package jboss-as:deploy
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
Undeploy the app using Maven
mvn jboss-as:undeploy
Start JBoss AS 7 from the console (if not already running)
$JBOSS_HOME/bin/standalone.sh
Build the war
mvn clean package
Start the CLI
$JBOSS_HOME/bin/jboss-admin.sh --connect
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
deploy target/jboss-as-helloworld.war
Show the app has deployed
undeploy jboss-as-helloworld.war
Start JBoss AS 7 from the console (if not already running)
$JBOSS_HOME/bin/standalone.sh
Build the war
mvn clean package
Open up the web management interface http://localhost:9990/console
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
Start JBoss AS 7 from the console (if not already running)
$JBOSS_HOME/bin/standalone.sh
Build the war
mvn clean package
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
cp target/jboss-as-helloworld.war $JBOSS_HOME/standalone/deployments
Show the war deployed
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
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!
This gives you much more precise control over deployments than before
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
Open up the helloworld quickstart in Eclipse, and open up src/main/webapp.
Point out that we don't require a web.xml anymore!
Show beans.xml and explain it's a marker file used to JBoss AS to enable CDI (open it, show that it is empty)
Show index.html, and explain it is just used to kick the user into the app (open it, show the meta-refresh)
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
, configure the JBoss AS Maven Plugin, set the Java version to 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
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.
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
Emphasize the lack of them!
No need to open any of them, just point them out
web.xml - don't need it!
beans.xml - as before, marker file
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)
pom.xml we saw this before, this time it's the same but adds in JSF API
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
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 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.
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-login
Login as admin/admin
Create a new user
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
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
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 is generated from an archetype available for JBoss AS (tell people to check the 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.
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-kitchensink
Register a member - make sure to enter an invalid email and phone - show bean validation at work
Click on the member URL and show the output from JAX-RS
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
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!
Make sure JBoss AS is running
mvn clean test -Parq-jbossas-remote
Explain the difference between managed and remote
Make sure JBoss AS is stopped
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
Right click on test, Run As -> JUnit Test
MemberRegistrationTest.java
Discuss micro deployments
Explain Arquilian allows you to use injection
Explain that Arquillian allows you to concentrate just on your test logic