• Mar
    • 20
    • 2012

Search like you mean it

Posted by In Uncategorized

This entry is part 13 of 15 in the series Building JEE applications in JavaFX 2.0

In the last post we added database support to our First Contact application, taking advantage of both JPA and Spring Data. We cheated a little however; to keep things simple we limited our contact search query to just a single keyword. Thanks to the rise of Google Search, powerful keyword searching across multiple attributes is now the most familiar way for people to navigate their data these days. Our users are going to expect more than just a simple, single keyword search.

The SQL query for this however is a little tricky. Unlike a standard query, the number of predicates in the query depends on the number of keywords. For example, if we wanted to search our contacts by first name or last name, for the keywords ‘one’, ‘two’ and ‘three’ our SQL would look something like the following:

select * from contact
  where (firstName like '%one%' or lastName like '%one%')
    and (firstName like '%two%' or lastName like '%two%')
    and (firstName like '%three%' or lastName like '%three%')

We need to check that each keyword exists in at least one of the columns we are searching (i.e. first name and last name). The more keywords we have, the more ‘and’ clauses we need. Our simple naming convention for Spring Data isn’t going to cut it for this sort of thing, we need to dynamically build our query at runtime! Luckily JPA includes a way to build dynamic queries using the classes found in javax.persistence.criteria.

The recommended way to build dynamic query predicates using Spring Data is to create a ‘Specifications‘ class that has a static method to generate each of the Specifications (i.e. dynamic query providers) that we will use. In our case we can create a ContactSpecifications class and add a single searchContacts method to it.

ContactSpecifications.java

package com.zenjava.firstcontact.service.repository;

import com.zenjava.firstcontact.service.Contact;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.*;

public class ContactSpecifications
{
    public static Specification searchContacts(final String[] keywords)
    {
        return new Specification()
        {
            public Predicate toPredicate(Root contact, CriteriaQuery query, CriteriaBuilder builder)
            {
                Predicate predicate = builder.conjunction();

                if (keywords != null)
                {
                    for (String keyword : keywords)
                    {
                        if (keyword != null && keyword.length() > 0)
                        {
                            String matchTerm = "%" + keyword.toLowerCase() + "%";
                            predicate.getExpressions().add(builder.or(
                                    builder.like(builder.lower(contact.get("firstName")), matchTerm),
                                    builder.like(builder.lower(contact.get("lastName")), matchTerm)
                            ));
                        }
                    }
                }

                return predicate;
            }
        };
    }
}

As you can see, the Specification class provides a ‘toPredicate’ method that generates a dynamic predicate (i.e. query) for the Contact table. In our implementation of this we iterate through the keywords provided, adding restrictions to the predicate as needed. This is a relatively simple predicate, searching only one table but you can create pretty much any query, including table joins, using this predicate builder approach. See the Spring Data Specification documentation for more detail on this.

Next we need a way to execute this dynamic query. With Spring Data we simply make our Repository interface extend JpaSpecificationExecutor. This additional interface provides several methods, such as  ’findOne(Specification)’ and ’findAll(Specification)’, that take Specification objects and execute the resulting queries for us. Our updated ContactRepository class now looks like this (we can remove the old ‘findByFirstNameLikeOrLastNameLike’ method as we won’t be needing this now we can do proper keyword searching):

ContactRepository.java

public interface ContactRepository
        extends CrudRepository, JpaSpecificationExecutor
{
}

As well as providing a simple ‘findAll’ method, the JpaSpecificationExecutor also provides methods for retrieving paged data – i.e. retrieving results in batches (such as 25 at a time) and paging forward and backwards through those results. This is extremely useful when you have a large set of data that you can’t show all at once. We won’t use this here, but check out the PageRequest class for more details on how to use this.

Finally, we can now update our ContactServiceImpl to use the new ContactSpecification to perform a true keyword search. Our new searchContacts method looks like this:

public List searchContacts(String[] keywords)
{
    return contactRepository.findAll(ContactSpecifications.searchContacts(keywords));
}

That’s it! Give it a run and check it out. This same basic query can be easily extended to cover more complex scenarios, allowing your users to search across multiple tables and multiple fields via a simple text field search – this is guaranteed to make you popular at parties.

The full source code for this post can be found at: http://code.google.com/p/jfxee/source/browse/trunk/first-contact/first-contact-client-db-search/

Continue Reading→
    • Mar
    • 19
    • 2012

JavaFX and persistence: adding database support

Posted by In Uncategorized

This entry is part 12 of 15 in the series Building JEE applications in JavaFX 2.0

So far we’ve created a tidy little JavaFX contact management GUI; we’ve added some funky dependency injection via Spring; set up some handy maven-based build scripts; and even made our application work as a client-server based system over the internet. All very cool, but we’re missing one vital ingredient: persistence. We’re not yet saving our contact data, so every time we stop our server, all the information we’ve entered is lost.

In this post we’re going to add database storage to our First Contact system. we’ll make use of JPA and Hibernate, as these are the established players in this field. We’ll also make use of a few Spring tools to make things even easier, including Spring Transactions and the awe-inspiring Spring Data project. As usual, we’ll start with the code base from the previous blog post and step through each of the changes needed to get database integration included. You can access the final, complete code for this post at: http://code.google.com/p/jfxee/source/browse/trunk/first-contact/first-contact-client-db/

Step 1: Configure the JPA Persistence Unit

The Java Persistence API (JPA for short) is a standard API for using Object Relational Mapping (ORM) technologies – i.e. those that map Java Objects onto Relational Databases, where each SQL table maps to a Java Bean class. JPA is a fairly well established standard these days with lots of tooling support and good documentation out there on the web.

Since JPA is just an API, we need to choose an implementation to use with it (called a ‘provider’). I generally use Hibernate, a well established and powerful ORM. If you’re not familiar with any of this stuff you might want to take a quick look through some of the Hibernate and JPA articles out there on the web.

The first thing we need to do is configure our server application to use JPA and Hibernate, and setup our database connection. JPA requires us to define an XML configuration file called persistence.xml and include this in our META-INF directory. Since we’re using Maven, we simply include this file in the directory /src/main/resources/META-INF.

JPA/Hibernate can be configured to work with any JDBC compliant database, such as Oracle, PostgreSQL, MySQL, etc. To get us up and running quickly and easily, we’re going to use a light-weight Java database called HyperSQL (aka HSQLDB). This doesn’t require any installation (it runs within the JVM and saves its data to a local file), and is a very handy tool for demos, development environments, unit tests, and client-side storage. In a future post I’ll show you how to wire up a PostgreSQL database instead for some production grade database support, but HSQLDB will suit our purpose for now.

The persistence.xml file contains any number of ‘persistence units’, each of which defines a provider (such as hibernate) and the configuration properties for that provider (such as the URL, username and password to use when connecting to the database). Below is the persistence.xml we’ll use for our First Contact application:

/src/main/resources/META-INF/persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence

http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"

             version="1.0">

    <persistence-unit name="first-contact">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
            <property name="hibernate.connection.url" value="jdbc:hsqldb:file:~/first-contact-db/first-contact" />
            <property name="hibernate.connection.username" value="sa" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>

</persistence>

In the configuration above, we’ve told JPA to use Hibernate as the provider, and then we’ve told Hibernate to use HSQLDB as the database implementation. In the HSQLDB connection URL we’ve specified a local file to use (the file will be created in your ‘home’ directory). See the HSQLDB documentation for more information on URL settings.

We’ve also set Hibernate’s ‘auto ddl’ setting to ‘update’ – on startup Hibernate will automatically create our database schema for us (i.e. all the Tables and Columns to use) based on the Entity beans we specify (which we will do in the next step). This is incredibly handy for testing/development as we simply make changes to our Java beans and the database is updated automatically to match. This can be a little risky in a production environment however, and in a future post, I’ll show you some techniques I use for database schema management.

As well as the above configuration we have to setup our project to include the JPA and Hibernate libraries on the classpath. With Maven this can be done by simply adding the following dependencies to our server:

<!-- JPA -->
<dependency>
    <groupId>org.hibernate.java-persistence</groupId>
    <artifactId>jpa-api</artifactId>
    <version>2.0-cr-1</version>
</dependency>

<!-- Hibernate -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>3.6.8.Final</version>
</dependency>

<!-- HSQL DB -->
<dependency>
    <groupId>hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <version>1.8.0.10</version>
</dependency>

All of these dependencies are available via the Maven central repository, so just by adding these to the POM, Maven will automatically download the necessary JARs and add them to the classpath (IntelliJ will automatically trigger a download, or you can force a refresh by doing a Maven -> reimport, I assume Eclipse and Netbeans do something similar but if not, you can run mvn clean install from the command line to force a download).

Note: we only need to add these dependencies to the server module. The client module is completely decoupled from the database implementation and does not have any dependencies onto Hibernate or HSQLDB. This is one of the design goals of our three-tier architecture, the data layer does not expose it’s plumbing to the other layers.

Step 2: Define the Contact Entity

We have a database but no tables yet. In JPA, we define our tables via ‘Entity beans’. These are basically regular Java Beans with a few annotations that tell the JPA system how to map the bean back to a table. Each row in the table will map to one instance of the Java bean.

We’re storing basic contact information, so a single ‘contact’ entity will do, with just first name and last name properties. In fact we have a bean already that will do the job, Contact.java. This is the Java bean we’ve been using in our previous examples to pass data between the client and server. We just need to make a few minor tweaks to this class so that it will work as an Entity.

Side note: using your service layer beans (which are effectively Data Transfer Objects between the presentation-tier and business-tier) as your entity beans (i.e. the data-tier) is a design decision that needs to be carefully considered. I personally create separate entity and DTO classes – this gives a very clean separation between the tiers at the (high) cost of code duplication. This choice is something of a contentious debate with good arguments on both sides of the fence. In the interest of keeping things simple, I am using the DTOs as the Entity beans in this post. In a later post I will likely explore the alternatives and advantages and disadvantages of each. If you are interested however, you can check out this article for some more insight.   

Here’s the updated bean, I’ll talk through the changes below:

package com.zenjava.firstcontact.service;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;

@Entity
public class Contact implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String firstName;
    private String lastName;

    public Contact()
    {
    }

    public Contact(Long id, String firstName, String lastName)
    {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Long getId()
    {
        return id;
    }

    public String getFirstName()
    {
        return firstName;
    }

    public String getLastName()
    {
        return lastName;
    }
}

The changes are as follows:

  • Annotate the bean with @Entity. This just tells the JPA system that we want this Bean to be mapped to the database.
  • Annotate the ‘id’ property with @Id. In order to be managed by JPA, each bean needs a field defining the unique ID for it.
  • Annotate the ‘id’ property with @GeneratedValue(strategy = GenerationType.AUTO). This tells JPA that we want to automatically generate unique IDs for us using whatever strategy makes sense for the underlying database implementation. This is optional, but if we left it out we would have to manually generate unique IDs ourselves.
  • Make the ‘id’ property a ‘Long’ instead of a ‘long’. This allows it to be ‘null’, which is a little easier to work with in JPA. You can use a ‘long’ if you prefer, however you have to then use -1 to represent a ‘null’ ID. Using a ‘Long’ is just more natural.
  • Add an empty constructor. Hibernate uses reflection to create the class and set the fields with data loaded from the database. To do this it needs an empty constructor so it can create an instance of the class and work with it.

We haven’t added any setter methods for the properties as yet, but we could if we had a need for them (we don’t in our application as yet).

The annotations defined above are part of the JPA library. The Contact class lives in the common module (since it is shared between client and server) and so far we’ve only added our JPA dependencies to the server module. In order for our annotations to be available in the common module we need to add the following dependency to the common POM:

<dependency>
    <groupId>org.hibernate.java-persistence</groupId>
    <artifactId>jpa-api</artifactId>
    <version>2.0-cr-1</version>
</dependency>

Notice that we’re only adding the JPA API here, not the Hibernate provider or HSQLDB libraries. These are needed only by the server, the API is sufficient for the common module and is all the client will be exposed to.

Back in step 2, we used the ‘auto dll’ setting to tell Hibernate to automatically create our schema for us, but we now need to include the Contact class in the persistence.xml file in order for it to be included in the process:

...
    <persistence-unit name="first-contact">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>com.zenjava.firstcontact.service.Contact</class>
        <properties>
        ...

Now, when the system starts up, Hibernate will automatically create a database table for the Contact bean and include the firstName and lastName fields on it.

Note: defining the ‘class’ in the persistence.xml file only seems to be needed when your Entity beans are defined in a separate Maven module (in our case ‘common’). If the Entity is defined in the same maven module, Hibernate will automatically find it without having to manually specify it. I’m not sure why this is so – if anyone knows a way to avoid this please post a comment. 

This is a very simple, single-table database system we’ve setup here. Obviously Hibernate is capable of a whole lot more, including relationships via foreign keys. For more details on this however, check out the plethora of Hibernate tutorials on the web.

Step 3: Create a Spring Data Repository 

We have a database, now we need a way to get data in and out of it. In a traditional database system you would use SQL queries to do this, but with JPA we can use regular Java calls and these will be mapped to SQL for us automatically. As such, instead of writing a whole stack of SQL queries, we can just write a stack of compiler-friendly Java methods for the Entities we want to access.

A typical design strategy for this is to use Data Access Object (DAOs). With this pattern you bundle all the data access methods relating to a single Entity into a DAO, encapsulating all your queries within this class, making them easier to test and maintain. Typically these DAOs all end up looking very similar, with every DAO providing the same basic CRUD operations. Several ‘generic DAO’ patterns have emerged as a result, such as the one described here.

