Thursday, October 18, 2012

Bookmarklet: Restarting Vaadin Applications

This is a quick one....

When working on a Vaadin application, there are several ways to update the app's class files while sessions are still active: deploy to a server that supports session preservation, make a change to a properties file on the running server, use JRebel to push incremental changes, etc. Because the state of the UI is stored in the user's session, the changes may not be visible unless a new session is started.

You could always clear out your cookies, restart your browser, etc., but Vaadin offers a simple way to re-initialize the application so that you see the changes right away. Adding "?restartApplication" to the URL in the browser performs this function. See Debugging Vaadin Applications for more information.

If you're like me (lazy), typing "?restartApplication" more than once means there's got to be a better way. The bookmarklet below will handle this for you. Just drag it to your bookmarks bar and click it to restart the app. It takes everything in your current URL up to a question mark and then appends the magic phrase.


Happy reloading!

Friday, June 8, 2012

Session Timeouts with Vaadin's Refresher Add-on

The Refresher add-on for Vaadin refreshes the UI without user input, allowing it to display information that has changed asynchronously on the server. It adds an invisible component to the client web page which polls the server for changes. A matching server-side handler is called when the server is polled.

Refresher is among the most popular Vaadin add-ons, but adding a poll (or push) mechanism  to a Java EE application can be dangerous in terms of user sessions. The servlet container doesn't distinguish automatic poll requests from any user-initiated request, so the session will never time out on its own.

This blog shows an example of manually tracking user requests in order to time out sessions properly. The application is contained in this one class (linked here for reference). You can get the whole application in this zip file that includes pom.xml for building and a session listener to see when sessions start and end.

Note the README file: you have to build with the -Pcompile-widgetset option the first time because we're using a Vaadin add-on. Thank you to this blog for showing me how to put the widget compilation into its own profile!

The code is heavily commented to explain how user activity is tracked, but here is a summary:

  1. Using the HttpServletRequestListener interface we can note when a request comes in and compare the time of the request to the time of the previous one. If it's been X minutes, end the session.
  2. But we don't want to note the time of every request. So in step 1 we note the current time, but save the previous one (like pushing the time onto a stack). If the Refresher.RefreshListener is called, we know this isn't user input, so we can discard the current request time and only consider the older one (popping the stack).
  3. At this point, we can now compare the current request time to the older one and make a decision about ending the session.
In the above scenario, you can see that the session-timeout decision is only ever made in the refresher listener. It can't be in the onRequestStart() method because we don't know what kind of request it is (unless you want to parse the request stream!). We also can't end the session in that method because it causes an error within Vaadin. You could make this decision in every listener in your application if you wanted to, but I think the refresher is fine. Since it runs every N seconds, at the most a session will be N seconds longer than normal.

This description of the application is also contained in the source code:

 Simple app with a label and start button. When a user first loads the
 page, there are no automatic refresher calls happening and the container
 will timeout the session normally.
 Clicking the button starts the refresher, mimicking a user logging into
 the 'real' application UI. Whenever the UI is refreshed, it updates
 the label with a new value. This represents the UI reading state from
 another resource such as a database, which is constantly updated by
 other threads. For our simple case, we just show how much time we
 have left before ending the session.

The application was deployed and tested on a GlassFish 3.1.2 server (the Java EE reference implementation), but it should work on any Servlet 3.X container.

While the application works as-is, there is another aspect to consider that I will (hopefully) cover later. Some components will reload their data when a page is refreshed, for instance a Table that only shows a subset of its rows. In this case, the refresh call will force tables to make subsequent calls back to the server, extending the session. I'll add tables and their request handling to this sample application in a separate blog.

Monday, April 23, 2012

Tour: PPCD Running on HP

The HP Compute Cloud will be starting its public beta soon, and the Postgres Plus Cloud Database will be there. You can see a tour now of the user console running on HP.

We're excited to start offering the cloud database on more and more service providers.

Sunday, April 1, 2012

Simplified Communication Between Applications

There exist several processes that can be used to communicate information between Java EE applications: JMS, database storage/retrieval, printing/OCR scanning, etc. (For a distributed version of the last one, see RFC 1149.)

But each of these requires the creation and management of resources, along with complicated APIs. Probably the best "hidden" feature of Java, beginning with JDK 1.4, is that there is already such a capability that can conduct complicated communications connecting Java EE applications: the Logger object.

Loggers can be given arbitrary names, and these logger objects are shared across the JVM. So if more than one application within an app server run the following:

    Logger logger = Logger.getLogger("logger0");

...both applications have a handle to the same object. We have the beginning of our inter-application communications framework so far. What makes this useful is that every Logger can contain a Level, and Levels hold a value that can be any integer. So we have, in essence, a map of strings to integers that can be accessed by any application within the server. The possibilities are wide open.

To test this, I have a simple web application that asks the user for 3 numbers and stores them in loggers like this (simplified slightly):


A separate web application, when reloaded, retrieves the values and displays them:


