16 min read

In this article by Grant Shipley author of Learning OpenShift we are going to learn how to use OpenShift in order to create and deploy Java-EE-based applications using the JBoss Enterprise Application Platform (EAP) application server. To illustrate and learn the concepts of Java EE, we are going to create an application that displays an interactive map that contains all of the major league baseball parks in the United States. We will start by covering some background information on the Java EE framework and then introduce each part of the sample application. The process for learning how to create the sample application, named mlbparks, will be started by creating the JBoss EAP container, then adding a database, creating the web services, and lastly, creating the responsive map UI.

(For more resources related to this topic, see here.)

Evolution of Java EE

I can’t think of a single programming language other than Java that has so many fans while at the same time has a large community of developers that profess their hatred towards it. The bad reputation that Java has can largely be attributed to early promises made by the community when the language was first released and then not being able to fulfill these promises. Developers were told that we would be able to write once and run anywhere, but we quickly found out that this meant that we could write once and then debug on every platform. Java was also perceived to consume more memory than required and was accused of being overly verbose by relying heavily on XML configuration files.

Another problem the language had was not being able to focus on and excel at one particular task. We used Java to create thick client applications, applets that could be downloaded via a web browser, embedded applications, web applications, and so on. Having Java available as a tool that completes most projects was a great thing, but the implementation for each project was often confusing. For example, let’s examine the history of the GUI development using the Java programming language. When the language was first introduced, it included an API called the Abstract Window Toolkit (AWT) that was essentially a Java wrapper around native UI components supplied by the operating system. When Java 1.2 was released, the AWT implementation was deprecated in the favor of the Swing API that contained GUI elements written in 100 percent Java. By this time, a lot of developers were quickly growing frustrated with the available APIs and a new toolkit called the Standard Widget Toolkit (SWT) was developed to create another UI toolkit for Java. SWT was developed at IBM and is the windowing toolkit in use by the Eclipse IDE and is considered by most to be the superior toolkit that can be used when creating applications. As you can see, rapid changes in the core functionality of the language coupled with the refusal of some vendors to ship the JRE as part of the operating system left a bad taste in most developers’ mouths.

Another reason why developers began switching from Java to more attractive programming languages was the implementation of Enterprise JavaBeans (EJB). The first Java EE release occurred in December, 1999, and the Java community is just now beginning to recover from the complexity introduced by the language in order to create applications. If you were able to escape creating applications using early EJBs, consider yourself one of the lucky ones, as many of your fellow developers were consumed by implementing large-scale systems using this new technology. It wasn’t fun; trust me. I was there and experienced it firsthand.

When developers began abandoning Java EE, they seemed to go in one of two directions. Developers who understood that the Java language itself was quite beautiful and useful adopted the Spring Framework methodology of having enterprise grade features while sticking with a Plain Old Java Object (POJO) implementation. Other developers were wooed away by languages that were considered more modern, such as Ruby and the popular Rails framework. While the rise in popularity of both Ruby and Spring was happening, the team behind Java EE continued to improve and innovate, which resulted in the creation of a new implementation that is both easy to use and develop with.

I am happy to report that if you haven’t taken a look at Java EE in the last few years, now is the time to do so. Working with the language after a long hiatus has been a rewarding and pleasurable experience.

Introducing the sample application

For the remainder of this article, we are going to develop an application called mlbparks that displays a map of the United States with a pin on the map representing the location of each major league baseball stadium. The requirements for the application are as follows:

  • A single map that a user can zoom in and out of
  • As the user moves the map around, the map must be updated with all baseball stadiums that are located in the shown area
  • The location of the stadiums must be searchable based on map coordinates that are passed to the REST-based API
  • The data should be transferred in the JSON format
  • The web application must be responsive so that it is displayed correctly regardless of the resolution of the browser
  • When a stadium is listed on the map, the user should be able to click on the stadium to view details about the associated team

The end state application will look like the following screenshot:

The user will also be able to zoom in on a specific location by double-clicking on the map or by clicking on the + zoom button in the top-left corner of the application. For example, if a user zooms the map in to the Phoenix, Arizona area of the United States, they will be able to see the information for the Arizona Diamondbacks stadium as shown in the following screenshot:

To view this sample application running live, open your browser and type http://mlbparks-packt.rhcloud.com.

Now that we have our requirements and know what the end result should look like, let’s start creating our application.

Creating a JBoss EAP application

For the sample application that we are going to develop as part of this article, we are going to take advantage of the JBoss EAP application server that is available on the OpenShift platform.

The JBoss EAP application server is a fully tested, stable, and supported platform for deploying mission-critical applications. Some developers prefer to use the open source community application server from JBoss called WildFly. Keep in mind when choosing WildFly over EAP that it only comes with community-based support and is a bleeding edge application server.

To get started with building the mlbparks application, the first thing we need to do is create a gear that contains the cartridge for our JBoss EAP runtime. For this, we are going to use the RHC tools. Open up your terminal application and enter in the following command:

$ rhc app create mlbparks jbosseap-6

Once the previous command is executed, you should see the following output:

Application Options
-------------------
Domain:     yourDomainName
Cartridges: jbosseap-6 (addtl. costs may apply)
Gear Size: default
Scaling:   no
Creating application 'mlbparks' ... done
Waiting for your DNS name to be available ... done
Cloning into 'mlbparks'...
Your application 'mlbparks' is now available.
URL:       http://mlbparks-yourDomainName.rhcloud.com/
SSH to:     [email protected]
Git remote: ssh://[email protected]/~/git/mlbparks.git/
Cloned to: /home/gshipley/code/mlbparks
 Run 'rhc show-app mlbparks' for more details about your app.

If you have a paid subscription to OpenShift Online, you might want to consider using a medium- or large-size gear to host your Java-EE-based applications. To create this application using a medium-size gear, use the following command:

$ rhc app create mlbparks jbosseap-6 -g medium

Adding database support to the application

Now that our application gear has been created, the next thing we want to do is embed a database cartridge that will hold the information about the baseball stadiums we want to track. Given that we are going to develop an application that doesn’t require referential integrity but provides a REST-based API that will return JSON, it makes sense to use MongoDB as our database.

MongoDB is arguably the most popular NoSQL database available today. The company behind the database, MongoDB, offers paid subscriptions and support plans for production deployments. For more information on this popular NoSQL database, visit www.mongodb.com.

Run the following command to embed a database into our existing mlbparks OpenShift gear:

$ rhc cartridge add mongodb-2.4 -a mlbparks

Once the preceding command is executed and the database has been added to your application, you will see the following information on the screen that contains the username and password for the database:

Adding mongodb-2.4 to application 'mlbparks' ... done
 mongodb-2.4 (MongoDB 2.4)
-------------------------
Gears:         Located with jbosseap-6
Connection URL: mongodb://$OPENSHIFT_MONGODB_DB_HOST:$OPENSHIFT_MONGODB_DB_PORT/
Database Name: mlbparks
Password:       q_6eZ22-fraN
Username:       admin
MongoDB 2.4 database added. Please make note of these credentials:
   Root User:     admin
   Root Password: yourPassword
   Database Name: mlbparks
Connection URL: mongodb://$OPENSHIFT_MONGODB_DB_HOST:$OPENSHIFT_MONGODB_DB_PORT/

Importing the MLB stadiums into the database

Now that we have our application gear created and our database added, we need to populate the database with the information about the stadiums that we are going to place on the map. The data is provided as a JSON document and contains the following information:

  • The name of the baseball team
  • The total payroll for the team
  • The location of the stadium represented with the longitude and latitude
  • The name of the stadium
  • The name of the city where the stadium is located
  • The league the baseball club belongs to (national or American)
  • The year the data is relevant for
  • All of the players on the roster including their position and salary

A sample for the Arizona Diamondbacks looks like the following line of code:

{   "name":"Diamondbacks",   "payroll":89000000,   "coordinates":[     -112.066662,     33.444799   ],
"ballpark":"Chase Field",   "city":"Phoenix",   "league":"National League",
"year":"2013",   "players":[     {       "name":"Miguel Montero", 
"position":"Catcher",       "salary":10000000     }, ………… ]}

In order to import the preceding data, we are going to use the SSH command. To get started with the import, SSH into your OpenShift gear for the mlbparks application by issuing the following command in your terminal prompt:

$ rhc app ssh mlbparks

Once we are connected to the remote gear, we need to download the JSON file and store it in the /tmp directory of our gear. To complete these steps, use the following commands on your remote gear:

$ cd /tmp
$ wget https://raw.github.com/gshipley/mlbparks/master/mlbparks.json

Wget is a software package that is available on most Linux-based operating systems in order to retrieve files using HTTP, HTTPS, or FTP.

Once the file has completed downloading, take a quick look at the contents using your favorite text editor in order to get familiar with the structure of the document. When you are comfortable with the data that we are going to import into the database, execute the following command on the remote gear to populate MongoDB with the JSON documents:

$ mongoimport --jsonArray -d $OPENSHIFT_APP_NAME -c teams --type
json --file /tmp/mlbparks.json -h $OPENSHIFT_MONGODB_DB_HOST --port $OPENSHIFT_MONGODB_DB_PORT
-u $OPENSHIFT_MONGODB_DB_USERNAME -p $OPENSHIFT_MONGODB_DB_PASSWORD

If the command was executed successfully, you should see the following output on the screen:

connected to: 127.7.150.130:27017
Fri Feb 28 20:57:24.125 check 9 30
Fri Feb 28 20:57:24.126 imported 30 objects

What just happened? To understand this, we need to break the command we issued into smaller chunks, as detailed in the following table:

Command/argument

Description

mongoimport This command is provided by MongoDB to allow users to import data into a database.
–jsonArray This specifies that we are going to import an array of JSON documents.
-d $OPENSHIFT_APP_NAME Specifies the database that we are going to import the data into the database. We are using a system environment variable to use the database that was created by default when we embedded the database cartridge in our application.
-c teams This defines the collection to which we want to import the data. If the collection does not exist, it will be created.
–type json This specifies the type of file we are going to import.
–file /tmp/mlbparks.json This specifies the full path and name of the file that we are going to import into the database.
-h $OPENSHIFT_MONGODB_DB_HOST This specifies the host of the MongoDB server.
–port $OPENSHIFT_MONGODB_DB_PORT This specifies the port of the MongoDB server.
-u $OPENSHIFT_MONGODB_DB_USERNAME This specifies the username to be used to be authenticated to the database.
-p $OPENSHIFT_MONGODB_DB_PASSWORD This specifies the password to be authenticated to the database.

To verify that data was loaded properly, you can use the following command that will print out the number of documents in the teams collections of the mlbparks database:

$ mongo -quiet $OPENSHIFT_MONGODB_DB_HOST:$OPENSHIFT_MONGODB_DB_PORT/$OPENSHIFT_APP_NAME
-u $OPENSHIFT_MONGODB_DB_USERNAME -p $OPENSHIFT_MONGODB_DB_PASSWORD --eval "db.teams.count()"

The result should be 30.

Lastly, we need to create a 2d index on the teams collection to ensure that we can perform spatial queries on the data.

Geospatial queries are what allow us to search for specific documents that fall within a given location as provided by the latitude and longitude parameters.

To add the 2d index to the teams collections, enter the following command on the remote gear:

$ mongo
$OPENSHIFT_MONGODB_DB_HOST:$OPENSHIFT_MONGODB_DB_PORT/$OPENSHIFT_APP_NAME
--eval 'db.teams.ensureIndex( { coordinates : "2d" } );'

Adding database support to our Java application

The next step in creating the mlbparks application is adding the MongoDB driver dependency to our application. OpenShift Online supports the popular Apache Maven build system as the default way of compiling the source code and resolving dependencies.