We can go one step further however and make use of the JPA support within the Spring Data project. This has a built in DAO-like architecture, which it then builds upon to provide automatic query generation, saving us huge amounts of boiler plate code to write. It’s a fairly new player to the scene (as far as I know) and hasn’t gained nearly as much attention as it should have – at least it seems to be largely unheard of down my end of the planet. As you’re about to see however, it’s pretty awesome.

To use Spring Data, first we add the following dependency to our server POM:

<!-- Spring data -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>1.0.2.RELEASE</version>
</dependency>

Now we create a Repository interface. This is the term Spring Data uses for DAOs, each Repository is basically just a DAO. We make our Repository extend Spring Data’s CrudRepository, telling it what Entity type it is a repository for, and what type of ID that entity has. Our ContactRepository looks like this:

package com.zenjava.firstcontact.service.repository;

import com.zenjava.firstcontact.service.Contact;
import org.springframework.data.repository.CrudRepository;

public interface ContactRepository extends CrudRepository<Contact, Long>
{
}

Just by extending CrudRepository, we already have all our basic CRUD support for the Contact entity. We can findOne by ID, findAll, save and delete our Contact entities. We don’t even have to provide an implementation for this interface – Spring Data will do this for us automatically at runtime!

Even better, if we want to do stuff beyond the basic CRUD functions we can do so very easily. If, for example, we want a query to find all Contacts by first name, we could just define a method like so:

public interface ContactRepository extends CrudRepository<Contact, Long>
{
    List<Contact> findByFirstName(String firstName);
}

By following this simple naming convention, Spring Data automatically generates a query for us that searches by first name! This is so ridiculously easy it almost feels like cheating. There’s loads more you can do with Spring Data (including defining your own custom queries for things that don’t fit the naming pattern using the @Query annotation). Check out the Spring Data documentation for more details.

There’s just one more step we need to do to make all of this work: we need to setup a JPA EntityManager, and enable Spring Data in our Spring config file and tell it where to find our Repository interfaces. This is a simple matter of adding the following to our spring configuration file first-contact-servlet.xml

First a ‘data’ namespace addition at the top of the file:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:data="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-2.5.xsd


http://www.springframework.org/schema/data/jpa


http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

Then the following  anywhere in the file:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="first-contact" />
</bean>

<data:repositories base-package="com.zenjava.firstcontact.service"/>

The above config defines a simple JPA based EntityManager that is hooked up to our ‘first-contact’ persistence unit that we defined in our persistence.xml. Then it enables Spring Data and tells it to scan the ‘service’ package and find all our Repository interfaces and automatically create implementations for them that we can use in our service beans.

Step 4: Create a Service implementation

Previously our service implementation was provided by the SimpleContactService class, which just kept a list of hard-coded contacts in memory. We can delete this simple class now and add a new one called ContactServiceImpl (the naming convention is up to you – if you end up having multiple service implementations a good name would be JpaContactService).

As with the SimpleContactService, our new ContactServiceImpl class will implement the ContactService interface. Instead of using an in-memory list however, our new service will use an injected instance of the ContactRepository to manage contacts.

@Service
public class ContactServiceImpl implements ContactService
{
    @Inject private ContactRepository contactRepository;

The getContact and updateContact methods can be implemented trivially by calling through to our repository like so:

public Contact getContact(Long contactId)
{
    return contactRepository.findOne(contactId);
}

public Contact updateContact(Contact updatedContact)
{
    return contactRepository.save(updatedContact);
}

Our ‘searchContact’ method is a little more tricky. We want to perform a detailed keyword search that requires each keyword to appear in either the first name or last name. There’s a way to do this but it requires some stuff we’ve not covered yet. So for now, to avoid getting bogged down and also to show you an example of Spring Data’s cool automatic query generation, we’re just going to do a simple query that picks the first keyword only.

For this to work we just add a new method to our ContactRepository like so:

public interface ContactRepository extends CrudRepository<Contact, Long>
{
    List<Contact> findByFirstNameLikeOrLastNameLike(String firstName, String lastName);
}

Based just on the name of the method, Spring Data will create a query that does a ‘like’ match on both first name and last name. We don’t have to write any implementation code or SQL for this, it just works!

Then we can use this in our ContactServiceImpl like so:

public List<Contact> searchContacts(String[] keywords)
{
    String searchTerm = keywords != null && keywords.length > 0 && keywords[0].trim().length() > 0
            ? "%" + keywords[0] + "%" : "%";
    return contactRepository.findByFirstNameLikeOrLastNameLike(searchTerm, searchTerm);
}

This is not quite the full multi-keyword search we wanted, but it’s still pretty good and it’s all been done with very little code. I’ll show you how to use Spring Data’s specifications to do the proper search in a future post, but for now let’s just stick to our simple query.

Our service is looking pretty good, we just now need to tell Spring to use this new implementation instead of our old SimpleContactService. This is done by editing the Spring config file, first-contact-servlet.xml, and changing the service export config to be the following:

<bean name="/contact.service" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
    <property name="service" ref="contactServiceImpl"/>
    <property name="serviceInterface" value="com.zenjava.firstcontact.service.ContactService"/>
</bean>

Step 5: Define the Transaction bounds

Something we’ve ignored up until now is transactions. Every database call has to be done within a transaction. By default each call to the database will be done with in its own local transaction, however it is much more efficient and cleaner to define your own transaction boundaries. That way you can perform several database calls in the one transaction, making your code run faster, as well as allowing you to rollback all the calls if you hit a failure half way through.

Traditionally transaction management was a messy area, but Spring comes to our rescue once again. Using Spring’s Transaction Management support we can easily enable transaction support by adding the following namespace to our Spring configuration file, first-contact-servlet.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:data="http://www.springframework.org/schema/data/jpa"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-2.5.xsd


http://www.springframework.org/schema/data/jpa


http://www.springframework.org/schema/data/jpa/spring-jpa.xsd


http://www.springframework.org/schema/tx


http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

And then adding the following configuration anywhere in the file:

<tx:annotation-driven/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

The ‘transactionManager’ bean declaration defines a standard JPA transaction manager and attaches this to our EntityFactory (which provides the connection to the database).

The ‘tx:annotation-driven’ element tells Spring that we want to use annotations on our classes to define our transaction bounds. I find this the easiest and cleanest way to do this, however you can use several powerful alternatives – check out the Spring docco for more info on this.

With transaction annotations enabled all we need to do is put the @Transactional annotation on the Spring controlled classes we want to use as transaction bounds. I use my service methods for this, so each call from the client to a service method is in its own transaction (calls between services on the server side will propagate their transactions).

In the case of our ContactServiceImpl we can just apply a global read-only transaction annotation to the whole class so that every method starts a new transaction. Our updateContact method however needs to do a write action, so we place a specific annotation on this method to allow this. The final ContactServiceImpl class looks like this:

import com.zenjava.firstcontact.service.repository.ContactRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Inject;
import java.util.List;

@Service
@Transactional(readOnly = true)
public class ContactServiceImpl implements ContactService
{
    @Inject private ContactRepository contactRepository;

    public List<Contact> searchContacts(String[] keywords)
    {
        String searchTerm = keywords != null && keywords.length > 0 && keywords[0].trim().length() > 0
                ? "%" + keywords[0] + "%" : "%";
        return contactRepository.findByFirstNameLikeOrLastNameLike(searchTerm, searchTerm);
    }

    public Contact getContact(Long contactId)
    {
        return contactRepository.findOne(contactId);
    }

    @Transactional(readOnly = false)
    public Contact updateContact(Contact updatedContact)
    {
        return contactRepository.save(updatedContact);
    }
}

When a service method is called a new transaction will be created, and in the case of non-read-only methods, when the method exits successfully the transaction will be committed. If the method fails with a runtime exception however, the transaction and all of the database changes made within that method, will be rolled back automatically as you would expect.

Transactions are a pretty fundamental database concept and Spring makes them almost too simple. It’s worth taking some time to read through the Spring documentation to really get a solid understanding of how they work and what you can do with them.

Step 6: Tweak the GUI to allow adding Contacts

Our system is now actually fully configured and you should be able to run both your server and client now without errors. Unfortunately our database is currently empty – in the SimpleContactService we hard-coded a bunch of contacts into it, but with our new database setup we want to add them in manually.

Unfortunately we’ve not yet provided a way to add a contact in our GUI yet so let’s quickly throw this in so we can get some data in there and see our database in action. Luckily, adding is very similar to editing (which we have implemented) so we can reuse this.

First include an add button in ContactSearch.fxml like so:

<HBox spacing="10">
    <children>
        <Label text="Search"/>
        <TextField fx:id="searchField" prefColumnCount="20" onAction="#search"/>
        <Button text="Search" onAction="#search"/>
        <Button text="Add" onAction="#addContact"/>
    </children>
</HBox>

Then add the handler method for this to ContactSearchPresenter, which just delegates onto to the MainPresenter:

public void addContact(ActionEvent event)
{
    mainPresenter.showAddContact();
}

The MainPresenter in turn just shows the ContactDetailPresenter passing in a ‘null’ contact ID to indicate that it is in create mode:

public void showAddContact()
{
    contactDetailPresenter.setContact(null);
    contentArea.setCenter(contactDetailPresenter.getView());
}

Our ContactDetailPresenter doesn’t need to do anything special except handle a null ID being passed in and then not try to load the contact details in this case:

    public void setContact(final Long contactId)
    {
        this.contactId = contactId;
        firstNameField.setText("");
        lastNameField.setText("");

        // only load details if contactId is not null
        if (contactId != null)
        {
            final Task<Contact> loadTask = new Task<Contact>()
            {
                protected Contact call() throws Exception
                {
                    return contactService.getContact(contactId);
                }
            };

            loadTask.stateProperty().addListener(new ChangeListener<Worker.State>()
            {
                public void changed(ObservableValue<? extends Worker.State> source, Worker.State oldState, Worker.State newState)
                {
                    if (newState.equals(Worker.State.SUCCEEDED))
                    {
                        Contact contact = loadTask.getValue();
                        firstNameField.setText(contact.getFirstName());
                        lastNameField.setText(contact.getLastName());
                    }
                }
            });

            new Thread(loadTask).start();
        }
    }

Step 7: Make contact

We now have a fully functional client-server, three-tier system with a persistent database backend. If you run your server and client now you should be able to add new contacts, search for them, and then edit them. When you shut down your server and restart it, all the data you entered should be still available the next time you search. You can even run multiple clients from multiple machines and share your contact information across the network.

You may have noticed that although this is a JavaFX system, we actually did no changes to the client when adding our database. In fact we didn’t touch the ‘client’ module at all. This is very much a design goal of any three tier architecture – the presentation layer should be completely decoupled from the implementation details of the data layer. Mission accomplished on that front!

We’ve finally achieved a truly functional JEE system, covering the core fundamentals of a JEE system. This is still a pretty bare bones application however and there’s a lot more that can be added. In the next few posts we’re going to look at improving that keyword search; hooking our system up to a ‘real’ traditional database instead of our file-based HSQLDB one; and if I can find the time we’ll also add some security, include some validation support, examine the benefits of DTOs, and possibly fix up our client application to better handle threading and errors communicating with the server. If you have any specific topics you’d like to see covered, feel free to post in the comments below.

The full source code for this post can be found at:  http://code.google.com/p/jfxee/source/browse/trunk/first-contact/first-contact-client-db/

Continue Reading→
    • Feb
    • 25
    • 2012

Going Remote – JavaFX and Spring Remoting

Posted by In Uncategorized

This entry is part 11 of 15 in the series Building JEE applications in JavaFX 2.0

Because JavaFX is so new to the scene, most of the focus of my previous blogs has been on getting our JavaFX client working cleanly. That’s only a very small part of the JEE puzzle however, and in this post we’re going to start expanding our horizons. We’re going to turn our little FirstContact application into a client-server one, using HTTP as the communication channel.

This post is probably going to be a little more complex than some of my last ones (unless you are already pretty familiar with web services development with Spring and Maven). I’m going to just push through it so as not to get bogged down in the detail. If you get lost on the way, feel free to ask questions via comments.

The full source code for this post can be found here.

Part 1: Split the project into a multi-module Maven project

Where before we had one single desktop application, now we’re going to have two: a client and a server. We also have a bit of code that is shared between these two (i.e. the service interface and data transfer objects sent between client and server), which we need to bundle into both the client and the server.

In Maven this means we need three ‘projects’, one for the client, one for the server and one for the common module shared between them. We could create these three separate projects as stand-alone instances, but it would be nice if we could bundle them all together into one so we can build them as one entity and work with them as one project in our IDE.

Maven’s answer to this is the ‘multi-module project’. If you’re not familiar with these, have a quick google on them. In fact this article here quite nicely explains what we’re about to do to our code so I’ll leave the explanation up to that and just get stuck into it.

First we need to restructure all our old single module code into the following directory structure:

c:\dev\first-contact-client-server

- pom.xml

+ first-contact-client
  - pom.xml
  + src
    + main
      + java
        + com
          + zenjava
            + firstcontact
              + gui
                + detail
                  - ContactDetailPresenter.java
                + main
                  - MainPresenter.java
                + search
                  - ContactSearchPresenter.java
                - FirstContactApp.java
                - FirstContactAppFactory.java
      + resources
        + fxml
          - ContactDetail.fxml
          - ContactSearch.fxml
          - Main.fxml
        - styles.css

+ first-contact-common
  - pom.xml
  + src
    + main
      + java
        + com
          + zenjava
            + firstcontact
              + service
                - Contact.java
                - ContactService.java

+ first-contact-server
  - pom.xml
  + src
    + main
      + java
        + com
          + zenjava
            + firstcontact
              + service
                - SimpleContactService.java

You can see our three modules are nicely contained within a single parent module called first-contact-client-server (you can use whatever name you like for). Additionally we’ve split the code and resources into the appropriate modules, so all the GUI code and FXML files are in the ‘client’ module, whereas the service interface and Contact bean (which are effectively the API onto our server implementation) are in the ‘common’ module, and our simple service implementation is in the ‘server’ module (for now we’re going to keep this simple, but in future posts we’ll look at making this use a database).

All the code and FXML is, at this stage, just a direct copy from our project in the last post, the only change is that we now have four pom.xml files instead of the single file we had before. There’s one pom.xml file for each of the three modules and a parent pom.xml to bundle it all together. Since each of these modules is doing something different, the POMs need to reflect this, so we need to modify each slightly.

First our parent POM. In this we need to let Maven know that we’re using a multi-module project and what modules are contained within. The below will do this (note the use of pom as the packaging type).

c:\dev\first-contact-client-server\pom.xml


<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zenjava</groupId>
    <artifactId>first-contact-client-server</artifactId>
    <name>JFX Contact Management System</name>