...where getLevelValue(Logger) simply returns logger.getLevel().intValue() or null if there is no level set. The entire source application is in this file, and the entire destination application is in this one. You can use this pom.xml [edit: fixed broken link] file to build either project -- just change 'artifactId' and 'finalName' to suit the circumstances.

Here is a screen shot of the 'source' application in exhilarating action:

...and the 'destination' application, before and after the data above was submitted:

Both of the applications were deployed to a GlassFish 3.1.2 server. Hopefully this blog sheds some light on a woefully underutilized feature of Java. This kind of communication between applications involves no setup before deployment, can be used with any number of applications, and doesn't directly couple applications to each other. It's left as an exercise to the reader to explore extending Level to include any arbitrary data, not just integers (though there are a lot of integers).

Also, happy April 1st everyone.

Thursday, February 23, 2012

Sample App Tour

In my last blog, I performed a very short DB migration from a local PostgreSQL installation to one running in the cloud. In this blog, I want to share the small "wine database" application that I used. All of the code is available in this zip file, including a pom.xml file for building through maven (if you want to build without maven, the only dependencies are the Java EE APIs and Vaadin -- see below). My target audience is developers who know how to set up JDBC connection pools and generate DB tables, but if there's interest I can follow up with a step-by-step guide to deploying this application.

Before getting into the application, here is the SQL used for creating the database tables and initial information (the file is also included in the zip above in the 'sql' directory). There are two simple tables, one for wines and one for wine classifications. The wine table holds a foreign key to entries in the classifications table.

