Thursday Mar 04, 2010

A Simple UI for Exploring Java EE

Java EE 6 has greatly simplified life for the EE developer. New annotations like @Startup and packaging options such as EJBs inside a war file save time and brain cycles. However, this makes writing the web UI for an application all the more time-consuming by comparison. If you're like me, you may have found yourself creating some entities and a session bean or two for controlling them, and then you just want to test it all out. Maybe step through the code in a debugger. Here's what I've done over and over -- it's simple, but it's silly. Just create a servlet, inject my session bean, and do something when the page is loaded:

    @EJB
    private MyBean myBean;
   
    @Override
    protected void doGet(...) throws ... {
        myBean.someMethod();
    } 

Then it's a simple matter to load the page in a browser and kick off the cool EJB code that you want to try. To check what really happened in the database, I use another tool (e.g., the database explorer in NetBeans). Simple, yes, but almost useless. In this blog, I'll show you a UI for testing Java EE services that is simple to write and trivial to adapt to your own applications. Not only can it provide a slick front end for calling business methods, but also access the database directly to show you what happened after the transactions have committed. As a bonus, it will show you the stack trace when something doesn't go quite right.

Yes, there are a number of tools that provide simple drag-and-drop interfaces for creating things like JSF front ends, but my goal is to create a UI with useful features as easily as I've created the session beans and entities. If you've ever written a Swing application, this should look very familiar. And there are no cryptic deployment descriptors, configuration files, or html/jsp templates needed. The only non-Java file in the application is a simple persistence.xml file.

To give you an idea before diving in, here is a screencast of the application in action.


Part 1: The Application

All of the application code is included in this zip file. I've included a pom.xml file so you can build with maven 2 without any additional setup. If you'd like to compile the sources and create the war another way, you just need the Java EE APIs in your classpath along with Vaadin, which comes in a single jar file that you can download from here. Look for the "Just the jar-file, please" text if you only want the one resource.

The back end consists of two simple entities, a SimplePerson and SimplePet. They both have a name, age, and one-to-one reference to each other. There is a PersonService session bean that has some normal CRUD operations on the person (which are cascaded to the pet). This bean is injected into the web UI -- see below for more details. Finally, there is a singleton bean loaded on startup that simply makes sure there is a pet named "Fred" in the database: FredCreatorBean. All of the classes are fairly simple and include comments to guide the reader. The persistence.xml file is very simple and uses a JTA data source jdbc/EE6Vaadin -- instructions for creating the resource are in part 2 of this blog. If you use a different JNDI name when creating the JDBC resource, make sure you change the name here. Also, after deploying the first time, you may want to comment out this line to avoid some warnings upon subsequent deployments:

    <property name="eclipselink.ddl-generation" value="create-tables"/>

For the presentation layer, I'm using Vaadin, a Java framework for creating rich internet applications. Since it's all Java, you write code that looks like Swing -- there are objects for layouts, widgets, and event handlers. GWT is similar, but with Vaadin the code you write stays on the server rather than being compiled into JavaScript objects. This is why I can inject a session bean into the presentation code to call my business logic. (Vaadin uses GWT for rendering the client in a web browser.) I should note that I'm not a Vaadin expert, so there may be better ways to create the UI. The Vaadin site has a nice forum for discussions like that -- I'll add a link here if there is any related discussion there.

Vaadin applications are loaded by a servlet com.vaadin.terminal.gwt.server.ApplicationServlet that you can configure in your web.xml file. This servlet creates the application object your write, initializes it, and the web page is displayed. In this example, I have included my own subclass of the Vaadin servlet in order to inject the session bean, and then I pass this bean to a custom constructor of my application. This also allows me to avoid having any configuration files except for persistence.xml. Here is the code included at the end of the main application class VaadinEE6App:

    /\*
     \* This code is adapted from the Vaadin example here:
     \* http://vaadin.com/wiki/-/wiki/Main/Hello%20GlassFish%203
     \*/
    @WebServlet(urlPatterns = "/\*")
    public static class Servlet extends AbstractApplicationServlet {

        @EJB
        private PersonService service;

        @Override
        protected Class<? extends Application> getApplicationClass() {
            return VaadinEE6App.class;
        }

        @Override
        protected Application getNewApplication(HttpServletRequest request)
            throws ServletException {
            return new VaadinEE6App(service);
        }
    }