    <packaging>pom</packaging>
    <version>1.0</version>

    <modules>
        <module>first-contact-common</module>
        <module>first-contact-client</module>
        <module>first-contact-server</module>
    </modules>

</project>

Next our client POM. This is very similar to our original POM as we are using all the same client side features. The only two significant changes are firstly the reference back to the parent POM (which we just created above), and secondly a dependency onto the first-contact-common module (which we’ll create below) so that our client can use the shared code from there.

c:\dev\first-contact-client-server\first-contact-client\pom.xml

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.zenjava</groupId>
        <artifactId>first-contact-client-server</artifactId>
        <version>1.0</version>
    </parent>

    <groupId>com.zenjava</groupId>
    <artifactId>first-contact-client</artifactId>
    <name>JFX Contact Client</name>

    <packaging>jar</packaging>
    <version>1.0</version>

    <dependencies>

        <!-- First Contact Common -->

        <dependency>
            <groupId>com.zenjava</groupId>
            <artifactId>first-contact-common</artifactId>
            <version>1.0</version>
        </dependency>

        <!-- JavaFX -->

        <dependency>
            <groupId>com.sun.javafx</groupId>
            <artifactId>javafx</artifactId>
            <version>2.0.beta</version>
            <scope>system</scope>
            <systemPath>C:/apps/javafx/javafx-2.0.2_32bit/rt/lib/jfxrt.jar</systemPath>
        </dependency>

        <!-- Spring and supporting toolkits -->

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2</version>
        </dependency>

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>

    </dependencies>

</project>

Our common POM is similar to our client one, however since this contains only basic code with an interface and a data transfer object, we have no need for all the dependencies onto JavaFX, Spring, etc. In fact we don’t want these dependencies because this code will be shared with the server, so there should be no reference to JavaFX or client side libraries in it.

c:\dev\first-contact-client-server\first-contact-common\pom.xml

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.zenjava</groupId>
        <artifactId>first-contact-client-server</artifactId>
        <version>1.0</version>
    </parent>

    <groupId>com.zenjava</groupId>
    <artifactId>first-contact-common</artifactId>
    <name>JFX Contact Common</name>

    <packaging>jar</packaging>
    <version>1.0</version>

</project>

Finally, our server POM. At this stage we’ve just got our very simple service implementation in this project so there’s no need for a lot of dependencies. We just need one reference back to our common module so our server can make use of the classes defined in there.

c:\dev\first-contact-client-server\first-contact-server\pom.xml

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.zenjava</groupId>
        <artifactId>first-contact-client-server</artifactId>
        <version>1.0</version>
    </parent>

    <groupId>com.zenjava</groupId>
    <artifactId>first-contact-server</artifactId>
    <name>JFX Contact Server</name>

    <packaging>jar</packaging>
    <version>1.0</version>

    <dependencies>

        <!-- First Contact Common -->

        <dependency>
            <groupId>com.zenjava</groupId>
            <artifactId>first-contact-common</artifactId>
            <version>1.0</version>
        </dependency>

    </dependencies>

</project>

That’s it, you should be able to open this project in your favourite IDE. In IntelliJ you simply choose File -> Open Project and then select the top-level pom.xml file. IntelliJ is smart enough to handle the multi-module setup and will create a corresponding multi-module IntelliJ project with all our sub-modules configured as you would expect.

Eclipse can definitely also handle this structure although I believe you have to use one of the plugins (m2Eclipse from memory) rather than the default project file generation. NetBeans also looks to have multi-module support (according to this document anyway), but I’ve not used it so can’t comment.

Alternatively you can use the command line to build your project via Maven. If you open a Command Prompt and change directory to where the top-level pom.xml file lives (so in my case that’s c:\dev\first-contact-client-server) then type the following command:

mvn clean install

This will attempt to build all three of our modules and package them into JAR files, one after the other. If the build is successful, the resulting JAR files will be found in the ‘target’ directories under each module (e.g. the client JAR will be at c:\dev\first-contact-client-server/first-contact-client/target/first-contact-client-1.0.jar).

If you run this build right now however, with our project in its current state, you will get a compile error! Our client is still trying to ‘new’ an instance of our SimpleContactService, which now lives on the server so the client doesn’t have access to it (since there is no dependency from the client POM to the server POM). We’re going to sort this all out in the next few steps.

Part 2: Create a web app for the server

Currently our modules are all setup to produce JAR files when built. For the client and common modules this works fine, but our server module is going to be deployed to a web server (i.e. Tomcat) so it needs to be bundled into a WAR file instead.

With Maven this is incredibly easy, all we do is change the ‘packaging’ type in our server POM from ‘jar’ to ‘war’:

<packaging>war</packaging>

Since this is a web application, we also need to supply a web.xml file to be included in the WAR file. We do this simply by adding one to the directory maven expects it to be, which is first-contact-server/src/main/webapp/WEB-INF.

For now we can just use an empty web.xml file, but we’ll add to this shortly:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

</web-app>

Job done! Next time you run a build (such as mvn clean install from the command line) Maven will assemble a WAR file for us into the ‘target’ directory of the server module, which can be deployed on any servlet engine (such as Tomcat). Of course our webapp doesn’t actually do anything yet, but we’ll sort that out next.

Part 3: Expose our services using Spring’s HTTP Invoker

We have a server, but it’s not really serving anything up yet. We need to expose some ‘web services’ that our client can access and make use of. There are a number of flavours of web services we can choose between here: SOAP is the old timer, a big, heavy, verbose XML-based solution; RESTful is a lighter XML-style approach, whereas Hessian and Spring’s HTTPInvoker are binary based solutions. There’s a whole stack of other options out there too.

The choice of web service toolkit is largely down to your specific project requirements. Each of the frameworks has it’s advantages and disadvantages. The binary protocols, for example, typically have less overhead and can be more performant, whereas the XML-based ones allow for human readability. Some toolkits will work only with Java clients (such as Spring’s HTTPInvoker), some work better for limited-memory mobile devices (such as Hessian or RESTful) and others have additional features (and overheads) for solving complex business-to-business scenarios (such as SOAP).

In our application we have a JavaFX client and a Java server so for my money our best choice is Spring’s HTTPInvoker. It is incredibly simple to setup and use and since it uses Java Object serialization (i.e. our Java beans are just serialized across the HTTP connection) it is very fast and handles all our data types naturally. If we were also looking at supporting non-Java clients (such as an iPhone app) then I’d probably tend towards Hessian.

Luckily there is a toolkit out there that helps us wire in our choice of web service technology and allow us to easily change our mind later: Spring Remoting. This is another optional Spring toolkit, separate to the HTTPInvoker (i.e. you can use one without the other) which allows us to magically switch between many of the popular remoting toolkits just through some configuration changes. This gives us the flexibility to start developing using one toolkit (such as Spring’s HTTPInvoker) and if we find the need, easily switch to another (such as Hessian). The official Spring documentation on this is very good and well worth a read.

Enough pre-amble, let’s get to it. First thing we need to do is get the Spring Remoting jars into our server project. Maven makes this easy once again, we just add the following dependency into our server POM:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>3.0.6.RELEASE</version>
</dependency>

Now we need to expose a Servlet that can handle incoming requests and route them to our service implementation. Spring provides the DispatcherServlet for exactly this purpose, so we can add this to our web.xml file like so:

<servlet>
    <servlet-name>first-contact</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>first-contact</servlet-name>
    <url-pattern>*.service</url-pattern>
</servlet-mapping>

I’ve mapped the above Servlet so that any incoming request ending in .service will be passed on to the DispatcherServlet. You can use any URL pattern you like (such as *.htm or *.do).

Next we need to tell Spring which services to expose. Up until now we’ve managed to get away with using Spring’s @Configuration annotation to avoid writing Spring XML files. This is web-land however, and web-land seems to love XML, so unfortunately we have to slot in at least a little XML to get things happening.

By default Spring will look for an XML file with the same name as the <servlet-name> in our web.xml and with “-servlet.xml” appended to it. So for our above web.xml in order to configure our first-contact servlet, we need to create a file called first-contact-servlet.xml and put this in our WEB-INF directory.

In this XML file we need to tell Spring to instantiate our SimpleContactController class and expose it at a certain endpoint (i.e. web URL). Since we’ve decided to use Spring’s HTTPInvoker, it’s a very simple case of including a HttpInvokerServiceExporter reference in our XML file. Our config looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="simpleContactService" class="com.zenjava.firstcontact.service.SimpleContactService"/>

    <bean name="/contact.service" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="simpleContactService"/>
        <property name="serviceInterface" value="com.zenjava.firstcontact.service.ContactService"/>
    </bean>

</beans>

The first <bean> declaration just adds our SimpleContactService to the application context with the name ‘simpleContactService’ so it can be referenced elsewhere in the file. On it’s own, this does nothing as far as our web service is concerned. The bean is loaded into memory, but it’s not accessible on the web yet.

It’s the second <bean> declaration where the magic happens. Here we define a HttpInvokerServiceExporter to expose our service over the web. Spring knows to use the ‘name’ attribute as the end point, so in this case, our service will be accessible via the URL http://your-domain.com/contact.service. If you want to change the end point, all you do is change the name in this config file (just make sure the URL mapping in your web.xml matches the pattern you use).

When the server is running you can actually hit this URL with a standard web browser to call the service – of course it will throw an error because the browser doesn’t know how to handle Java serialized objects but it’s still a useful little test to see if things are wired up correctly.

As well as the ‘name’, we also give the Exporter a reference to the ‘simpleContactService’ that we defined in the first <bean>. This tells Spring to use the simpleContactService to provide all the implementation of the service calls. The HttpInvoker will do all the socket handling and serializing and deserializing for us, and then just delegate the calls onto our nice, Java implementation. Like magic!

There’s one more thing we have to tell the exporter. We have to explicitly specify that we want this service to be accessible via the ContactService interface. This might seem a bit redundant but it’s actually a pretty important security decision. If Spring just exposed every method on the SimpleContactService implementation bean we might accidentally allow web access to private methods that should only be used on the server side. Using a single interface allows us to tightly control what we expose to the big, scary world that is the world wide web, where hackers lurk waiting to take down our every server.

We’re done. Well almost. Because we’re using Spring’s HTTPInvoker, and it uses Java serialization to serialize our data between client and server, we need to make sure our beans are actually serializable. This is a simple case of making our Contact bean implement the standard java Serializable interface like so:


import java.io.Serializable;

public class Contact implements Serializable
{

Exposing our ContactService as a web service was that easy! All you need to do now is either run your web application in your IDE, or use ‘mvn clean install’ from the command line to generate a WAR file that you can then take and deploy to any servlet-based web server. I use Tomcat religiously because it simple and reliable, but there are literally dozens to choose from.

Part 4: Add a little magic

In our previous step, we had to manually declare our SimpleContactService bean in the XML file. In a large project there could be large numbers of these service beans (as well as dozens of supporting beans such as DAOs, etc). Declaring each one by hand can get a bit annoying.

There’s a little bit of Spring magic, called component scanning, that can save us some work in this area. Basically we can set some properties in our Spring XML file to tell Spring to scan our project’s classpath and find any class annotated with @Service (or a few alternatives that we won’t worry about yet) and Spring will then just magically add those to the application context.

Unfortunately there’s no way (that I’m aware of) to avoid defining the HttpInvokerServiceExporter in our XML file so we still have to do this step by hand. I don’t know whether this is a deliberate decision by the Spring guys for security reasons (i.e. they don’t want people accidentally exposing service beans when they didn’t mean to) or whether it was just not thought of. Either way, we’re left with the job of exposing these one-by-one in XML config.

Here’s the Spring config for using component scanning for our beans:

first-contact-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <context:annotation-config/>

    <context:component-scan base-package="com.zenjava.firstcontact.service"/>

