Using Font Awesome Icons in a JavaServer Faces h:commandButton

This will be a short blog. Today I spent way too much time looking for a solution. I am writing a web app for my GoPiGo3 robot car. The first version used 5 JSF h:commandButton buttons labelled forward, right, reverse, left and stop. I wanted to replace them with icons from the Font Awesome library. I thought this was a common way to dress up a button but I was wrong. A shout out to the freeCodeCamp site and the forum question that contained the answer https://forum.freecodecamp.org/t/solved-adding-font-awesome-icons-to-an-input-button/74139. It was John Kennedy’s answer to the question “Adding Font Awesome Icons to an input button?”.

While John’s answer dealt with plain HTML, the attributes he used are also found in the JSF h:commandButton tag. Here is what my robot control panel first looked like:

Next, using Font Awesome icons:

My projects are always Maven based. To be able to use Font Awesome I added the following dependency.

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>font-awesome</artifactId>
    <version>4.7.0</version>
</dependency>
Maven dependency for Font Awesome

The current version of Font Awesome is 5.0.13 but as of this writing I am unable to get this version to work. I have emailed the Font Awesome people concerning this.

Next is the JSF page. Here is the original version with just text. If you know me then you may wonder why I am not using i118n. For this blog I have purposely removed references to bundles and have hard coded the text. The production version will use i18n. I have also removed all actions to simplify the code.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <h:head>
        <title>GoPiGo3</title>
    </h:head>

    <h:body>
        <h1>GoPiGo3 Control</h1>
        <h:form id="gopigo" >
            <h:panelGrid columns="3" cellpadding="1" border="0" cellspacing="10">
                <h:panelGroup />
                <h:commandButton id="forwardButton" value="forward"/>
                <h:panelGroup />
                <h:commandButton id="leftButton" value="left" />
                <h:commandButton id="stopButton" value="stop" />
                <h:commandButton id="rightButton" value="right" />
                <h:panelGroup />
                <h:commandButton id="reverseButton" value="reverse" />
                <h:panelGroup />
            </h:panelGrid>
        </h:form>
    </h:body>
</html>
index.xhtml with test for buttons

Here is the Font Awesome version. Take note of the h:outputStylesheet in the h:head section. For the buttons I refer to the Unicode value for the icon and the matching class name. The class name has three parts. The first is the library name, fa. The second is the name of the icon such as fa-arrow-right. The third, fa-3x, is a size multiplier. Font Awesome icons are displayed based on the current CSS value of the page so the multiplier allows you to enlarge the icon without enlarging anything else.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <h:head>
        <title>GoPiGo3</title>
        <h:outputStylesheet library="webjars" name="font-awesome/4.7.0/css/font-awesome.min-jsf.css" />
    </h:head>

    <h:body>
        <h1>GoPiGo3 Control</h1>
        <h:form id="gopigo" >
            <h:panelGrid columns="3" cellpadding="1" border="0" cellspacing="10">
                <h:panelGroup />
                <h:commandButton id="forwardButton" value="" class="fa fa-arrow-up fa-3x" />
                <h:panelGroup />
                <h:commandButton id="leftButton" value="" class="fa fa-arrow-left fa-3x" />
                <h:commandButton id="stopButton" value="" class="fa fa-hand-stop-o fa-3x" />
                <h:commandButton id="rightButton" value="" class="fa fa-arrow-right fa-3x" />
                <h:panelGroup />
                <h:commandButton id="reverseButton" value="" class="fa fa-arrow-down fa-3x" />
                <h:panelGroup />
            </h:panelGrid>
        </h:form>
    </h:body>
</html>
index.xhtml with Font Awesome icons

You can see all the icons available in version 4.7 of Font Awesome at https://fontawesome.com/v4.7.0/cheatsheet/

There you have it. There is a price to pay for this. I wanted 5 icons from Font Awesome and the Font Awesome jar file is 674 KB. I will likely switch to using 5 small jpeg images for the buttons as the application needs to run on a Raspberry Pi. My students frequently use Font Awesome as part of Bootstrap and Primefaces. I wanted to learn how to use Font Awesome on its own.

REST Client Code Generated by NetBeans Does Not Handle Lists and the Solution

In my Introduction to Java Web Services course I use as an example a web service that returns a List of JPA entity objects of type Fish. A Fish is just several fields that describes different aspects of aquarium fish. For many years, going back to 2004, I only showed SOAP services. The code generator in my favourite IDE, NetBeans, output working server and client code. Then about five years ago I added REST services to my curriculum.

The NetBeans code generator for REST services produced workable code except in one situation for REST clients. The List type could not be returned by the generated code. Here is what the client generated code looks like:

public <T> T getJson(Class<T> responseType) throws ClientErrorException {
    WebTarget resource = webTarget;
    return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType);
}
REST client method

To call this code I used:

List<Fish> fishies = client.getJson(List.class);
Calling the REST service

When I ran this code, I received the following error message:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.List, genericType=interface java.util.List.
Error message

This error has been around from the first time I explored REST services. After spending a few hours looking for a solution five years ago I came across one that showed by adding a dependency to my pom.xml the code will work.

<dependency>
    <groupId>com.owlike</groupId>
    <artifactId>genson</artifactId>
    <version>1.4</version>
</dependency>
Maven dependency

Genson, a Java and Scala JSON conversion library, was created to deal with several issues in REST services, one of which was to simplify working with List. You can learn more about this library at https://owlike.github.io/genson/. I added the dependency to the client pom file and never gave it another thought until today. How could jax-rs not be able to handle a List? So, I did more research.

I discovered that this was a problem that many had encountered and not just NetBeans users. There were several suggested solutions, but the one that made the most sense showed me that the problem was not with jax-rs but with the code that NetBeans generated.

The solution came from Adam Bien’s blog. Adam is one of the foremost Java EE developers and trainers who is in great demand as a speaker. I have had the good fortune of meeting him at JavaOne. His blog at http://www.adam-bien.com/roller/abien/entry/jax_rs_returning_a_list showed that responses from a REST service that are in a List must be wrapped in a GenericType class. First, I changed the generated getJson method, renaming it getJson2:

public List<Fish> getJson2() throws ClientErrorException {
    WebTarget resource = webTarget;
    return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON)
        .get(new GenericType<List<Fish>>() { });
}
Corrected method for returning a List

If you compare this to the generated code shown earlier in this article you will see that this method is now tightly coupled to the data type it is returning. The generated code was designed to work in all cases because it used generics. As generated, you needed to pass the class of the returned data. Problem is that you cannot pass a generic type such as List<Fish>.class instead of List.class.

When the return type is a generic collection, Adam pointed out that it must be wrapped in a GenericType class that is part of jax-rs. The code that NetBeans produces should work in all cases but not in this case.

The dependency for Genson is now removed and my executable client is 378K smaller.

Thanks to Adam Bien for his article. Read his blog at http://www.adam-bien.com and follow him on Twitter at @AdamBien