Purpose and Target Audience
The target audience for this tutorial are those individuals who do not yet have a great deal of experience with:
-
Eclipse + JBoss Tools (JBoss Developer Studio)
-
JBoss Enterprise Application 6 or JBoss AS 7
-
Java EE 6 features like JAX-RS
-
HTML5 & jQuery for building an mobile web front-end.
This tutorial sets the stage for the creation of TicketMonster - our sample application that illustrates how to bring together the best features of Java EE 6 + HTML5 + JBoss to create a rich, mobile-optimized and dynamic application.
TicketMonster is developed as an open source application, and you can find it at github.
If you prefer to watch instead of read, a large portion of this content is also covered in video form.
In this tutorial, we will cover the following topics:
-
Working with JBoss Developer Studio (Eclipse + JBoss Tools)
-
Creating of a Java EE 6 project via a Maven archetype
-
Leveraging m2e and m2e-wtp
-
Using Forge to create a JPA entity
-
Using Hibernate Tools
-
Database Schema Generation
-
Deployment to a local JBoss Server
-
Adding a JAX-RS endpoint
-
Adding a jQuery Mobile client
-
Using the Mobile BrowserSim
Installation
The first order of business is to get your development environment setup and JBoss Developer Studio v5 installed. JBoss Developer Studio is Eclipse Indigo (3.7.2) for Java EE Developers plus select JBoss Tools and is available for free. Visit http://www.jboss.org/tools/download/ to download it. You may also choose to install JBoss Tools 3.3 into your existing Eclipse Indigo for Java EE Developers. This document uses screenshots depicting JBoss Developer Studio.
You must have a Java Development Kit (JDK) installed, either v6 or v7 will work - whilst a JVM runtime will work for most use cases, for a developer environment it is normally best to have the full JDK. System requirements for JBoss Developer Studio are listed in the System Requirements chapter of the JBoss Developer Studio 5.0 Getting Started Guide online documentation.
|
If you prefer to see JBoss Developer studio being installed, then check out this video. To see JBoss Tools being intalled into Eclipse Indigo, see this video. |
The JBoss Developer Studio installer has a (very long!) name such as jbdevstudio-product-universal-5.0.0.v201204301418M-H119.jar where the latter portion of the file name relates to build date and version information and the text near the front related to the target operating system. The "universal" installer is for any operating system. To launch the installer you may simply be able to double-click on the .jar file name or you may need to issue the following from the operating system command line:
java -jar jbdevstudio-product-universal-5.0.0.v201204301418M-H119.jar
We recommend using the "universal" installer as it handles Windows, Mac OS X and Linux - 32-bit and 64-bit versions.
|
Even if you are installing on a 64-bit OS, you may still wish to use the 32-bit JVM for the JBoss Developer Studio (or Eclipse + JBoss Tools). Only the 32-bit version provides the Visual Page Editor - a split-pane editor that gives you a glimpse of what your HTML/XHTML (JSF, JSP, etc) will look like. Also, the 32-bit version uses less memory than the 64-bit version. You may still run your application server in 64-bit JVMs if needed to insure compatibility with the production environment whilst keeping your IDE in 32-bit mode. |
The rest of the steps are fairly self explanatory. If you run into trouble, please consult the videos above as they explore a few troubleshooting tips related to JRE/JDK setup.
Please make sure to say Yes to the prompt that says "Will you allow JBoss Tools team to receive anonymous usage statistics for this Eclipse instance with JBoss Tools?". This information is very helpful to us when it comes to prioritizing our QA efforts in terms of operating system platforms. More information concerning our usage tracking can be found at http://www.jboss.org/tools/usage
You can skip the step in the installation wizard that allows you to install JBoss Enterprise Application Platform 6 or JBoss AS 7 as we will do this in the next step.
Creating a new Java EE 6 project with Maven
|
For a deeper dive into the world of Maven and how it is used with JBoss Developer Studio 5 and JBoss Enterprise Application Platform 6 (or JBoss Tools 3.3 and JBoss AS 7) review link: this video. |
Now that everything is properly installed, configured, running and verified to work, let’s build something "from scratch".
We recommend that you switch to the JBoss Perspective if you have not already.
|
If you close JBoss Central, it is only a click away - simply click on the JBoss icon in the Eclipse toolbar - it is normally the last icon, on the last row - assuming you are in the JBoss Perspective. |
First, select Create Projects → Java EE Web Project in JBoss Central. Under the covers, this uses a Maven archetype which creates a Java EE 6 web application (.war), based around Maven. The project can be built outside of the IDE, and in continuous integration solutions like Hudson/Jenkins.
You will be prompted with a dialog box that verifies that JBoss Developer Studio is configured correctly. If you are in a brand new workspace, the application server will not be configured yet and you will notice the lack of a check mark on the server/runtime row.
|
There are several ways to add JBoss Enterprise Application Platform 6 or JBoss AS 7 to JBoss Developer Studio. The Install… button on the new project wizard is probably the easiest, but you can use any of the methods you are familiar with! |
To add JBoss Enterprise Application Platform or JBoss AS 7, click on the Install… button, or if you have not yet downloaded and unzipped the server, click on the Download and Install… button.
|
The download option only works with the community application server. |
Selecting Install… will pop up the JBoss Runtime Detection section of Preferences. You can always get back to this dialog by selecting Preferences → JBoss Tools → JBoss Tools Runtime Detection.
Select the Add button which will take you to a file browser dialog where you should locate your unzipped JBoss server.
Select Open and JBoss Developer Studio will pop up the Searching for runtimes… window.
Simply select OK. You should see the added runtime in the Paths list.
Select OK to close the Preferences dialog, and you will be returned to the New Project Example dialog, with the the server/runtime found.
Select Next.
The default Project name is jboss-javaee6-webapp. If this field appears blank, it is because your workspace already contains a "jboss-javaee6-webapp" in which case just provide another name for your project. Change the project name to ticket-monster, and the package name to org.jboss.jdf.example.ticketmonster.
The Target Runtime allows you to choose between JBoss Enterprise Application Platform and JBoss AS 7. If it is left empty, JBoss AS 7 will be elected.
Select Finish.
JBoss Tools/JBoss Developer Studio will now generate the template project and import it into the workspace. You will see it pop up into the Project Explorer and a message that asks if you would like to review the readme file.
Select Finish
Exploring the newly generated project
Using the Project Explorer, open up the generated project, and double-click on the pom.xml.
The generated project is a Maven-based project with a pom.xml in its root directory.
JBoss Developer Studio and JBoss Tools include m2e and m2e-wtp. m2e is the Maven Eclipse plug-in and provides a graphical editor for editing pom.xml files, along with the ability to run maven goals directly from within Eclipse. m2e-wtp allows you to deploy your Maven-based project directly to any Web Tools Project (WTP) compliant application server. This means you can drag & drop, use Run As → Run on Server and other mechanisms to have the IDE deploy your application.
The pom.xml editor has several tabs along its bottom edge.
For this tutorial, we do not need to edit the pom.xml as it already provides the Java EE 6 APIs that we will need (e.g. JPA, JAX-RS, CDI). You should spend some time exploring the Dependencies and the pom.xml (source view) tabs.
One key element to make note of is <jboss.bom.version>1.0.0.M6</jboss.bom.version> which establishes if this project uses JBoss Enterprise Application Platform or JBoss AS dependencies. The BOM (Bill of Materials) specifies the versions of the Java EE (and other) APIs defined in the dependency section.
If you are using JBoss Enterprise Application Platform 6 and you selected that as your Target Runtime, you will find a -redhat-1 suffix on the version string.
|
The specific version (e.g. 1.0.0.M6) is very likely to change, so do not be surprised if the version is slightly different. |
Using the Project Explorer, drill-down into src/main/java under Java Resources.
The initial project includes the following Java packages:
- .controller
-
contains the backing beans for #{newMember} and #{memberRegistration} in the JSF page index.xhtml
- .data
-
contains a class which uses @Produces and @Named to return the list of members for index.xhtml
- .model
-
contains the JPA entity class, a POJO annotated with @Entity, annodated with Bean Validation (JSR 303) constraints
- .rest
-
contains the JAX-RS endpoints, POJOs annotated with @Path
- .service
-
handles the registration transaction for new members
- .util
-
contains Resources.java which sets up an alias for @PersistenceContext to be injectable via @Inject
Now, let’s explore the resources in the project.
Under src you will find:
- main/resources/import.sql
-
contains insert statements that provides initial database data. This is particularly useful when hibernate.hbm2dll.auto=create-drop is set in persistence.xml. hibernate.hbm2dll.auto=create-drop causes the schema to be recreated each time the application is deployed.
- main/resources/META-INF/persistence.xml
-
establishes that this project contains JPA entities and it identifies the datasource, which is deployed alongside the project. It also includes the hibernate.hbm2dll.auto property set to create-drop by default.
- test/java/test
-
provides the .test package that contains MemberRegistrationTest.java, an Arquillian based test that runs both fomm within JBoss Developer Studio via Run As → JUnit Test and at the command line:
mvn test –Parq-jbossas-remote
- src/main/webapp
-
contains index.xhtml, the JSF-based user interface for the sample application. If you double-click on that file you will see Visual Page Editor allows you to visually navigate through the file and see the source simultaneously. Changes to the source are immediately reflected in the visual pane.
In src/main/webapp/WEB-INF, you will find three key files:
- beans.xml
-
is an empty file that indicates this is a CDI capable EE6 application
- faces-config.xml
-
is an empty file that indicates this is a JSF capable EE6 application
- ticket-monster-ds.xml
-
when deployed, creates a new datasource within the JBoss container
Adding a new entity using Forge
There are several ways to add a new JPA entity to your project:
- Starting from scratch
-
Right-click on the .model package and select New → Class. JPA entities are annotated POJOs so starting from a simple class is a common approach.
- Reverse Engineering
-
Right-click on the "model" package and select New → JPA Entities from Tables. For more information on this technique see this video
- Using Forge
-
to create a new entity for your project using a CLI (we will explore this in more detail below)
- Reverse Engineering with Forge
-
Forge has a Hibernate Tools plug-in that allows you to script the conversion of RDBMS schema into JPA entities. For more information on this technique see this video.
For the purposes of this tutorial, we will take advantage of Forge to add a new JPA entity. This requires the least keystrokes, and we do not yet have a RDBMS schema to reverse engineer. There is also an optional section for adding an entity using New → Class.
Right-click on the .model package in the Project Explorer and select Show In → Forge Console.
|
Alternative methods to activate Forge include:
Note: the Show In method will issue a "pick-up" command to switch you to the right location within your project. |
The first time you start Forge, you will be prompted with a Forge Not Running dialog, select Yes.
|
If you are not prompted you can always start Forge using the green arrow (or stop via the red square) in the Forge Console tab.
Figure 19. Show Forge Start/Stop
|
Forge is a command-oriented rapid application development tool that allows you to enter commands that generate classes and code. It will automatically update the IDE for you. A key feature is "content assist" or "tab completion", activated by pressing tab.
To generate an entity, use these commands:
entity --named Event --package org.jboss.jdf.example.ticketmonster.model field string --named name validation setup constraint NotNull --onProperty name constraint Size --onProperty name --min 5 --max 50 --message "Must be > 5 and < 50" field string --named description constraint Size --onProperty description --min 20 --max 1000 --message "Must be > 20 and < 1000" field boolean --named major field string --named picture
Let’s work through this, step by step.
At the [ticket-monster] model $ prompt, type en and hit the tab key on your keyboard. entity will fill in. Hit tab again and entity --named will appear. Type in Event and add a space — Forge can not anticipate the name of your new entity!
Hit tab again and select --package. Now, hit tab repeatedly to fill in org.jboss.jdf.example.ticketmonster. Since there are multiple entries underneath examples, Forge will display those options. Type in m and hit tab to select model.
Now hit the Enter/Return key to watch the command execute. The Event entity will be generated into the "model" package and open up inside of Eclipse.
|
@Entity public class is placed on the same line as ` import java.lang.Override` by Forge. Using the formatter your IDE provides on the entity will make this look more like you would expect! |
Forge has automatically changed the context of the CLI to Event.java, and typing ls will provide a listing of the fields and methods.
Now that the base Event entity has been created, let’s add the fields and their JSR 303 Bean Validation constraints.
This next step involves adding a name property for the Event entity so that an event could hold data like "Rock Concert".
Type fie and hit tab to fill in field, if you hit tab again, Forge will list out the possible field types. Type in s and hit tab, Forge will respond with string. Hit tab again to get --named and type in name. You should end up with the command field string --named name, to execute it, press enter. This will add a private String name; field, and the appropriate accessor and mutator (getter and setter) methods. You should also notice that the toString method is tweaked to include name as well.
From this point forward, we will assume you have the basics of using Forge’s interactive command line. The remaining commands to run are:
validation setup constraint NotNull --onProperty name constraint Size --onProperty name --min 5 --max 50 --message "Must be > 5 and < 50" field string --named description constraint Size --onProperty description --min 20 --max 1000 --message "Must be > 20 and < 1000" field boolean --named major field string --named picture
The easiest way to see the results of Forge operating on the Event.java JPA Entity is to use the Outline View of JBoss Developer Studio. It is normally on the right-side of the IDE when using the JBoss Perspective.
Reviewing persistence.xml & updating import.sql
By default, the entity classes generate the database schema, and is controlled by src/main/resources/persistence.xml.
The two key settings are the <jta-data-source> and the hibernate.hbm2ddl.auto property. The datasource maps to the datasource defined in src\main\webapp\ticket-monster–ds.xml.
The hibernate.hbm2ddl.auto=create-drop property indicates that all database tables will be dropped when an application is undeployed, or redeployed, and created when the application is deployed.
The import.sql file contains SQL statements that will inject sample data into your initial database structure. Add the following insert statements:
insert into Event (id, name, description, major, picture, version) values (1, 'Shane''s Sock Puppets', 'This critically acclaimed masterpiece...', true, 'http://dl.dropbox.com/u/65660684/640px-Carnival_Puppets.jpg', 1); insert into Event (id, name, description, major, picture, version) values (2, 'Rock concert of the decade', 'Get ready to rock...', true, 'http://dl.dropbox.com/u/65660684/640px-Weir%2C_Bob_(2007)_2.jpg', 1);
Adding a new entity using JBoss Developer Studio
Alternatively, we can add an entity with JBoss Developer Studio or JBoss Tools.
First, right-click on the .model package and select New → Class. Enter the class name as Venue - our concerts & shows happen at particular stadiums, concert halls and theaters.
First, add some private fields representing the entities properties, which translate to the columns in the database table.
package org.jboss.jdf.example.ticketmonster.model;
public class Venue {
private Long id;
private String name;
private String description;
private int capacity;
}Now, right-click on the editor itself, and from the pop-up, context menu select Source → Generate Getters and Setters.
This will create accessor and mutator methods for all your fields, making them accessible properties for the entity class.
Click Select All and then OK.
Now, right-click on the editor, from the pop-up context menu select Source → Generate Hibernate/JPA Annotations.
If you are prompted to save Venue.java, simply select OK.
The Hibernate: add JPA annotations wizard will start up. First, verify that Venue is the class you are working on.
Select Next.
The next step in the wizard will provide a sampling of the refactored sources – describing the basic changes that are being made to Venue.
Select Finish.
Now you may wish to add the Bean Validation constraint annotations, such as @NotNull to the fields.
Deployment
At this point, if you have not already deployed the application, right click on the project name in the Project Explorer and select Run As → Run on Server. If needed, this will startup the application server instance, compile & build the application and push the application into the JBOSS_HOME/standalone/deployments directory. This directory is scanned for new deployments, so simply placing your war in the directory will cause it to be deployed.
|
If you have been using another application server or web server such as Tomcat, shut it down now to avoid any port conflicts. |
Now, deploy the h2console webapp. You can read how to do this in the h2console quickstart.
The Run As → Run on Server option will also launch the internal Eclipse browser with the appropriate URL so that you can immediately begin interacting with the application.
Now, go to http://localhost:8080/h2console to start up the h2 console.
Use jdbc:h2:mem:ticket-monster as the JDBC URL (this is defined in src/main/webapp/WEB-INF/ticket-monster-ds.xml), sa as the username and sa as the password.
Click Connect
You will see both the EVENT table, the VENUE table and the MEMBER tables have been added to the H2 schema.
And if you enter the SQL statement: select * from event and select the Run (Ctrl-Enter) button, it will display the data you entered in the import.sql file in a previous step. With these relatively simple steps, you have verified that your new EE 6 JPA entities have been added to the system and deployed successfully, creating the supporting RDBMS schema as needed.
Adding a JAX-RS RESTful web service
The goal of this section of the tutorial is to walk you through the creation of a POJO with the JAX-RS annotations.
Right-click on the .rest package, select New → Class from the context menu, and enter EventService as the class name.
Select Finish.
Replace the contents of the class with this sample code:
package org.jboss.jdf.example.ticketmonster.rest;
@Path("/events")
@RequestScoped
public class EventService {
@Inject
private EntityManager em;
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Event> getAllEvents() {
final List<Event> results =
em.createQuery(
"select e from Event e order by e.name").getResultList();
return results;
}
}This class is a JAX-RS endpoint that returns all Events.
You’ll notice a lot of errors, relating to missing imports. The easiest way to solve this is to right-click inside the editor and select Source → Organize Imports from the context menu.
Some of the class names are not unique. Eclipse will prompt you with any decisions around what class is intended. Select the following:
-
javax.ws.rs.core.MediaType
-
org.jboss.tools.examples.Event
-
javax.ws.rs.Produces
-
java.util.List
-
java.inject.Inject
-
java.enterprise.context.RequestScoped
The following screenshots illustrate how you handle these decisions. The Figure description indicates the name of the class you should select.
You should end up with these imports:
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jboss.jdf.example.ticketmonster.model.Event;Once these import statements are in place you should have no more compilation errors. When you save EventService.java, you will see it listed in JAX-RS REST Web Services in the Project Explorer.
This feature of JBoss Developer Studio and JBoss Tools provides a nice visual indicator that you have successfully configured your JAX-RS endpoint.
You should now redeploy your project via Run As → Run on Server, or by right clicking on the project in the Servers tab and select Full Publish.
Using a browser, visit http://localhost:8080/ticket-monster/rest/events to see the results of the query, formatted as JSON (JavaScript Object Notation).
|
The rest prefix is setup in a file called JaxRsActivator.java which contains a small bit of code that sets up the application for JAX-RS endpoints. |
Adding a jQuery Mobile client application
Now, it is time to add a HTML5, jQuery based client application that is optimized for the mobile web experience.
There are numerous JavaScript libraries that help you optimize the end-user experience on a mobile web browser. We have found that jQuery Mobile is one of the easier ones to get started with but as your skills mature, you might investigate solutions like Sencha Touch, Zepto or Jo. This tutorial focuses on jQuery Mobile as the basis for creating the UI layer of the application.
The UI components interact with the JAX-RS RESTful services (e.g. EventService.java).
|
For more information on building HTML5 + REST applications with JBoss technologies, check out Aerogear. |
These next steps will guide you through the creation of a file called mobile.html that provides a mobile friendly version of the application, using jQuery Mobile.
First, using the Project Explorer, navigate to src/main/webapp, and right-click on webapp, and choose New HTML file.
|
The New HTML File Wizard starts off with your target location being m2e-wtp/web-resources, this is an incorrect location and it is a bug, JBIDE-11472. It is possible it may already be corrected by the time you read through this document. |
Change directory to ticket-monster/src/main/webapp and enter name the file mobile.html.
Select Next.
On the Select HTML Template page of the New HTML File wizard, select HTML5 jQuery Mobile Page. This template will get you off to a fast start using jQuery Mobile.
Select Finish.
The document must start with <!DOCTYPE html> as this identifies the page as HTML 5 based. For this particular phase of the tutorial, we are not introducing a bunch of HTML 5 specific concepts like the new form fields (type=email), websockets or the new CSS capabilities. For now, we simply wish to get our mobile application completed as soon as possible. The good news is that jQuery and jQuery Mobile make the consumption of a RESTful endpoint very simple.
You might notice that in the Visual Page Editor, the visual portion is not that attractive, this is because the majority of jQuery Mobile magic happens at runtime and our visual page editor simply displays the HTML without embellishment.
|
Note: Normally HTML files are deployed automatically, if you find it missing, just use Full Publish or Run As Run on Server as demonstrated in previous steps. |
As soon as the page loads, you will be prompted with an alert box with "Ready to Go". This alert box is generated from JavaScript that is associated with the pageinit event.
One side benefit of using a HTML5 + jQuery-based front-end to your application is that it allows for fast turnaround in development. Simply edit the HTML file, save the file and refresh your browser.
Now the secret sauce to connecting your front-end to your back-end is simply editing the pageinit JavaScript event and including an invocation of the previously created Events JAX-RS service.
Insert the following block of code directly below the alert()
$.getJSON("rest/events", function(events) {
// console.log("returned are " + events);
var listOfEvents = $("#listOfItems");
listOfEvents.empty();
$.each(events, function(index, event) {
// console.log(event.name);
listOfEvents.append("<li><a href='#'>" + event.name + "</a>");
});
listOfEvents.listview("refresh");
});
Note:
-
using $.getJSON("rest/events") to hit the EventService.java
-
a commented out // console.log, causes problems in IE
-
Getting a reference to listOfItems which is declared in the HTML using an id attribute
-
Calling .empty on that list - removing the exiting One, Two, Three items
-
For each event - based on what is returned in step 1
-
another commented out // console.log
-
append the found event to the UL in the HTML
-
refresh the listOfItems
|
You may find the .append("<li>...") syntax unattractive, embedding HTML inside of the JS .append method, this can be corrected using various JS templating techniques. |
The result is ready for the average mobile phone. Simply refresh your browser to see the results.
JBoss Developer Studio and JBoss Tools includes BrowerSim to help you better understand what your mobile application will look like. Look for a "phone" icon in the toolbar, visible in the JBoss Perspective.
|
The BrowserSim tool takes advantage of a locally installed Safari (Mac & Windows) on your workstation. It does not package a whole browser by itself. You will need to install Safari on Windows to leverage this feature – but that is more economical than having to purchase a MacBook to quickly look at your mobile-web focused application! |
The Mobile BrowserSim has a Devices menu, on Mac it is in the top menu bar and on Windows it is available via right-click as a pop-up menu. This menu allows you to change user-agent and dimensions of the browser, plus change the orientation of the device.
You can also add your own custom device/browser types.
Under the File menu, you will find a View Page Source option that will open up the mobile-version of the website’s source code inside of JBoss Developer Studio. This is a very useful feature for learning how other developers are creating their mobile web presence.
Conclusion
This concludes our introduction to building HTML5 Mobile Web applications using Java EE 6 with Forge and JBoss Developer Studio. At this point, you should feel confident enough to tackle any of the additional exercises to learn how the TicketMonster sample application is constructed.
Cleaning up the generated code
Before we proceed with the tutorial and implement TicketMonster, we need to clean up some of the archetype-generated code. The Member management code, while useful for ilustrating the general setup of a Java EE 6 web application, will not be part of TicketMonster, so we can safely remove some packages, classes, and resources:
-
All the Member-related persistence and business code:
-
src/main/java/org/jboss/jdf/example/ticketmonster/controller
-
src/main/java/org/jboss/jdf/example/ticketmonster/data
-
src/main/java/org/jboss/jdf/example/ticketmonster/model/Member.java
-
src/main/java/org/jboss/jdf/example/ticketmonster/rest/MemberResourceRESTService.java
-
src/main/java/org/jboss/jdf/example/ticketmonster/service/MemberRegistration.java
-
-
Generated web content
-
src/main/webapp/index.html
-
src/main/webapp/index.xhtml
-
src/main/webapp/WEB-INF/templates/default.xhtml
-
-
JSF configuration (we will re-add it via Forge)
-
src/main/webapp/WEB-INF/faces-config.xml
-
-
Prototype mobile application (we will generate a proper mobile interface)
-
src/main/webapp/mobile.html
-
Also, we will update the src/main/resources/import.sql file and remove the Member entity insertion:
insert into Member (id, name, email, phone_number) values (0, 'John Smith', 'john.smith@mailinator.com', '2125551212'
The data file should contain only the Event data import:
insert into Event (id, name, description, major, picture, version) values (1, 'Shane''s Sock Puppets', 'This critically acclaimed masterpiece...', true, 'http://dl.dropbox.com/u/65660684/640px-Carnival_Puppets.jpg', 1); insert into Event (id, name, description, major, picture, version) values (2, 'Rock concert of the decade', 'Get ready to rock...', true, 'http://dl.dropbox.com/u/65660684/640px-Weir%2C_Bob_(2007)_2.jpg', 1);
Share the Knowledge
Find this guide useful?
Feedback
Find a bug in the guide? Something missing? You can fix it by forking the repository, making the correction and sending a pull request. If you're just plain stuck, feel free to ask a question in the user discussion forum.
Recent Changelog
- Jan 24, 2013: Fix syntax errors that upset asciidoctor Dan Allen
- Dec 06, 2012: Corrections on intro, datapersistence and businesslogic Marius Bogoevici
- Dec 06, 2012: Transitions to other chapters Marius Bogoevici
- Dec 04, 2012: Make the introduction refer to ticketmonster Marius Bogoevici
- Dec 03, 2012: Fix obsolete urls in the ticketmonster tutorial Sande Gilda
- Jun 24, 2012: Fix error in javascript, thanks to juraci paixão kröhling Pete Muir
- Jun 07, 2012: Fix typo, thanks to robertral Pete Muir
- Jun 04, 2012: Fix odd asciidoc formatting Pete Muir
- Jun 04, 2012: Change poh5 -> html5 Pete Muir
- May 30, 2012: Rename files without ordering, finish off single book output Pete Muir
- May 29, 2012: Numbered files for proper ordering Marius Bogoevici
- May 28, 2012: Continue to update introduction Pete Muir
- May 28, 2012: Start to improve formatting of introduction Pete Muir
- May 28, 2012: Add author info Pete Muir
- May 24, 2012: Added author tags for the document Marius Bogoevici