    <bean name="/contact.service" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="simpleContactService"/>
        <property name="serviceInterface" value="com.zenjava.firstcontact.service.ContactService"/>
    </bean>

</beans>

Then all we have to do is annotate out SimpleContactService class like so:

import org.springframework.stereotype.Service;

@Service
public class SimpleContactService implements ContactService
{

For just our single bean the above component scanning is definitely overkill but as our application grows with more features and more services, this component scanning approach will save us a little bit of XML configuration file mucking around. We’ll see this pay off soon, I promise.

Part 5: Access our services from our client

Our server’s now sitting there eager to accept requests and serve up data, but our client is not talking to it yet. If you look at our old FirstContact code, you’ll remember that the SimpleContactService was created in our FirstContactAppFactory class and then injected into our various Presenters. The Presenters only ever made reference to the ContactService interface and never had any dependency on the underlying implementation being used. This was a deliberate tactic which is about to pay dividends.

Instead of creating a new instance of the SimpleContactService in our client, we can now use Spring Remoting to get a reference to the remote SimpleContactService that’s running on our server. Spring will give us a ‘stub’ implementation of our ContactService interface that uses HTTPInvoker to communicate back to the server, but from our perspective this is virtually invisible – everything is coded to use the ContactService interface so it doesn’t matter whether we’re accessing the local SimpleContactService or using a stub, the rest of our code won’t change at all!

First things first: we have to get the Spring Remoting library into our client module. Additionally we also need the HttpClient library from Apache commons. Spring’s HttpInvoker uses this under the covers to make the connection to the server. Here’s the dependencies to add to our client module’s POM:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>3.0.6.RELEASE</version>
</dependency>

<dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.1</version>
</dependency>

Next we replace the factory method in FirstContactAppFactory (which currently creates our new SimpleContactFactory), to instead create a ‘stub’ onto our server. The code for this is a tad messy because it has been written more for XML-based configuration than Java based config, meaning we have to manually do some factory stuff that XML Spring normally hides. Still it is only a few lines of extra code and it is all nicely hidden away inside our AppFactory doing no harm to anyone.

Our new factory method looks like this:

@Bean
public ContactService contactService()
{
    String serverUrl = "http://localhost:8080/contact.service";

    HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean();
    factory.setServiceUrl(serverUrl);
    factory.setServiceInterface(ContactService.class);
    factory.setHttpInvokerRequestExecutor(new CommonsHttpInvokerRequestExecutor());
    factory.afterPropertiesSet();
    return (ContactService) factory.getObject();
}

Note that I’ve just hard coded the server URL into this class and I’m using localhost on port 8080. This is the default when you are running a local tomcat instance but obviously in a proper distribution you would need to provide a proper URL (e.g. http://yourdomain.com/yourapp/contact.service). It would be trivial to load the URL from a properties file, or there are a number of other techniques that could be used. For now I’ll leave that as something for you to play with.

Part 6: Marvel at our success

We’re done! We’ve just written a working distributed JavaFX application with a web based back-end. You can either run the server inside your IDE (check your IDE’s help for details on how to do this, or post questions below) or you can use mvn clean install to build a WAR file that you can then copy into a Tomcat webapps directory. Your client at this stage is best run through your IDE by launching the FirstContactApp class (down the road we’ll have a look at different ways to build a deployable client bundle).

Since this is a distributed application you can actually run as many instances of the client as you want and they will all talk to the same server instance. You can even run the client from different machines but in this case you will need to change the server URL in the FirstContactAppFactory class to point to the IP address or domain name of the computer running the server.

We’ve made a pretty big step with this work towards a proper JEE application, but you’ll notice that when we start and stop the server, all our data is reset because it is only stored in memory on the server. In the next post we’ll have a look at using a database to store changes long term as you’d expect from a proper JEE system.

The full source code for this post can be found here.

Continue Reading→
    • Feb
    • 20
    • 2012

Porting “First Contact” to Spring

Posted by In Uncategorized

This entry is part 10 of 15 in the series Building JEE applications in JavaFX 2.0

In an earlier post we looked at different design patterns for building First Contact, our simple JavaFX-based contact management system. To keep things simple I deliberately avoided using Spring (or Guice) for the dependency injection and instead manually injected all the dependencies. This is great for educational purposes but really we’re doing things the hard way – Spring provides all sorts of magical things for making this easier, so let’s take advantage of them.

We looked at five different design pattern options for implementing First Contact, but moving forward let’s just pick one and work with that. I’m going to go with “Option 4: FXML and the MVP compromise” as it lets us use FXML for the presentation layer, which I think is a big win. Option 5 also uses FXML, but it is based on my third-party framework, JFX Flow and although I’m confident that JFX Flow is a nice little framework to use, I want it to leave it out of the equation at this stage so you can get a good, clean understanding of how everything is working. The pattern used in option 4 is very similar to what Flow expects, so switching between the two should be relatively trivial (and I’ll most likely do a port of our final First Contact app to JFX Flow when we get it all working).

So to give us a base to work off, we’ll make a copy of the source code from option 4, and then we’ll modify this to use Spring for dependency injection. The final source code for this blog can be found at: http://code.google.com/p/jfxee/source/browse/trunk/first-contact/first-contact-spring/.

Step 1: Add Spring dependencies

The first thing we need to do is get hold of the Spring JARs and get them on our classpath. Since we’re using Maven (check out my previous post on using Maven if you haven’t done so already) all we need to do is add the dependencies for the relevant Spring libraries to our pom.xml. Spring is made up of a whole suite of modules that we could use, but our requirements at this stage are quite simple. We just need Spring’s basic ‘context’ module for dependency injection. Since we’re using Spring’s annotation-based configuration (because I hate writing XML if I can avoid it), we’ll also need both the CGLIB module and the standard javax.inject library, which the annotation stuff in Spring makes use of.

We can update our pom.xml to look like this:

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zenjava</groupId>
    <artifactId>first-contact-spring</artifactId>
    <name>JFX Contact Management System</name>

    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <!-- JavaFX -->

        <dependency>
            <groupId>com.sun.javafx</groupId>
            <artifactId>javafx</artifactId>
            <version>2.0.beta</version>
            <scope>system</scope>
            <systemPath>C:/apps/javafx/javafx-2.0.2_32bit/rt/lib/jfxrt.jar</systemPath>
        </dependency>

        <!-- Spring and supporting toolkits -->

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.0.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2</version>
        </dependency>

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>

    </dependencies>

</project>

We’re reaping the rewards of using Maven here – just by adding those few dependencies to the pom.xml, Maven will automatically download the necessary JARs and put them on our application classpath. How easy is that!

Step 2: Simplify the First Contact Application Factory

Without Spring, we had to hand roll our own application factory. If you’ve forgotten what this looked liked, take a moment to look through our old FistContactAppFactory class. In this class we manually created all our beans, kept references to them, and then used setter methods to wire up everything (i.e. give each object access to the other beans it needed). The general pattern was something a little like this:

public class FirstContactApplicationFactory
{
    private SomeObject someObject;

    public SomeObject getSomeObject()
    {
        if (this.someObject == null)
        {
            this.someObject = new SomeObject();
            this.someObject.setSomeOtherObject1(getSomeOtherObject1());
            this.someObject.setSomeOtherObject2(getSomeOtherObject2());
        }
        return this.someObject;
    }

    ...
}

And we repeat this over and over again for each object we want to use. Lot’s of boring, copy-paste code.

With Spring we can get rid of most of this boiler plate code. First we annotate our FirstContactAppFactory class with the @Configuration annotation. This is just a marker, that lets Spring know this class is an application factory capable of providing beans for dependency injection.

Once we’ve done that we can then annotate each of the factory methods with Spring’s @Bean annotation. By doing this, we tell Spring that the resulting object is a bean that can be injected into other classes. We also tell Spring that we want the result of the method to be a singleton (this is the default for all beans in Spring, though you can change it if you want): Spring will then make sure the bean is only created once and the result will be cached and reused for every subsequent method call.

With Spring now doing our singleton caching we can get rid of the manual caching we were doing. Our new pattern looks a little like the following:

@Configuration
public class FirstContactApplicationFactory
{
    @Bean
    public SomeObject getSomeObject()
    {
        SomeObject someObject = new SomeObject();
        someObject.setSomeOtherObject1(getSomeOtherObject1());
        someObject.setSomeOtherObject2(getSomeOtherObject2());
        return someObject;
    }

    ...
}

This has saved us a fair bit of work already, but we can go one step further. Those calls to the setter methods are actually dependency injection, which is what Spring does for us so we can drop those as well (we need to also add some annotations on our Beans for this to work – see the next step). Our new pattern is now as simple as this:

@Configuration
public class FirstContactApplicationFactory
{
    @Bean
    public SomeObject getSomeObject()
    {
        return new SomeObject();
    }

    ...
}

Pretty simple! Below is the source code for the updated FirstContactAppFatcory. All it really does is create all our presenters and return them (using the FXML loader rather than creating a ‘new’ instance, but the pattern is the same). I’ve also dropped the ‘get’ from the method names, this is just a convention thing – Spring tends to leave these off for factory methods (since they are not strictly getters anymore), but you can name the methods whatever you want.

@Configuration
public class FirstContactAppFactory
{
    @Bean
    public MainPresenter mainPresenter()
    {
        return loadPresenter("/fxml/Main.fxml");
    }

    @Bean
    public ContactSearchPresenter contactSearchPresenter()
    {
        return loadPresenter("/fxml/ContactSearch.fxml");
    }

    @Bean
    public ContactDetailPresenter contactDetailPresenter()
    {
        return loadPresenter("/fxml/ContactDetail.fxml");
    }

    @Bean
    public ContactService contactService()
    {
        return new SimpleContactService();
    }

    private <T> T loadPresenter(String fxmlFile)
    {
        try
        {
            FXMLLoader loader = new FXMLLoader();
            loader.load(getClass().getResourceAsStream(fxmlFile));
            return (T) loader.getController();
        }
        catch (IOException e)
        {
            throw new RuntimeException(String.format("Unable to load FXML file '%s'", fxmlFile), e);
        }
    }
}

There’s a whole lot more that Spring can do for us – we are definitely only using the most basic of its features at this stage. For now though, that’s all we need and as you can see it’s made our code significantly simpler and easier to maintain.

Step 3: Inject dependencies using annotations

In the previous step we took away all those explicit setter calls in our factory methods (i.e. the manual dependency injection calls). We need to annotate our beans as well so that Spring knows to inject these classes for us now. For each of our beans, where we were previously calling a set method, we need to annotate the corresponding property instead. In fact, we can get rid of the setter altogether (if you want to leave it in, you can, but I tend to get rid of them) as Spring can access our annotated properties, even if they are private member variables with no getters or setters.

So something like this:

public class MyPresenter
{
    private String myProperty;

    public void setMyProperty(String myProperty)
    {
        this.myProperty = myProperty;
    }

    ...
}

Becomes as simple as this:

public class MyPresenter
{
    @Inject private String myProperty;

    ...
}

Again we’re just removing some of the minor annoying boiler plate code and telling Spring we want it to take care of the dependency injection for us. For some before and after examples, check out the following changes:

Note for long-time Spring users: the @Inject annotation is just the newer standards-based version of @Autowired. They are more or less interchangeable, however using the standards one allows us to change frameworks (e.g. move to Guice) with minimal fuss.

Step 4: Change how the factory is loaded at startup

Our factory and our beans are now all dressed up for the Spring dance, but we’ve still got to kick off the music. In our previous FirstContactApp we were manually instantiating a new instance of our FirstContactAppFactory and then accessing the main presenter by calling getter methods. This isn’t going to give Spring a chance to get in there and do all that magic autowiring stuff for us, so we need to change this slightly.

As you’d expect, the code for this is pretty simple. All we need to do is  use Spring’s AnnotationConfigApplicationContext and let it instantiate our Factory for us so we can then use Spring’s standard bean lookup mechanism to get our fully wired-up beans:

public void start(Stage stage) throws Exception
{
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(FirstContactAppFactory.class);
    MainPresenter mainPresenter = context.getBean(MainPresenter.class);
    mainPresenter.showSearchContacts();
    Scene scene = new Scene(mainPresenter.getView(), 800, 600);
    scene.getStylesheets().add("styles.css");
    stage.setScene(scene);
    stage.setTitle("First Contact - JavaFX Contact Management");
    stage.show();
}

Wrapping it up

That’s all the changes we need to make. If you run your updated FirstContactApp main method, you should see exactly the same GUI as from our previous post. We’ve not changed any of the functionality, just simplified the plumbing and removed a lot of redundant code.

Using Spring to this level has already helped us somewhat but we’ve barely scratched the surface. The main reason I wanted to port this application across is that in my next post I’m going to look at hooking this all up to a database using JPA. Spring is really going to start to pay off in this environment, and after that, when we add Transactions, Remoting and possibly even a dash of Security, we’ll be really making the most of Spring’s power.

Continue Reading→
    • Feb
    • 17
    • 2012

JavaFX and Maven

Posted by In Uncategorized

This entry is part 9 of 15 in the series Building JEE applications in JavaFX 2.0

For JEE application development, Maven is, in my opinion, a requirement. Sure you can use Ant, and that will give you more ‘control’ over you build, but you’ll be spending a fair chunk of time managing your build scripts – time that you could spend actually building your application. The two big reasons you want to use Maven for your JEE build are:

  1. Dependency management: Maven provides a free, web-hosted central repository which contains just about every major distributable toolkit out there. When you use Maven, you simply specify the toolkits you want to use and the version numbers, and Maven will automatically download the jars you need and setup your classpath.
     
  2. Minimal configuration build: Maven uses “convention over configuration”, which means if you follow its directory structure and naming conventions, you can avoid writing massive amounts of XML config. When assembling WAR or EAR files, which have some funny rules regarding WEB-INF directories and the like, Maven just makes all of this simple.

I’m not going to waste time selling you further on this (a quick web search will find you hundreds of articles comparing Maven to other build tools). What we’ll do here now is step through how to create a Maven project for running JavaFX applications. In this post, I’m only going to get us to the stage where we can run a simple, pure-client JFX app in out IDE, but we’ll grow on this later to build multi-module projects with client and server components, and include ways to build JNLP deployment bundles for web deployment.

Step 1: Download and install Maven

You can get the latest version from here: http://maven.apache.org/download.html. It’s just a zip file and doesn’t need any special ‘installing’. I usually just grab the latest ‘Binary Zip’ and extract it locally. I tend to put all my applications (like Tomcat, Maven, Java, etc) under c:\apps (on windows) as this makes it real easy to type on the command line if I ever need to.So for me, I unzip Maven to in c:\apps\maven\maven-3.0.1 but you can do whatever you like.

Once you have unzipped it, the only thing needed to install it is to add a system variable called ‘M2_HOME‘ that points to the directory you just unzipped to, and then update the PATH variable to include ‘%M2_HOME%\bin’. If you run into any trouble with this, check out this very detailed installation guide:http://www.sonatype.com/books/mvnref-book/reference/installation.html

Step 2: Create an empty project folder

Most IDE’s will generate you a skeleton Maven project these days, and Maven itself has the concept of project templates (called ‘archetypes’) that you can use to quickly generate a ready-to-use project structure but we’ll give these a miss in this round so you can see just how little magic is actually needed.

We need to create a new directory to house our project, Maven doesn’t care where we put this directory.  I tend to use c:\dev for all my projects (again because it is easy from the command line), so if we’re creating a project called ‘MyJfxProject’, I would put it in a folder called c:\dev\myjfxproject.

Step 3: Create an initial POM file

The heart of every Maven project is the POM (or Project Object Model). This is just an XML file called  ’pom.xml‘ that lives in the base directory of your project. It tells Maven what features you want to use in your build (e.g. are you building a JAR or a WAR). Unlike an Ant build script however, this file is generally pretty light however, there’s a lot Maven can work out just from your project structure.

At a minimum we need to tell Maven three pieces of information: our group ID, which is typically your domain name (so I use ‘com.zenjava’), our artifact ID, which is just the name of our project (so in this case we’ll use ‘myjfxproject’) and the version, usually it’s good to start with version 1.0. You can also do some cool stuff with snapshot versions, but we won’t get sidetracked with them right now. Here’s how our initial pom.xmlshould look:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zenjava</groupId>
    <artifactId>myjfxproject</artifactId>
    <version>1.0</version>

</project>

Step 4: Create our source file structure

Maven requires us to follow its convention for structuring our project. It doesn’t matter where our project base folder is, but within this base folder we need to use the Maven hierarchy. There is a lot to this, but we just need a place to store our Java files at the moment, Maven requires us to put these in the directory src/main/java. Any Java files in that directory will be automatically compiled and included in our resulting build.

You can (and should) use sub-directories to get packages like normal. In my case I use the base package com.zenjava, but you should use a domain that suits you (your registered web domain is best, but if you don’t have one, just make up something sensible – not using a package structure is bad form).

We will also want some non-Java resources (such as properties files, images, CSS style sheets and FXML files) included in our project. Maven requires us to put these in the directory src/main/resources. Any files in these directories will be automatically included in our final JAR. You can use whatever directory structure you want within the resources directory, I typically create a directory for each resource type. So our initial directory structure should look something a little like the following.

c:\dev\myjfxproject

- pom.xml
+ src
  + main
    + java
      + com
        + zenjava
          + myjfxproject
            - MyJfxProjectApp.java
    + resources
      + fxml
        -  (FXML files)
      + images
        -  (image files files)
      + styles
        -  (CSS files)

Step 5: Add JavaFX as a dependency 

In the introduction of this blog, I made the bold claim that the Maven repository “contains just about every major distributable toolkit out there”. There’s one notable exception to this however: unfortunately and frustratingly, JavaFX is not in there!

There’s a couple of reasons for this. Firstly, there’s a licencing issue. Somewhat disappointingly Oracle has used a licence that allows us to redistribute JavaFX but only if as part of a bigger application. You can’t just redistribute the JAR on it’s own. Putting the JFX JAR in any public Maven repository would blatantly violate this licence. Oracle’s not likely to change this unfortunately, but once JavaFX is fully open sourced into the OpenJDK project (sometime this year, I believe) we should be able to get around this.

The second reason is a technical one. JavaFX uses a number of native files (e.g. DLLs on windows) and Maven does not handle native files overly well. Native files need to be added to the java system path, whereas Maven’s whole dependency management is focused around the more common java classpath. Other libraries that use native files have found ways around this (such as the JOGL toolkit), but to support this the actual libraries themselves have to load their native files in a certain way, which the JavaFX guys are not doing (and as yet, are not intending to do). JavaFX requires its native files to be in a relative subdirectory (namely rt/bin), and Maven just doesn’t support this.

So this seems like a bit of a show stopper: if we can’t add JavaFX as a Maven dependency we can’t use JavaFX in Maven. Fortunately there are a couple of hack options we can use to cludge around this problem. None of the options are perfect and they all sacrifice some of the niceness that we expect when using Maven, but the cludges are just good enough to get us through and still take advantage of the other great features that Maven offers.

The easiest option, and my recommended approach, for getting a JavaFX dependency into Maven is to use the ‘system‘ scope. If you’re a regular Maven user, you may not even be aware this exists (I wasn’t) as it is very rarely used. This special scope allows you to specify a system path, which can reference the JAR file on your local system, rather than downloading it from the central repository. Maven no longer provides version management and automatic updates for us, but our native issue is resolved because we can reference the jar in its default installation location, which has the natives files relative to it.

To do this you first download and install the JavaFX SDK as per normal. Then you just add a dependency like the following to your POM (change the system path to point to your JFX installation directory):

<dependencies>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>javafx</artifactId>
        <version>2.0</version>
        <scope>system</scope>
        <systemPath>C:/apps/jfx2.0/rt/lib/jfxrt.jar</systemPath>
    </dependency>
</dependencies>

The groupId, artifactId and version are actually arbitrary in this case (you can put whatever you like in there). Normally Maven would use these to find the JAR in the central repository but because we’re specifying the JAR with the ‘systemPath’, Maven will ignore these other values.

Several alternate options exist for getting Maven and JavaFX to play nicely together but the above is the simplest and easiest. Probably the most powerful alternative is to use a “pre-loader” that extracts the native files from a JAR file installed into Maven when your application runs (the JFXtras project has code in it to assist with this). If you’re not wanting to take advantage of the JFX/JNLP deployment tools (more on this in future posts) then this can be a good option for bundling JFX in your final JAR. There’s a fair bit of work involved in assembling and maintaining the native JAR bundles however, so I personally tend not to use this approach.

It’s my hope that through a few of us working with the JFX team on this Maven issue that we’ll end up with a much cleaner solution for this in the future. There’s not a great deal of Maven experience in the JFX team however so it is slow going, and the future plans to co-bundle JFX with the JDK are also an influencing factor in this discussion. If JFX ends up in the JDK then version management and distribution will be intimately linked between these two taking Maven out of the game altogether (adding a whole new bucket of versioning and deployment complexities). There’s work to be done here still.

Step 6: Open your project in your favourite IDE 

We now have a fully operational JavaFX project and we can open this in our IDE. I use IntelliJ, which has fantastic, built-inn support for Maven. I simply go to File -> Open Project and then select the pom.xml file for my project. The result is a ready to run project with the classpath all set to include my source code, resources and third party libraries (in this case we’ve only added JavaFX but you can add as many dependencies as you like). I can also edit my POM file whenever I like (to add dependencies for example) and IntelliJ will automatically download the corresponding JAR files and update the classpath instantly.

I know that Eclipse also has strong support for Maven, as I have often worked with developers using Eclipse while I was using IntelliJ on the same project (which is another advantage of using Maven). I’m not totally up on the steps to getting this working but you should be able to find more info here: http://www.eclipse.org/m2e/

Additionally NetBeans also has support for Maven. Again I am not sure of the exact details, but this wiki seems to provide the right sort of information: http://wiki.netbeans.org/MavenBestPractices

If anyone has experience in using Maven with either Eclipse or NetBeans (or any other IDE out there), please post additional information in the comments below.

Step 7: Build your JAR file

With just this simple POM setup, we can now quickly and easily build the JAR file for our application. You can usually do this via your IDE, but using the command line is just as effective. On windows open a Command Prompt (Start -> Run -> cmd), then change directory into your project home directory (e.g. cd  c:\dev\myjfxproject) and type the following command:


mvn clean package

You will see a whole lot of log that should finish with “BUILD SUCCESS”. Assuming you get to this point, then the jar file containing all of your application code and resources can be found in the newly created ‘target’ directory. You can take this jar and use it as normal.

Beyond the basics

Building a single JAR file is pretty cool, but generally we will want to build a ready to run deployable application. We can use Maven to do all sorts of wonderful things, including building web deployable JNLP based deployment bundles and applets, as well as executable jars containing third party dependencies. Not to mention generating JavaDoc, automatically running unit tests, creating full project documentation and much, much more.

This does get quite a bit more complex however, and this blog post is already too long, so I will leave these more advanced topics to later. We’ll weave some deployment options into our future posts, especially when we look at building WAR files for our JEE-based server.

If you’re desperate for more info on a more complete JNLP-based deployment build process and you’re feeling comfortable with Maven then you can find some workable options buried in this forum discussion. As always, feel free to post further questions in the comment section below, or post on the JFX forum if you have more general questions.

Continue Reading→
    • Dec
    • 11
    • 2011

JavaFX and MVP – a smörgåsbord of design patterns

Posted by In Uncategorized

This entry is part 8 of 15 in the series Building JEE applications in JavaFX 2.0

Things are getting pretty exciting in the land of JavaFX. The platform seems to be gaining traction and we’re starting to see a real community build up around the forums and the open source channels. As a result we’re also seeing more developers moving beyond the ‘hello world’, and ‘colourful circles’ stage and setting their sights on real application development. With that comes a need for design patterns and best practices and these are currently lacking, or at least lacking in documentation.

In this post, I’m going to run through a few options for implementing the Model View Presenter (MVP) pattern using JavaFX. If you’re not familiar with MVP it’s basically the latest re-branding of the MVC pattern. The ‘Controller’ has been replaced with a ‘Presenter’ but the same big concepts apply. To be honest there’s so many variations and interpretations on MVC that you may already be using MVP under the guise of MVC anyway. This article does a decent job of quickly outlining the key differences, but there are loads more articles on the web. Martin Fowler, has provided a lot of analysis on MVP as well, and has split the term further.

We’re not going to get too hung up on theoretical purity and academic classifications however. Our goal is to get a usable pattern in place that just works, making it easier to develop and maintain a complex, production grade project. The theoretical semantics can be left to the academics who don’t have to build real world apps for a Monday deadline.

First Contact

First things first, we need an application to build. Something a little more complex than HelloWorld but still simple enough for us to easily work with. A very basic contact management system (i.e. an address book) should do the job. We’ll call it ‘First Contact’, and for the sake of simplicity it will have only two screens: a search screen that lets you filter the list of contacts, and a detail screen that lets you view and edit the basic details of each Contact.

The ‘search’ screen will look a little like this:

And the ‘detail’ screen will look something like:

The Business Layer

We’ll design the system as if the data was coming from a remote server (and probably a database) but since this post is all about UI design patterns we will just provide a local stub for this and not worry about the remote aspects (though you can easily use my earlier post on using Hessian to replace the local implementation with a remote one).

Our business layer consists of just a simple Contact bean, a ContactService interface for accessing the store of contacts and a local stub-implementation of this service for us to work with. The code for each of these is fairly trivial:

A note on Dependency Injection

If you’ve read my previous posts you’ll know that I’m a bit of a Dependency Injection (DI) fan, and I’d definitely recommend using either Guice or Spring as a DI toolkit to wire up your JavaFX applications.

I realise however that DI can seem like a magical and perhaps complex thing for a lot of people unfamiliar with it (a lot of desktop developers have not had a lot of exposure to it yet). I’m going to let you in on a little secret though: there is no magic to dependency injection. Seriously, all it means is to pass an instance into anther class rather than instantiating or looking it up from within that class itself. This has the rather fancy name of “Inversion of Control”, which just means the bean is no longer in control of looking up the resources, the thing that creates the bean has to look it up and pass it in.

So this:

public class MyClass
{
    private MyOtherClass myOtherClass;

    public MyClass()
    {
        this.myOtherClass = new MyOtherClass(); // or jndi.lookup("myOtherClass"), etc;
    }
}

becomes this:

public class MyClass
{
    private MyOtherClass myOtherClass;

    public MyClass(MyOtherClass myOtherClass)
    {
        this.myOtherClass = myOtherClass;
    }
}

If you’ve never taken the plunge into DI before, you’re probably wondering what all the fuss is about; if it’s just passing variables around, why is everyone always banging on about it. The answer to that is that while the pattern itself is incredibly simple, when you combine it with things like aspect-oriented-programming, annotations, mock objects for testing, etc this tiny shift starts to have powerful advantages.

So, in the interest of not scaring anyone off, and just to demonstrate how simple DI actually is, I’m going to avoid using any DI framework in these patterns. You won’t see any Guice or Spring in the following code. I’ll still use DI (i.e. I’ll pass variables in instead of instantiating them) but I’ll just wire it all up in plain, regular Java with no magical help from Guice or Spring.

Obviously, I’d recommend that you get familiar with and use a DI toolkit in your apps – depending on how I go for time, I may post the Spring and Guice equivalents of the below MVP patterns in a future post. If you’re keen to see this, post a comment to let me know.

The Patterns

Enough pre-amble, let’s get to it! Below are five different ways to build the same First Contact GUI outlined above. They all work, they are all OK. Some people will like one and others will prefer another. I have my favourites but it is totally up to you which one you choose to use.

Option 1: Keeping it Simple

In this option we use the most basic approach possible. Since we’re using MVP we obviously have a Model a View and a Presenter for each component on the screen.

Our View is focused solely on the visual representation of the screen; it is what the user sees. The View builds the layout of the controls and sets the styling but does none of the processing logic. When a user action occurs (such as a button click) the View passes this on to the Presenter for handling.

Our Presenter is then responsible for the ‘control’ logic. In this case it is responsible for interacting with our ContactService to load and save contact information. The Presenter is responsible for all threading and error handling. It is the brains behind the view and in many ways is the ‘boss’ of the view. If a button is clicked in the view, it is the Presenter that decides what happens and it then tells the View what information to show.

In this simple MVP scenario, our Model is just the Contact bean, which we defined as part of our Service model. It is a regular Plain Old Java Object returned by the ContactService. Unlike the more traditional MVC approach, the model in this case is somewhat temporal; the Presenter grabs a fresh Contact or list of Contacts from the Service every time the screen is loaded and passes this to the View. Once the data is loaded into the fields within the view, the bean is then discarded. In this approach our Model is more like a Data Transfer Object (DTO), used to transfer the data between our view and our ‘true’ model, which is the database hidden by our server.

Looking at our proposed UI, we obviously have two main screens: the ‘search’ screen and the ‘detail’ screen. As such, we’ll need a View and a Presenter for each of these. We’ll step through the more interesting bits of these now, but for reference, the full code for each of these is here:

Looking at our two views, the ContactSearchView and ContactDetailView, we see that these just create the controls needed and lay them out appropriately. When it comes time to handle a button click however, they simply call onto their Presenter (which has been passed into them via the constructor following the DI pattern).

In both views, the data they display (i.e. the search results and the contact details) is passed to them and neither view has any knowledge of how that data was loaded or the semantics behind that data. The ContactSearchView for example has no idea whether the terms in the search TextField match the data in the results ListView – this is not it’s job, like a good soldier, it just does what it is told, whether that’s right or not.

The Presenters are the more interesting players in this game. At the request of the View, these Presenters perform some threading to access the ContactService. This threading is overkill when we have a local service implementation (as we currently do), however if you are making remote calls you need to use Threads (see this slightly outdated post about it). I use a Task here, and given our Presenters are simply calling onto a service, Tasks are nearly always sufficient. You could easily substitute a Service but that is only useful if the code you are executing within the thread is complex and you want to reuse that code in several places.

So we have our two Views and two Presenters and they are nice, stand-alone modules. We need to integrate them however into our bigger application and provide a way to switch between these two views. To do this I have introduced another View, called the MainView, and a corresponding Presenter, called the MainPresenter. The MainPresenter contains the ‘search’ and ‘detail’ presenter and it controls which one is currently active and showing. The MainView is basically just a BorderPane with a header. Its content area (i.e. its center) acts much like a ‘CardLayout’, allowing the MainPresenter to swap the SearchView and DetailView in and out.

We provide both the ContactSearchPresenter and the ContactDetailPresenter access to the MainPresenter (via DI), so that they can request a change in the currently active screen. For example, the ContactSearchPresenter detects when a Contact has been selected in the search results and then it asks the MainPresenter to show the details for that Contact. This provides us with some reasonable decoupling, although it would be even better to use an event bus of some kind to control this navigational change. That’s one of the things JFX Flow does however, so if you want to go down that road I would suggest looking into JFX Flow before rolling your own solution (see option 5 below).

All we need to do now is wire up our three modules. As mentioned in the pre-amble, I’m not going to use Spring or Guice, which just means I have to do a bit more coding. All I really have to do is create a Factory for the whole UI and provide a factory method for each of the components of the application. To wire everything up I just call onto the factory methods as needed. This is really quite simple and you can see the code for yourself here:

Finally we just create an Application class to be the entry point for our First Contact application. Since most of the heavy lifting happens in our factory, the Application class is really quite simple; it just needs to create a new factory and extract the MainView from this and add it as the root of the scene. The code for this can be seen here:

Option 2: Interfaces for the purists

This second option is very similar to Option 1, however we introduce interfaces for all our Views and Presenters. This approach will probably be popular with purists and people from a strong dependency injection and aspect-oriented-programming background as it allows you to totally decouple your view and presentation implementations from each other. GWT developers also may find this approach comfortable as it is the recommended GWT design pattern (not surprising, since Guice and GWT are close friends).

Others, especially those coming from a more script-oriented language, such as Flash or JavaScript will probably be horrified by this ‘unnecessary’ bloat. This is a legitimate drawback to this approach – you end up with a lot of classes. I admit to being quite partial to this approach however (probably because of my JEE background, where this sort of thing is common place and familiar) but it is not for everyone. I also like FXML and as you’ll see in option 4, FXML does not lend itself to using this form of the pattern, so the debate becomes irrelevant if you’re using FXML anyway.

The code changes are really quite simple, where we had a single View before we now have a View (which is an interface) and a ViewImpl (which is the implementation of that View). Similar for the Presenter. These classes all then reference each other only by their interface, and only the factory class actually has any awareness of the implementations, which is what any purist will tell you is “as it should be”.

We end up with the following:

And our Factory now looks like this:

One of the big benefits of this approach is that it allows you to easily use Mock objects to test your components (although UI testing is still a messy topic at best so the benefits of this are only valid if you are going to put in the effort to actually test your GUI).

Option 3: MVP with a PresentationModel

In this option we introduce the concept of a PresentationModel, which is a model that represents the state of the view. In the case of the search view, for example, the model holds the current text in the search text field and the list of results showing in the results list.

So we end up with a Model for each of our three modules, like so:

Our Presenters then populate these models when they get data back from the server (instead of passing the data to the view directly). Our Views bind to the model properties (bidirectionally), so that whenever a change happens on the model it is reflected on the screen, and vice versa.

Our MainModel may look a little weird. Why does a Model have a Node in it? Remember that this is a ‘presentation’ model, and the ‘state’ of the MainView is really which sub-view it is showing. A node in the model is ok in this case. If we wanted to get pedantic (and someone always does) then we could have an enumerated type for the currently showing sub-view and this could be our model value, with the MainView mapping that to the appropriate Node. If you like that sort of stuff however, you might want to have a look at JFX Flow, which uses a ‘Place’ to represent the current active page and a whole lot more.

One positive with this approach is that it does allow us to make use of JavaFX bindings, which have been sadly unhelpful in our other options. On that basis, you would think the resulting code would be simpler and cleaner, but I don’t find it overly nice – there’s a lot of extra code for no obvious gain that I find useful. You are free to make up our own mind.

This pattern could be a lot more useful if we weren’t designing for a client-server application. If our Model could live in memory on the client side then having a shared model between the screens might become a lot more useful. These kind of applications are not overly common these days though (I haven’t had to make one since 2002).

You could also argue that we already have a PresentationModel in our other options. Each JavaFX Control contains a ‘model’ of sorts. For a TextField, this is the ‘text’ property, for a ListView it is the list of items. In this scenario however we create a model that is ‘control agnostic’ (meaning the model has no idea what type of control is being used to display the data) and then we expose that model to both the view and the presenter.

A quick academic side note: if we look at Fowler’s descriptions of MVP, then this approach is more in line with his Supervising Presenter pattern, whereas our previous options have been more the flavour of his Passive View pattern (where we use a DTO to pass the attributes to the view, and this DTO just happens to be our domain object).

Option 4: FXML and the MVP compromise

If you haven’t had a chance to play with FXML yet, I recommend giving it a go. FXML is an XML-based toolkit for building JavaFX scenes using a syntax that is simple enough for designers and junior coders to use, while still allowing your power coders to hook in and do the real work.

I’m usually the last person to advocate anything other than data being defined in XML and I’ve always hated XML GUI coding tools in the past. It’s strange then that I’ve come to like FXML but the key difference between FXML and other XML coding toolkits that I’ve seen is the clear separation of roles between view and control. In many other platforms, the XML ends up as a scripting language, and it is so verbose and clumsy for this that the resulting scripts are almost comical. In FXML the XML part is used only for layout, for any actual coding/logic, there is a natural fall-out to a ‘backing bean’ or controller.

So if FXML provides the controls and visual layout for our screen it is obviously a prime candidate for replacing the Java-based View’s we’ve defined in our previous options. This is good news, but it’s not all roses however. FXML has been designed with RAD tooling in mind (i.e. visual screen design tools), and seems to draw from backgrounds that are a little less rigorous in their design patterns than Java normally encourages.

As a result there are a number of areas where using FXML forces us to compromise on our pure MVP pattern. Here’s a few of them:

  • You have to specify your presenter (which FXML directly calls a controller) implementation inside your FXML. This breaks a fundamental concept of MVP, that the view and presenter should be decoupled as much as possible, and means you cannot reuse your view with another controller without copying the whole view again.
  • You can’t use interfaces for your presenter (as per option 2 above), since FXML needs a concrete class to instantiate.
  • The FXML loader instantiates the controller in internal code that we have no access to, so to make this work with a DI framework you have to jump through hoops to get setter injection to work (and constructor injection doesn’t work at all).
  • In order to access the fields of your view within your presenter (i.e. to show data on the screen), you have to expose the fields directly to the presenter using @FXML annotations. This means your presenter ends up knowing far too much intimate detail about your view.

There are a number of other smaller issues (like Controller inheritance not being supported) but for me, the end result is still better than not using FXML – the compromises are worth the benefits of the concise view syntax and simple notation for designers (i.e. it’s not too far a stretch for someone who know how to write HTML). There are also a couple of enhancements in the pipeline for JFX 2.1 that will improve (but not completely solve) some of these issues. You can make up your own mind whether the benefits are worth it to your or not.

So how does this FXML/MVP compromise look? First, the easy bits. We can directly convert our Views to FXML. This is very simple and the resulting code is quite a bit nicer:

There is one hurdle however, there’s no easy way to define our custom list renderer (i.e. the CellFactory) in FXML, it’s just too cumbersome. We end up having to define this within our presenter, which is not ideal.

Our Presenters are quite significantly different. Instead of interacting with a nice, contained view, the Presenters now have to access the plumping of the view directly. That is, they need to get a reference to the actual controls they want to interact with and manipulate them directly.

It’s worth noting that in the next release of FXML there is plans for bidirectional binding support, which will improve this somewhat, but it is unlikely to decouple our Presenter completely from the internal workings of the FXML defined View. The custom CellFactory is one example of this, and another is the need to have our callbacks include ‘view’ events such as the ActionEvent parameter needed for the ‘search’ method.

Here’s how our FXML-based Presenters look:

As I mentioned, we also now have some extra complexities in loading and wiring up our Presenters. The FXMLLoader does the instantiating for us, so we can’t use constructor based injection, instead we have to fall back to manually calling ‘set’ for every resource needed by each view.

You can see all the gory details here:

  • FirstContactAppFactory.java
  • All in all, a definite compromise on purity for the sake of convenience. I personally feel it is one worth making and am using FXML in all my applications. You can make up your own mind.

    Option 5: JFX Flow and MVP

    And finally, we have JFX Flow, which is a framework I’ve put together to provide some extra tools when working with JEE style applications, especially those you want to look more like a browser-based web-app. If you haven’t done so yet, check out the runnable showcase on the homepage for a general overview.

    JFX Flow can actually be used with any of the design patterns above. It is however designed with FXML in mind and encourages a pattern similar to that outlined in option 4. One of the biggest changes however, is that you don’t need a MainPresenter or MainView at all. These are provided for you out of the box with JFX Flow via the Browser class.

    The FXML for the JFX Flow option is identical to option 4, with no actual changes needed. The Presenters are similar in structure, however there are a couple of key changes.

    • Each Presenter needs to extend the JFX Flow AbstractActivity* base class.
    • Since we no longer have a MainPresenter, we need to use a NavigationManager instead. Each Presenter gets registered with Browser with a unique ‘place name’ that the NavigationManager can be used to navigate to.
    • We can use the activated() method to detect when a Presenter is made the active page. Any parameters needed for the page are passed to fields marked with the @Param annotation.
    • When we execute a task, instead of creating a new Thread directly we make use of the AbstractActivity.execute(Task) method. This gives us better error handling and blocks the screen while the load is in progress – two things we conveniently ignored in our earlier patterns.

    * Note: In JFX Flow I have opted for the term ‘Activity’ instead of Presenter and you will see this throughout the documentation. The two terms are interchangeable and just for consistency in this post I have left it as Presenter in the sample code. The Activity term has been popularised by GWT and I feel is a better fit than either ‘Controller’ or ‘Presenter’ (especially since JFX Flow does not dictate the use of either of these). The end result is quite nice and logical: a user navigates to a ‘Place’ to carry out an ‘Activity’.  

    Here are the JFX Flow versions of our Presenters:

    Our factory is where the Presenters are registered with the Browser:

    And our Application entry point now needs to use the Browser instead of the MainView:

    If we run this application as is, we see a GUI like following:

    Notice that the Browser bar has appeared for us, and we now have a back, forward and refresh buttons all for free. As we navigate between screens we see page transitions (the default is to fade in and fade out, but you can configure your own), and the screen will be blocked while our background threads are running.

    This is all pretty neat and more powerful than our previous patterns (otherwise there wouldn’t be much point to JFX Flow!). However it is not exactly the task we were given. We wanted to build an app identical to the others and currently we have this toolbar up the top and we don’t see our nice blue header.

    Luckily we can change that. The JFX Flow Browser provides a setHeader() method which can be used to completely replace the toolbar at the top. All we have to do is create a small class for our header and set this in its place. I’ve been lazy and just done this in code, but you could of course do this in FXML as you want:

    This is a very simple way to customise the Browser, however JFX Flow fully supports you totally redesigning your Browser and structuring it however you want. You can set the header (or set it to null) as described, or provide your own custom skin class, and if that isn’t enough for you, the tools are there to piece together your own Browser completely and build whatever layout you want with side-docking panes, shortcut bars and history lists (I’m working on this docco for this, promise!).

    Conclusion

    Well I hope that’s been a helpful introduction to JavaFX with the MVP pattern. There are plenty of other ways to put together a clean JFX application (and I’d love to hear from people out there if they have any improvements or alternatives) but the ones listed above should provide you with a nice base to work off.

    Obviously I have a strong preference to the JFX Flow approach and would suggest that your life will be a lot easier when building large, page-based GUIs if you make use of this framework. When it comes to design patterns however, it’s a case of finding the right shoe for the foot: I hope this article helps a few of you on your path to finding your Cinderella.

    Continue Reading→
      • Nov
      • 27
      • 2011

    JFX Flow early access

    Posted by In Uncategorized

    This entry is part 7 of 15 in the series Building JEE applications in JavaFX 2.0

    I started this blog a few weeks ago with the grand plan of stepping you through the process of building a clean architecture for building JEE, web-style GUI applications using JavaFX 2. As I wrote the first few blogs, I realised that if we stepped through each little twist and turn on the journey to a complete framework we’d be here for a few years. I also started to think that most of you probably don’t care about the details, you just want something that you can use so you can get on with the real job of building your applications and making your users happy.

    So, “here’s one I prepared earlier”. The more attentive of you will have already noticed a new new link called ‘JFX Flow‘ in the menu bar above. Go on, click on it. In fact, have a flick through the ‘showcase’ linked to from the main page just to get a feel for what I’m talking about here.

    This is an alpha version of a framework I’ve put together with all of my ideas in it for building web-style applications in JavaFX. I’m still fleshing out the documentation (yea, I leave the least fun stuff till last too) The core features are good enough to use right now (I’m using it in two of my projects currently, one which is a decent way along), however some of the supporting features (such as dialogs) are still a little rough around the edges and I can’t guarantee the API for some of these won’t change a little over the next few weeks.

    It’s all free and open source. I’ve also tried as much as possible to make it so that you guys can customise bits and pieces without having to rewrite everything. If you want your own funky Browser that’s all in 3D and has flying magical dragons on it, you can write one (assuming you know how to use the javafx.magical.dragon package) and just plug it in.

    I’ve deliberately limited JFX Flow to the GUI aspects of a JEE system. It’s goal is to allow you to build GUIs that provide the user with a familiar and enjoyable experience, and at a code level support dependency injection, have nice threading and error handling, and use a clean separation of concerns (view vs control, etc).

    You won’t see anything in there specifically for database or server communication however. JFX Flow provides the ‘presentation’ tier only. It has ways to integrate with the back-end tiers but it does not give you an end-to-end JEE stack. JEE is at its best when it provides the developer with the freedom to mix and match technologies at each level of the stack. Specific projects always have their own specific requirements. Sometimes you need to use message queues and XML, sometimes you can make pure-Java RPC calls and can use Hibernate, and sometimes you might have to integrate with something weird like Google’s App Engine, or a legacy mainframe system. JFX Flow aims to give you that power, while making the front-end a bit easier to develop.

    I’m guessing a lot of you probably still want to know how to do all that database and server communication stuff though. That’s what the rest of this blog will be about. Now that we’ve got a JavaFX presentation layer for our JEE stack, we can start looking at how this can be used for common scenarios. Those of you already familiar with the business and data layers of the JEE stack can go on ahead, JFX Flow is ready for you to use. The rest of you, stick with me and let’s see what we can come up with. For now have a play with JFX Flow and let me know what you like, and don’t like.

    Continue Reading→
      • Nov
      • 14
      • 2011

    File Downloading in JavaFX 2.0 (over HTTP)

    Posted by In Uncategorized

    I had to implement a File Download service for something I’m working on this week and thought I’d share.

    File downloading is pretty easy these days if we use something like Apache’s HttpComponents. This can do all sorts of stuff, like proxy-support, retry-on-error and HTTP Basic Authentication. I won’t go into too much detail on this as we only need the basics here, but you can find a lot of good information about it on the web (check out their tutorial for a good starting point).

    The trick to getting it working in JavaFX is the threading. Downloading a file is obviously a slow operation, the kind of thing we want to do on a background thread so we’re not blocking our GUI. Using JavaFX’s threading Worker framework we can create a fairly nifty little re-usable class for this sort of Downloading.

    Have a look at the full source code for the FileDownloadTask first. As you can see, the main work happens in the ‘call’ method, so we’ll step through that in detail.

    First we open a connection to our download URL. Using HttpClient this is ridiculously easy:

    HttpGet httpGet = new HttpGet(this.remoteUrl);
    HttpResponse response = httpClient.execute(httpGet);
    

    There are a number of different ways we could access our response, we could get the whole thing as a String or a byte array for example, but for downloading files we want to use streams. This is as easy as:

    InputStream remoteContentStream = response.getEntity().getContent();
    

    Now we have our stream, we can use simple Java streaming to copy from our remote stream to a local file stream, but since we’re JavaFX programmers and we want to make nice, friendly GUIs for our users were going to add some support for tracking how much of the file we’ve downloaded and how much we have left to do.

    First, we find out just how big our file is, using this command:

    long fileSize = response.getEntity().getContentLength();
    

    Now we can create our local file and get it ready for writing to:

    File dir = localFile.getParentFile();
    dir.mkdirs();
    localFileStream = new FileOutputStream(localFile);
    

    We’ll use a buffer to read chunks of data from the remote fiel and push this into our local file, as we go we’ll keep track of how many bytes we’ve downloaded:

    int sizeOfChunk;
    int amountComplete = 0;
    while ((sizeOfChunk = remoteContentStream.read(buffer)) != -1)
    {
        localFileStream.write(buffer, 0, sizeOfChunk);
        amountComplete += sizeOfChunk;
        updateProgress(amountComplete, fileSize);
    }
    

    Notice, the call to ‘updateProgress’, this is a method provided by Task that allows us to update the ‘progress; property of our task in a thread safe way. UI Controls (such as the ProgressBar) can bind to this property to monitor the progress of the download without having to do any special thread handling on their end.

    That’s more or less all there is to it from the service perspective, to use this service anywhere in your code you just do the following:

    FileDownloadTask fileDownloadTask = new FileDownloadTask("http://www.tagg.org/pdftest.pdf", "c:/temp/downloaded.pdf");
    

    Generally, when you use this class there are a few tips and tricks that can be helpful.

    If you want the user to choose where the download should be saved, you can use JavaFx’s FileChooser like so:

    String remoteUrl = "http://media.beyondzeroemissions.org/ZCA2020_Stationary_Energy_Report_v1.pdf";
    FileChooser chooser = new FileChooser();
    File file = chooser.showSaveDialog(stage);
    if (file != null)
    {
        FileDownloadTask fileDownloadTask = new FileDownloadTask(remoteUrl, file);
        new Thread(fileDownloadTask).start();
    }
    

    To create a Progress Bar and have it display the progress of your download do the following:

    ProgressBar progressBar = new ProgressBar();
    progressBar.progressProperty().bind(fileDownloadTask.progressProperty());
    progressBar.visibleProperty().bind(fileDownloadTask.runningProperty()); // optionally hide the progress bar when not loading
    

    To create a launch button that is only enabled when the file is successfully download you can do this:

    Hyperlink link = new Hyperlink();
    link.setText(fileDownloadTask.getLocalFile().getName());
    link.disableProperty().bind(fileDownloadTask.stateProperty().isNotEqualTo(Worker.State.SUCCEEDED));
    link.setOnAction(new EventHandler()
    {
        public void handle(ActionEvent event)
        {
            try
            {
                Desktop.getDesktop().open(fileDownloadTask.getLocalFile());
            }
            catch (IOException e)
            {
                // todo handle this by showing an error message
                e.printStackTrace();
            }
        }
    });
    

    I won’t bore you with the details of it all, but you can see a simple little demo of this all in action using this code found at: http://code.google.com/p/jfxee/source/browse/trunk/jfxee8/pom.xml

    When you get it all running it should look like this:

     

    Continue Reading→
      • Nov
      • 03
      • 2011

    Client Server with JavaFX 2 and Hessian (+Guice +FXML)

    Posted by In Uncategorized

    This entry is part 6 of 15 in the series Building JEE applications in JavaFX 2.0

    Ok, due to popular demand, I’m going to fast track a bit of this walk through. I had planned to do more on the client end first, but it seems everyone wants to know how to build a client-server app (apparently that Internet thing has really taken off).

    So in this post we’re going to build a very simple hello world client-server application, using HTTP. We’re going to use Hessian to make all our client-server communication nice and easy. There are a whole load of other communication options out there but Hessian is simple, lightweight and just works.

    By the looks of it people are favouring Guice over Spring at this stage, due to the concept of it being ‘lightweight’. As such, I’m going to stick with Guice as our DI toolkit for the front-end. In later posts we’ll have a look at changing over to Spring, which really starts to show its advantages when we start working with database transactions and security.

    This topic is a little more in-depth than some of the previous stuff. If you’ve never written a servlet or basic web application before, you may want to brush up on this first. Also, we’re going to use some JavaFX threading which is only lightly documented at this stage, and the API is just a little raw still too in my opinion. It may be a bumpy ride for some.

    The full source code (as a multi-module maven project) can be found at: http://code.google.com/p/jfxee/source/browse/trunk/jfxee7/

    Step 1: Design your application

    We’re going to keep things as simple as we can. We will have a simple client that allows the user to enter their first and last name. The client will then pass these details to the server and the server will return a simple welcome message based on the name entered.

    If we get everything right, our client will end up looking like the following:

    Step 2: Create a Service interface

    The great thing about Hessian is that it allows us to define our client-server protocol in pure Java objects. It works in a very similar way to RMI, where you define an interface for your server, which your server implements and client accesses. Hessian then provides the magical wiring underneath our interface to serialize our data and send it (over HTTP) to the server, where it gets deserialized and passed into our server implementation. Pretty sweet.

    For our example, our service interface is very simple and looks like this:

    public interface HelloService
    {
        String sayHello(Person person);
    }
    

    This is our ‘contract’ between the client and the server. The client will call the sayHello method and the server will implement it.

    We could pass two strings into the sayHello method for the first name and last name, but to make things a little bit interesting and show the power of Hessian, I have chosen to encapsulate all this in a Person bean. Hessian will magically handle all the serialization for this.

    Our person bean is a standard serializable Java bean and looks like this:

    import java.io.Serializable;
    
    public class Person implements Serializable
    {
        private String firstName;
        private String lastName;
    
        public Person(String firstName, String lastName)
        {
            this.firstName = firstName;
            this.lastName = lastName;
        }
    
        public String getFirstName()
        {
            return firstName;
        }
    
        public String getLastName()
        {
            return lastName;
        }
    }
    

    Step 3: Create a Service implementation

    Now that we’ve defined the contract between our client and server, we need to have our server fulfill that contract. We’re keeping things simple in this example: our server will simply build a message out of the Person details and send this back to the client. In a real world application, your server will likely hit a database, provide some security and do all the other things that a serious application does, but we won’t worry about that here.

    Our service is just another Java object that implements the HelloService interface we defined above. The only special thing about it is that it extends HessianServlet, which is a custom servlet provided by the Hessian platform. All the magic happens in here and by simply extending it we have a ready-to-roll server implementation. Too easy.

    Our service implementation looks like this:

    package com.zenjava.jfxee7;
    
    import com.caucho.hessian.server.HessianServlet;
    
    public class HelloServiceImpl extends HessianServlet implements HelloService
    {
        public String sayHello(Person person)
        {
            // in the real world, use a logging API like slf4j or log4j
            System.out.println(String.format("The server received a request from %s %s",
                    person.getFirstName(), person.getLastName()));
    
            return String.format("The server says hello %s %s!",
                    person.getFirstName(), person.getLastName());
        }
    }
    

    Step 4: Run your server as a web application

    The next step is to publish our service as a web service. I’m going to assume you are at least a little familiar with creating normal servlets and building webapps. If not, you probably want to google these topics – there’s a wealth of information out there on this, just ask Google.

    To publish our service we create a web.xml that loads our HelloServiceImpl as a servlet. The HelloServiceImpl is no different to any other servlet and can be exposed in exactly the same way:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
        <servlet>
            <servlet-name>HelloService</servlet-name>
            <servlet-class>com.zenjava.jfxee7.HelloServiceImpl</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>HelloService</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
    
    </web-app>
    

    From here you simply have to bundle your application into a war file and then deploy it to a server. I use Maven for all my builds and this makes this step extremely easy. Check out the example POM for this. If you’re using ANT (maybe it’s time to upgrade :) ) then you might find something like this helpful: http://javabeanz.wordpress.com/2009/02/12/how-to-create-a-war-file-using-ant/