The application is a small Java EE app using Vaadin for the web framework. Because the last post was more about the database than the application, it's not a full CRUD app: it's more CR-oriented in that you can save and view data only. Very little code is required to create this application: one POJO for each DB entity/table, a simple EJB service object between the UI and back end, three files for the whole UI, and a very short servlet class used to load the UI. Please see the source code for full comments, but here is the relevant part of the servlet class:
@WebServlet(urlPatterns = {"/app/*", "/VAADIN/*"})
public class UIServlet extends AbstractApplicationServlet {
    WineService service;
    protected Application getNewApplication(HttpServletRequest request)
        throws ServletException {
        return new MainUI(service);
    protected Class<? extends Application> getApplicationClass()
        throws ClassNotFoundException {
        return MainUI.class;

That's all that's needed to create the Vaadin application object and pass a reference to the EJB service to it. From there, the class creates a small user interface with a table and single button for adding more entries to the table. The button has a listener that pops up a child window containing the form for adding another entry:

To access the back-end data, I'm using two separate strategies. That may sound complicated, but it's actually due to laziness (a good trait in engineers when used properly!). The table is using Vaadin's SQL Container, which is very easy to set up. It connects to the database through SQL directly, and handles details like paging, optimistic locking, etc, automatically. The form that adds new wines is using JPA, which also means very little code to write since the EJB can persist an entity while handling transactions, locking, etc, with one line of code:

    public void store(Wine wine) {

The data source for the table, the SQLContainer, can use a database connection pool to perform its queries. This is as simple as using new J2EEConnectionPool("jdbc/WineDB") in the table class. Because this jndi name is used here and in persistence.xml, both database access methods use a single definition of the datasource, as shown here from the GlassFish administration console. Here is the resource definition:

...and here are the relevant details of the winedb-pool connection pool:

Thus, I can change the location of the database in only one place and the application will find it. I'm letting the database assign primary keys rather than letting JPA do it. Here is the SQL, for example, for creating the classification table and inserting some data:
create table classification (
  id               serial primary key,
  class_name       varchar(255) not null
insert into classification (class_name) values ('Cabernet');
insert into classification (class_name) values ('Merlot');

In my JPA entity, I use the following annotations to work with the primary key generation strategy:
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

This makes it easier to access the database through tools outside of the application itself, without worrying about details like a key generation table.

One last note about the application: every class in the app is serializable, which is required by Vaadin and which is a good idea in general for a web app (so the container can persist your session to some storage or to enable replication/failover). I didn't bother with generating serialVersionUIDs for the UI classes since they will only be serialized/deserialized by the container and not transferred around. I could have done the same with the entities, but for these I try to remember to generate the IDs just in case a future version of an application uses them as DTOs. In this case, it's just a matter of preference.

For a future blog, I hope to rewrite the app to run in Tomcat and deploy it to Amazon's Elastic Beanstalk using the JDBC URL property to connect it to the cloud database.

Monday, February 13, 2012

Migrating Your PostgreSQL Database to the Cloud

Now that EnterpriseDB has launched the Postgres Plus Cloud Database, it's easy to get a database running in the cloud. This blog covers the next step: migrating a PostgreSQL database that you already have running on traditional hardware to your new cloud database.

To provide a full example, this entry uses a simple web application written in Vaadin. I'm running it on a GlassFish 3.1.1 application server (supports Java EE 6), and the application talks to a PostgreSQL 9.1 database through a JDBC connection that's configured in the server. This means there's only one place I need to change my connection information once the data has been migrated.

The application itself is a very simple database for storing information about wine. I'll give a walkthrough of the application in a subsequent blog, followed by a version that runs on Tomcat that could be deployed to Amazon Elastic Beanstalk.

For better viewing, here is a direct link to the video embedded below.

After setting up the remote database in the cloud, the migration happens in three steps:
  1. Back up the existing database to a file.
  2. Restore the data into the new database.
  3. Point the application to the new database location (and restart if necessary).
For the screen cast, I'm using all command line tools. For more information on using the PostgreSQL tools from the command line, see this article from EnterpriseDB.

Note that the GlassFish administration can be performed from the command line as well. To see a list of the properties that are set, you can use the asadmin "get" command and grep for the information (if you don't already know the property names):

BobbyMac}> ./asadmin get "*" | grep wine | grep property

Similarly, you can use the asadmin "set" command to change these values. Then you can redeploy the application to pick up the new values.

Thursday, February 2, 2012

A Tour of the Cloud Database Console

This is a short screen cast giving a tour of the Postgres Plus Cloud Database console. From the console, you can easily create and manage database clusters through a web interface.

Here is a direct link to the video on YouTube.

For more information, please see the cloud database link above or the forum from EnterpriseDB.

Monday, January 30, 2012

Asadmin with Remote GlassFish

Now that I've been working more with Amazon EC2, I'm starting to appreciate how useful the GlassFish asadmin tool is with a remote system. Here are some steps to get GlassFish set up for secure, remote access. Note that I'm not covering any of the setup on the local machine besides unzipping the bundle -- there are other blogs and documentation out there about securing your installation at the OS level. The following applies to GlassFish 3.1.1:

Step 0: Setup

After starting up a remote machine, copy the GlassFish zip file there and unzip it. At this point, I only have the standard ssh and http ports open in my firewall ("security group" on Amazon EC2). If you start with port 4848 open, then someone could access the server through the admin console in a browser before you've had a chance to change the password or admin username.

Step 1: Secure admin

With GlassFish installed, start the server, then change the admin user's password and enable secure administration. Without secure administration on, remote systems cannot talk to the server at all. Here are the commands to run locally from your ssh session:
  • asadmin start-domain
  • asadmin change-admin-password
After changing the admin password, you may want to run asadmin login as well to avoid having to specify the password again and again. This will only affect local access to the server (e.g. your environment while ssh'ed into the remote machine). Next:
  • asadmin enable-secure-admin
  • asadmin restart-domain
For more information on secure admin, see Tim Quinn's blog on the subject.

Step 2: Enable access

You can now open port 4848 in the security group/firewall so that your local asadmin client can talk to the remote server. If you want to remove the 'admin' user and create an administrative user with a different name, you can now reach the admin console at port 4848 in a browser:
  1. Log in as 'admin' user.
  2. In the left-hand panel, open Configurations, server-config, Security, Realms, admin-realm.
  3. Click Manage Users on the right and create the new user in the asadmin group.
  4. Log out as 'admin' then log in as your new user to delete the 'admin' user.
If you change the admin user, use the new user name in place of 'admin' below.

Step 3: Set up local access

With secure administration turned on, you can now access the remote machine like this (note that the port argument is only needed if you have changed the admin port):

BobbyMac}> asadmin --host <hostname> --user admin --port 4848 --secure list-applications
Enter admin password for user "admin">
Nothing to list.
Command list-applications executed successfully.
Of course, you may not want to specify the command line options over and over and supply the password manually each time. You can specify these environment variables instead:

  • AS_ADMIN_SECURE (set to "true" without the quotes)
The last one should be set to the path of a file with these contents:
AS_ADMIN_PASSWORD=<your password>
Now you can access your remote server with simple asadmin commands with no other parameters:

BobbyMac}> asadmin list-applications
Nothing to list.

Command list-applications executed successfully.
Note: if you want to see all the parameters that are being used in the asadmin command, you can use the --echo option to have them printed:

BobbyMac}> asadmin --echo list-applications
asadmin --host <host> --port 4848 --user admin --passwordfile <path> --secure --interactive=true --echo=true --terse=false list-applications --long=false --terse=false --subcomponents=false --resources=falseNothing to list.Command list-applications executed successfully.
There are more options you can use with asadmin, but these are the basics to make remote administration easy. For all of the available options, run 'asadmin --help' on your local system. (If you're on a Mac, run 'asadmin --help | open -f" to bring up the help in a text editor for easy searching. See one of my earlier blogs for more information.)

Happy administering....

Tuesday, January 24, 2012

Hello World

Having left Oracle, my previous blog has reached its end. As far as I know it will still exist, and I still use my old GlassFish and Vaadin posts as references.

Looking forward, I'm now with EnterpriseDB and am working on a cloud database based on Postgres that ought to be live "real soon."