In the application constructor, I store the EJB and create a couple class-level fields such as some panels that handle display and creation of the person/pet POJOs. The init() method creates some simple layouts, adds the panels, buttons, text field, etc., and connects the buttons to some actions for calling the back end. See the (hopefully) well-commented VaadinEE6App.java file for all the details. Everything there should look more or less familiar to a Java developer who has seen any Swing code.


Part 2: Setup and deployment using GlassFish v3

I'm using GlassFish v3 for this example, along with the JavaDB database that is included. In production, we would create the DB tables with SQL, but for a simple demo the JPA provider will do this for us. We just need to create the database connection pool, create a JNDI resource for it, and then build and deploy the application.

If you haven't already, download and unzip GlassFish v3, which supports Java EE 6. The database and server can be started with:

    asadmin start-database
    asadmin start-domain

Then visit the administration console at http://localhost:4848 -- the default username is admin with no password if prompted. On the left side, open the Resources->JDBC node and click Connection Pools. Click the New button and enter the following information, then click Next:

Step 1 of creating JDBC connection pool

In step 2, scroll to the Additional Properties table at the bottom. Delete properties as needed and enter information as shown below. Then click Finish.

Step 2 of creating JDBC connection pool

In the table above, the "create=true" property tells JavaDB to create the database when it is needed. The database name, user name, and password can be set to whatever you'd like, but you'll need to remember to change this information in the com.sun.bobby.ee6vaadin.presentation.SQLPanel class, which access the database directly.

Before moving on, you can check to make sure the database connection is working by clicking your new EE6VaadinPool entry in the Connection Pools list and then click the Ping button.

The last setup step is simple: creating the JDBC resource that points to the connection pool you just created. In the administration console, open the Resources->JDBC node again and click JDBC Resources. Click the New button, enter the following info, and click OK. If you choose a different name here, it has to match the jta-data-source element in the persistence.xml file in the application. That's all there is for setting up the database and server.

Creating the JNDI resource

Now you can create and deploy the war file. If using maven, you can use a simple "mvn package" from the ee6vaadin directory to build the war file. One more time, I'd like to point out that we have EJBs running without an ejb-jar file or an application .ear file! Good stuff.

To deploy, you can use the admin console or the following from the command line. The "--force" option isn't necessary the first time, but it is used in subsequent deployments to overwrite the deployed application. After your first deployment, you may want to comment out the table-creation property in persistence.xml and rebuild. Here is the command, but feel free to use whatever context root you'd like:

    asadmin deploy --force --contextroot /ee6v target/ee6vaadin.war

Assuming deployment proceeds without an issue, you can access the web application at http://localhost:8080/ee6v/ and give it a spin. It's not meant to include every conceivable feature -- there are even a couple "homework" features left for the user. But I hope it's enough to show how easily a web UI can be constructed that a) avoids configuration files, expression languages, templates, etc.; and b) can take full advantage of the Java EE server and use EJBs directly.

Update: I noticed I left an entity manager call in the code that isn't necessary at all. The 'else' block in the only method of FredCreatorBean looks like this:

        } else {
            // doesn't matter which one for this demo
            SimplePet fred = (SimplePet) fredPets.get(0);
            fred.setAge((fred.getAge() % 10) + 1);
            em.merge(fred);
            System.out.println(String.format(
                "Wow, Fred is %s years old already!",
                fred.getAge()));
        }

The 'em.merge(fred);' statement isn't necessary since the entity is still being managed throughout the method.

About

Whatever part of GlassFish or the Java EE world that catches my attention. (Also, go Red Sox.)

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today