    The resulting war file can be deployed to any servlet friendly server. I use good old Tomcat but you can use Jetty, Resin or any of the other free ones out there. If you’re insane, you can pay for one of the commercial JEE servers (but really, don’t bother).

    Step 5: Create a view and controller

    Our server is now deployed and running, and we’re ready to build our client. The first part is easy, we just build a GUI to service our needs. I’m going to use the same Guice + FXML approach as in my last post but you could use the Spring approach, or even roll it all by hand and use no Dependency Injection at all if you’re into an old-fashion style.

    Here’s our view:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?language javascript?>
    <?import java.lang.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    
    <VBox fx:id="view"
          fx:controller="com.zenjava.jfxee7.HelloController"
          spacing="6"
          xmlns:fx="http://javafx.com/fxml">
    
        <styleClass><String fx:value="enterDetails"/></styleClass>
    
        <children>
    
            <Label fx:id="messageLabel" text="Waiting for your input">
                <styleClass><String fx:value="message"/></styleClass>
            </Label>
    
            <Label text="First Name"/>
            <TextField fx:id="firstNameField"/>
    
            <Label text="Last Name"/>
            <TextField fx:id="lastNameField"/>
    
            <Button text="Connect to Server" onAction="#submit"/>
    
        </children>
    </VBox>
    