Maven was originally created to simplify the build process by allowing developers to specify specific JARs that their application depends on. This alleviates the bad practice of checking JAR files into the source code repository and allows a way to share JARs across several projects. This is accomplished via a pom.xml file that contains configuration items and dependency information for the project.

In order to add the dependency for the MongoDB client to our mlbparks applications, we need to modify the pom.xml file that is in the root directory of the Git repository. The Git repository was cloned to our local machine during the application’s creation step that we performed earlier in this article. Open up your favorite text editor and modify the pom.xml file to include the following lines of code in the <dependencies> block:

<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.9.1</version>
</dependency>

Once you have added the dependency, commit the changes to your local repository by using the following command:

$ git commit -am "added MongoDB dependency"

Finally, let’s push the change to our Java application to include the MongoDB database drivers using the git push command:

$ git push

The first time the Maven build system builds the application, it downloads all the dependencies for the application and then caches them. Because of this, the first build will always that a bit longer than any subsequent build.

Creating the database access class

At this point, we have our application created, the MongoDB database embedded, all the information for the baseball stadiums imported, and the dependency for our database driver added to our application. The next step is to do some actual coding by creating a Java class that will act as the interface for connecting to and communicating with the MongoDB database. Create a Java file named DBConnection.java in the mlbparks/src/main/java/org/openshift/mlbparks/mongo directory and add the following source code:

package org.openshift.mlbparks.mongo;
 import java.net.UnknownHostException;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import com.mongodb.DB;
import com.mongodb.Mongo;
 @Named
@ApplicationScoped
public class DBConnection {
private DB mongoDB;
public DBConnection() {
   super();
}
@PostConstruct
public void afterCreate() {
   String mongoHost = System.getenv("OPENSHIFT_MONGODB_DB_HOST");
   String mongoPort = System.getenv("OPENSHIFT_MONGODB_DB_PORT");
   String mongoUser = System.getenv("OPENSHIFT_MONGODB_DB_USERNAME");
   String mongoPassword = System.getenv("OPENSHIFT_MONGODB_DB_PASSWORD");
   String mongoDBName = System.getenv("OPENSHIFT_APP_NAME");
   int port = Integer.decode(mongoPort);
   Mongo mongo = null;
 try {
    mongo = new Mongo(mongoHost, port);
   } catch (UnknownHostException e) {
    System.out.println("Couldn't connect to MongoDB: " + e.getMessage() + " :: " + e.getClass());
   }
   mongoDB = mongo.getDB(mongoDBName);
   if (mongoDB.authenticate(mongoUser, mongoPassword.toCharArray()) == false) {
    System.out.println("Failed to authenticate DB ");
   }
}
public DB getDB() {
   return mongoDB;
}
}

The preceding source code as well as all source code for this article is available on GitHub at https://github.com/gshipley/mlbparks.

The preceding code snippet simply creates an application-scoped bean that is available until the application is shut down.

The @ApplicationScoped annotation is used when creating application-wide data or constants that should be available to all the users of the application. We chose this scope because we want to maintain a single connection class for the database that is shared among all requests.

The next bit of interesting code is the afterCreate method that gets authenticated on the database using the system environment variables.

Once you have created the DBConnection.java file and added the preceding source code, add the file to your local repository and commit the changes as follows:

$ git add .
$ git commit -am "Adding database connection class"

Creating the beans.xml file

The DBConnection class we just created makes use of Context Dependency Injection (CDI), which is part of the Java EE specification, for dependency injection.

According to the official specification for CDI, an application that uses CDI must have a file called beans.xml. The file must be present and located under the WEB-INF directory. Given this requirement, create a file named beans.xml under the mlbparks/src/main/webapp/WEB-INF directory and add the following lines of code:

<?xml version="1.0"?>
<beans  
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd"/>

After you have added the beans.xml file, add and commit it to your local Git repository:

$ git add .
$ git commit -am "Adding beans.xml for CDI"

Summary

In this article we learned about the evolution of Java EE, created a JBoss EAP application, and created the database access class.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here