    And here’s our controller:

    
    import com.google.inject.Inject;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.scene.Node;
    import javafx.scene.control.Label;
    import javafx.scene.control.TextField;
    
    public class HelloController
    {
        @FXML private Node view;
        @FXML private Label messageLabel;
        @FXML private TextField firstNameField;
        @FXML private TextField lastNameField;
    
        public Node getView()
        {
            return view;
        }
    
        public void submit(ActionEvent event)
        {
            // todo implement this to talk to the server
        }
    }
    
    

    Step 7: Use Guice to load the UI and inject the service

    In order for our client to connect to the server, all it needs to do is use the HelloService interface we created earlier and use Hessian to load this. The following code will do the trick:

    HessianProxyFactory factory = new HessianProxyFactory();
    String serverUrl = "http://localhost:8080/hello";
    HelloService helloService = (HelloService) factory.create(HelloService.class, serverUrl);
    // use the helloService object now and hessian will magically make the calls on the server for you
    

    This is basic Hessian stuff – we use the HessianProxyFactory to create a new instance of our HelloService for us, passing in the URL of our server. The factory then creates a ‘proxy’ (in this case, you could call it a ‘stub’), that implements the interface by making HTTP calls onto the servlet on the server side. The Proxy and the servlet work together to serialize the data between each other and make the actual call on the server. From our end, it’s all just nice simple Java.

    We could create this proxy anywhere in our code and use it via plain Java calls and for this simple little scenario that would do the job. In our last post however we looked at ways to use Guice to load our controllers and provide Dependency Injection and this is a great candidate for this. As our project gets bigger and we end up with more controllers wanting to use more services, this DI is really going to pay off.

    In order to inject our service using Guice, we first add the following line to our HelloController:

    @Inject private HelloService helloService;
    

    And now we can just wire up everything in our Guice module. I’m going to use instance injection in this case, but you could use the provider style approach just as easily. The instance injection approach looks like so:

    import com.caucho.hessian.client.HessianProxyFactory;
    import com.google.inject.AbstractModule;
    import javafx.fxml.FXMLLoader;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    
    public class HelloClientModule extends AbstractModule
    {
        protected void configure()
        {
            try
            {
                HessianProxyFactory factory = new HessianProxyFactory();
                String serverUrl = "http://localhost:8080/hello";
                HelloService helloService = (HelloService) factory.create(HelloService.class, serverUrl);
                bind(HelloService.class).toInstance(helloService);
    
                bind(HelloController.class).toInstance((HelloController) loadController("/Hello.fxml"));
            }
            catch (MalformedURLException e)
            {
                // NOTE: this is not best-practice for exception handling. Check the
                // Guice documentation for better ways.
                throw new RuntimeException(String.format("Error connecting to server"), e);
            }
            catch (IOException e)
            {
                // NOTE: this is not best-practice for exception handling. Check the
                // Guice documentation for better ways.
                throw new RuntimeException(String.format("Error loading FXML file"), e);
            }
        }
    
        protected Object loadController(String url) throws IOException
        {
            InputStream fxmlStream = null;
            try
            {
                fxmlStream = getClass().getResourceAsStream(url);
                FXMLLoader loader = new FXMLLoader();
                loader.load(fxmlStream);
                return loader.getController();
            }
            finally
            {
                if (fxmlStream != null)
                {
                    try
                    {
                        fxmlStream.close();
                    }
                    catch (IOException e)
                    {
                        System.out.println("Warning: failed to close FXML file");
                    }
                }
            }
        }
    }
    

    And then to launch our application, we simply have:

    
    import com.google.inject.Guice;
    import com.google.inject.Injector;
    import javafx.application.Application;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    public class HelloClient extends Application
    {
        public static void main(String[] args)
        {
            launch(args);
        }
    
        public void start(Stage stage) throws Exception
        {
            Injector injector = Guice.createInjector(new HelloClientModule());
            HelloController helloController = injector.getInstance(HelloController.class);
            Scene scene = new Scene((Parent) helloController.getView(), 320, 240);
            scene.getStylesheets().add("styles.css");
            stage.setScene(scene);
            stage.setTitle("JFX2.0 Sprung");
            stage.show();
        }
    }
    

    Step 8: Call the server in a background thread

    So we have a server and a client, and our controller has access to the server via the HelloService. Now we can just make the following call in our controller right?

    public void submit(ActionEvent event)
    {
        Person person = new Person(firstNameField.getText(), lastNameField.getText());
        String messageFromServer = helloService.sayHello(person);
        messageLabel.setText(messageFromServer);
    }
    

    There’s two problems with this though: threads and exceptions.

    Now that the call to sayHello() is actually a remote call to a server it could be slow. Depending on the network speed it could take seconds for the client and server to do all the socket and serialization work. Java FX (like Swing) uses a single thread for application processing. If we lock this thread up waiting for the server to respond then our UI will become unresponsive as the application thread won’t be able to process mouse moves or even redraw the screen (this is a slight simplification of how threads and rendering work in JFX but from our point of view this is enough for us to know).

    As well as the threading issue, we’ve also introduced a lot more room for things to go wrong: the server may be down, the client may have lost internet connection, the wrong URL may have been entered, etc. These will all be thrown as runtime exceptions so we could just ignore them and have the system crap out but this is not very nice for our users. Ideally we need to start handling these errors and show the user a friendlier message, such as “Hey mate, did you forget to plug in your network cable again?”, so they can actually do something about it and try again.

    Fortunately JFX has an answer to both of these problems, and that answer is the Worker/Task/Service framework. Unfortunately this is not a simple toolkit to use (although if you are familiar with SwingWorker you will have a good head start) and even more unfortunately there is extremely little documentation on this as yet. The only real guide that I’ve found is this post from Richard that uses an early version of the framework while still in beta. The API has been tidied up a little since and Richard also neglected to give us too much detail on how to actually handle the response from the server, or handle errors.

    We can muddle through it however, and by piecing all the bits together here’s a threading approach that works:

    public void submit(ActionEvent event)
    {
        // extract person details from the screen
        final Person person = new Person(
                firstNameField.getText(),
                lastNameField.getText()
        );
    
        // pass the details to the server in a worker thread
        final Task task = new Task()
        {
            protected String call() throws Exception
            {
                return helloService.sayHello(person);
            }
        };
    
        // handle the result
        task.stateProperty().addListener(new ChangeListener()
        {
            public void changed(ObservableValue source,
                                Worker.State oldState, Worker.State newState)
            {
                if (newState.equals(Worker.State.SUCCEEDED))
                {
                    messageLabel.setText(task.getValue());
                }
                else if (newState.equals(Worker.State.FAILED))
                {
                     // always log your system errors with stack trace (please!!!)
                    messageLabel.setText("Oh no, a system error, we're all going to die!");
                    Throwable exception = task.getException();
                    exception.printStackTrace();
                }
            }
        });
    
        // start the task in a thread
        messageLabel.setText("Contacting server...");
        new Thread(task).start();
    }
    

    As you can see this approach uses a ‘Task’, which is the simplest unit of the Worker framework. The Service base class is much more powerful (you can cancel active threads for example) but is more complex to use. For an example of using a Service, check out this forum topic: https://forums.oracle.com/forums/thread.jspa?messageID=9928424&#9928424

    We also have pretty simple exception handling here. Ideally we would check the type of the Exception thrown and provide an error message to match. To do this we just use a big if-else statement and instanceof like so:

    else if (newState.equals(Worker.State.FAILED))
    {
        Throwable exception = task.getException();
        if (exception instanceof HessianConnectionException)
        {
             messageLabel.setText("Couldn't connect to the server, sorry about that.");
        }
        else
        {
             // always log your system errors with stack trace (please!!!)
             messageLabel.setText("Oh no, a system error, we're all going to die!");
             exception.printStackTrace();
        }
    }
    

    A note on building, deploying and running

    Above are all the bits and pieces we need for our client and server communication and if you’re familiar with web applications and this style of development that’s probably all you need to know. Simply deploy your generated WAR file to your web server, edit the URL in the client to match and then run HelloApplication. Sorted.

    For anyone who is not familiar with this stuff however, there are a few gotchas to be aware of when it comes to deploying and running. Firstly is how to package all of this up. You have two separate applications now, a client and a server, but they both share the common service API. You could bundle all the classes together and deploy it this way if you’re being lazy, but you should really separate them to avoid bloat, especially the client which typically is downloaded.

    In my setup, I have one module (bundles into a jar) for the ‘common’ code, which includes the HelloService interface and the Person bean. Then my ‘client’ module has all my client code (bundled into a jar) and my ‘server’ module has all my server code (bundled into a war). The client and server then reference back to the ‘common’ module as if it were a third party library. It’s a little more complicated but it is the cleanest separation – you are free to make your own setup work for you.

    When you deploy your web application the server will have a base address (such as http://zenjava.com) where the server (e.g. Tomcat) is running. When you run locally this address will typically be http://localhost:8080. Depending on how you deploy your WAR file it may then be allocated a sub-domain. In Tomcat for example, if you name your WAR file ‘helloserver.war’ and then put this into Tomcat’s ‘webapps’ directory, the URL you will need to use in your HelloClientModule is “http://localhost:8080/helloserver/hello”.

    Ultimately you will likely want to deploy your client via webstart and then you will want it all bundled into your server (but not on the server’s classpath just for some added complexity). I’m not going to confuse people further with this here, if you can’t work out the packaging side of it yourself just run the client from within the IDE for now. I am planning to post something on doing this sort of complex deployment using Maven (our best friend in this situation) in a future post.

    The above is hopefully enough to get you started on the road to developing client-server Java FX 2 applications over the web.

    Enjoy!

    The full source code for this post (as a multi-module maven project) can be found at:http://code.google.com/p/jfxee/source/browse/trunk/jfxee7/

    Continue Reading→
      • Oct
      • 30
      • 2011

    Better Controller Injection with Guice

    Posted by In Uncategorized

    By request, here’s how to do the better controller injection I outlined in an earlier post, but using Guice instead of Spring.

    It’s worth noting however, that JavaFX 2.0.2 is targeted for release in about a month or so (or so Richard has alluded to in this forum topic), and that this should have a way to control how FXML instantiates its controllers. This should make it possible to use both Spring and Guice in more natural ways. If you’re reading this and 2.0.2 has been released, you may want to look for a more recent post.

    But for now, here’s how it goes. We’ll use Richard’s example as a basis again, merging in the concepts from my previous post.

    Person.java and sample.fxml are unchanged from the previous post.

    In SampleController.java, we simply revert back to using Guice’s @Inject instead of Spring’s @Autowired.

    public class SampleController
    {
        @FXML private Node view;
        @Inject private Person person;
    
        ...
    }
    

    The biggest change is in our application factory. Instead of our SampleAppFactory, which was essentially a Spring configuration file, we have a Guice module instead, called SampleAppModule.

    There are a few different options for loading our controllers in this module. The easiest way is to bind our Controller class directly to an instance, using the toInstance() binding method. This allows us to do the instantiation (or rather allows FXMLLoader to do the instantiation at our request) and then Guice takes care of all the injection from there. If we use this option, our SampleAppModule.java looks like this:

    import com.google.inject.AbstractModule;
    import javafx.fxml.FXMLLoader;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    public class SampleAppModule extends AbstractModule
    {
        protected void configure()
        {
            // we can use instance binding for the person object, or if it had an empty
            // constructor (as in Richard's example) we could use the default Guice binding
            bind(Person.class).toInstance(new Person("Richard"));
    
            // OPTION 1: bind to an instance
            bind(SampleController.class).toInstance((SampleController) loadController("/sample.fxml"));
        }
    
        protected Object loadController(String url)
        {
           // normal loading stuff here - see full code for details
        }
    }
    

    The only limitation with this approach is that all our controllers will be created up front when the application starts. Depending on your requirements, this could be a good thing or it could be a bad thing – basically trading startup load time for in-application load time.

    If you don’t want to load everything straight away and need to delay the loading, then the alternative is to use Guice Providers. You can create a whole Provider class if you want, however it is much easier to just annotate a provider method in your module for these simple cases.

    There is a drawback to this approach however. Once we’ve told Guice we want to use a provider, Guice no longer injects our dependencies for us. The best we can do is ask Guice to inject our provider method with dependencies and then we have to manually inject these into our created class (this seems a little limited, and perhaps I have missed something in Guice here – if anybody knows a way around this, please post in the comments).

    Using the provider option, our SampleAppModule looks like this:

    <pre>import com.google.inject.AbstractModule;
    import javafx.fxml.FXMLLoader;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    public class SampleAppModule extends AbstractModule
    {
        protected void configure()
        {
            bind(Person.class).toInstance(new Person("Richard"));
        }
    
        // OPTION 2: use a provider - the person parameter is the one bound in the configure() method
        @Provides
        public SampleController sampleController(Person person)
        {
            System.out.println("Creating controller");
            SampleController controller = (SampleController) loadController("/sample.fxml");
    
            // we have to manually set our person object since Guice has washed its hands of this
            // controller leaving it all up to us to create and configure (i.e. 'provide') it
            controller.setPerson(person);
    
             return controller;
        }
    
        protected Object loadController(String url)
        {
           // normal loading stuff here - see full code for details
        }
    }
    

    The full code for this post can be found at: http://code.google.com/p/jfxee/source/browse/trunk/jfxee6/

    Continue Reading→