Java EE 7 Web Profile Maven pom.xml Using Arquillian, Selenium, MySQL, Primefaces and EclipseLink

  1. Update: Removed unnecessary eclipselink dependency 2017-02-27 14:46
  2. Update: Changed skipTests value to false in Surefire dependency in the complete pom file 2017-02-27 15:18

If you are not using Maven then you should. If you are using Maven then you are likely cutting and pasting snippets of pom.xml file examples and hoping for the best. In this article I will present the pom.xml file that I require my students to use in an e-commerce project course. Not everything in it is required and you likely have libraries you need that are not in my example. After reviewing my pom.xml you should be able to make all the changes you need. You can find the complete file at the end of this article.

This is my third article on the pom.xml file that I have written. The last time I wrote about it was two years ago and while Maven has not changed I have learned more about the pom.xml. If you are not using Maven because a practical explanation of the elements required in the real world are rare, then hopefully this will change your mind.

Whether you work from the command line or with an IDE such as NetBeans (my favourite) one issue comes up over and over again. How do I make sure all the libraries I need get included in my project? It used to be for me that I needed to track down the web site for every library I wanted to use, download the jar and manually paste it into a location on the classpath or a specific folder in IDE. Packaging an application for distribution was also an issue because I needed to ensure that all the right jars were included in the uber archive, jar or war, I planned to distribute.

There is more to Maven than just including libraries. I use it to upload Java programs to my Raspberry Pi and execute them. I use Maven to control when I want unit testing to occur. There is much, much more it can do. The one task that drives my continual writing about Maven is that I use it in the classroom. I teach software development at Dawson College in the final year of the program. I like teaching coding but I am not fond of teaching the necessary plumbing to make systems work. I use NetBeans in my courses because it does not need to be managed the way Eclipse or IntelliJ needs to be. I use Maven for the same reason. I provide my students with a standard Maven pom.xml file that ensures that they all begin from the same baseline. Here is that pom.xml file.

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

 Every XML document should begin with an XML declaration. While the version has remained 1.0, it is the encoding attribute that is important. UTF-8 means that this document is encoded using the Unicode standard in which the first 128 characters map to Unicode. For more information on UTF-8 I recommend http://www.fileformat.info/info/unicode/utf8.htm


 <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">

  This is the root tag for this XML document. An XML document must be well formed and valid. Well formed means that all tags are properly nested and have a matching closing tag. Valid means that the tags and attributes you are using are part of this specific XML language. Testing for validity requires a schema and that is what is referred to in the root project tag. The schema is also used by the IDE to validate while you enter the tags into the file.


     <!-- Maven version of the xml document currently only 4.0.0 is valid -->
    <modelVersion>4.0.0</modelVersion>
 

      As the comment says, its always 4.0.0.


     <!-- The GAV consists of an arbitrary descriptor that is usually in the
    form of a reverse domain name. -->
    <groupId>com.kfwebstandard</groupId>
 
    <!-- This is the name given to the packaged build -->
    <artifactId>KFWebStandardProject</artifactId>

 Maven manages the thousands of libraries available by using the combination of the groupId and artifactId as a unique identifier for each library. This is commonly called the GAV. These are usually expressed using the naming convention for Java packages or as a reverse domain name but they can be anything. You’ll see a non-package name for the MySQL dependency. When a library is a dependency for a project it is identified by this combination. This is also the directory in your local repository where this jar or other file type is stored.


    <!-- The version of the build. Any value is valid though a number and a
    string are common. SNAPSHOT means a project under development. FINAL is commonly
    used to refer to stable production version -->
    <version> 0.0.1-SNAPSHOT</version>

   The version number for a project is an important piece of data that you should be updating during development. Over time there may may be many versions of a project and other developers may depend on a specific version. The most recent version may contain changes that could break the work of other developers who have a dependency on your work. Two special optional terms are SNAPSHOT for a project in development and FINAL for a production ready project.


    <!-- Default value is jar but may be war or ear -->
    <packaging>war</packaging>

 Select the appropriate archive packaging type, either jar, war or ear.


    <!-- The name given to the project. Unlike groupId and artifactId a name
    may have spaces -->
    <name>${project.artifactId}</name>

I like to use the artifactId for the project name but you can use any name you want. Notice that you can refer to a tag in the file using substitution notation and by appending it to the term ‘project’.


    <!-- A description of the program -->
    <description>Standard starting point for a JEE Web Profile application using Java Server Faces
        for students of Ken Fogel</description>

    <!-- Identifies the programmer or programmers who worked on the project -->
    <developers>
        <developer>
            <id>Enter your school id</id>
            <name>Enter your name</name>
            <email>Enter your email address</email>
        </developer>
    </developers>

    <!-- The company or organization that the programmer(s) work for -->
    <organization>
        <name>Enter school name</name>
    </organization>

 The three sections above are used to identify you. They are optional if you are an amateur. If you are a professional they are mandatory. 


    <!-- Global settings for the project. Settings can be accessed in the pom
    by placing the tag name in ${...} ex. ${endorsed.dir} -->
    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

 Properties represent data that another section of the pom may need access to. This way this data can be stored in one place and not repeated where it is needed. Endorsed represents a directory where files with the same name and type as those present in the Java installation are stored. This way the file in the endorsed folder will be used rather than the one supplied in the Java installation. The encoding of the project appears here as does the version of Java you will be using.


    <!-- Dependencies listed here are usually bom or bill of materials-->
    <!-- The bom lists all the child dependencies that could be used and -->
    <!-- lists the current version number for each -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.arquillian</groupId>
                <artifactId>arquillian-bom</artifactId>
                <version>1.1.12.Final</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>

            <dependency>
                <groupId>org.jboss.shrinkwrap.resolver</groupId>
                <artifactId>shrinkwrap-resolver-bom</artifactId>
                <version>2.2.6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

 When using Arquillian there are numerous libraries that may be required. Exactly what they are may change from version to version. A dependencyManagement section refers to special files classifid as bill of materials that in turn will include the necessary Arquillian libraries. 


    <!-- Dependencies are libraries that either must be included in the -->
    <!-- jar/war file or are expected to be found in the container such as -->
    <!-- GlassFish -->

 As my comment above says, the dependencies are libraries that must be available to your project. They will all be downloaded to your local repository. This will allow your IDE to ensure you are using classes and methods from these libraries correctly. They are further classified by the scope tag. If there is no scope tag then the file associated with the dependency will be added to your final archive file. If the scope tag shows ‘provided’ then the required files are in the container you will be running in, such as Glassfish/Payara, and do not need to be added to your archive. If the scope is ‘test’ then the files are only added to an archive used for testing such as what Arquillian produces.


    <dependencies>
        <!-- These dependencies are required to run the project on the server -->
        <!-- Java EE 7.0 Web profile dependency -->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- MySQL dependency -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
            <scope>provided</scope>
        </dependency>

        <!-- PrimeFaces dependency -->
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>6.0</version>
        </dependency>

        <!-- EclipseLink dependency for the static metamodel generator -->
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
            <version>2.6.4</version>
            <scope>provided</scope>
        </dependency>

 The metamodel generator dependency invokes a process to create meta model classes dynamically. This will allow you to use identifiers rather than strings in certain types of JPA queries so that refactoring (renaming) is supported.

Thanks to BillyTheKid for pointing out that the dependency for eclipselink, now removed, is not needed, only the metamodel dependency is required.


        <!-- These dependencies are required for testing only -->
        <!-- Arquillian dependency for running tests on a remote GlassFish server -->
        <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-glassfish-remote-3.1</artifactId>
            <version>1.0.0.Final</version>
            <scope>test</scope>
        </dependency>

        <!-- Resolves dependencies from the pom.xml when explicitly referred to
        in the Arquillian deploy method -->
        <dependency>
            <groupId>org.jboss.shrinkwrap.resolver</groupId>
            <artifactId>shrinkwrap-resolver-depchain</artifactId>
            <type>pom</type>
            <scope>test</scope>
        </dependency>

 Not every required Arquillian dependency that my students need is in one of the two bom dependencyManagement entries so we need to add these two dependencies. If you are using Arquillian then you need these too.


        <!-- Connects Arquillian to JUnit -->
        <dependency>
            <groupId>org.jboss.arquillian.junit</groupId>
            <artifactId>arquillian-junit-container</artifactId>
            <scope>test</scope>
        </dependency>
 
        <!-- JUnit dependency -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- Selenium dependencies -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>htmlunit-driver</artifactId>
            <version>2.25</version>
            <scope>test</scope>
        </dependency>

        <!-- You will need a driver dependency for every browser you use in
        testing. You can find the meven dependencies at
        https://mvnrepository.com/artifact/org.seleniumhq.selenium -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-chrome-driver</artifactId>
            <version>3.2.0</version>
            <scope>test</scope>
        </dependency>

        <!-- Normally you must download an exe for each browser. This library
        will retrieve the the necessary file and place it in the classpath for
        selenium to use -->
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>1.6.0</version>
            <scope>test</scope>
        </dependency>

 For the first time I will be having my students use Selenium as part of their testing. Selenium is actually an independent system that can even be placed in a Java desktop application. Here it will be run as a unit test. Selenium requires, in addition to the Java library, a standalone executable program to connect it to a specific browser. I found this extremely convenient library, webdrivermanager, that will download all the required executables and run them as required.


        <!-- A better way to write assertions -->
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>1.7.1</version>
            <scope>test</scope>
        </dependency>

        <!-- Selenium uses SLF4J and log4j so these dependencies are needed
        but just for test scope -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.23</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.8</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.8</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

 Selenium uses slf4j as the interface to log4j. That is why these dependencies are all listed as test scope. A student recently ran into a problem when a library they were using in their project also needed slf4j. The solution was to remove scope so that the libraries were added to both the production and test archive files. 


    </!-- Information for compiling, testing and packaging are define here -->
    <build>
        <testResources>
            <!-- Folders in the project required during testing -->
            <testResource>
                <directory>src/test/resources</directory>
            </testResource>
            <testResource>
                <directory>src/test/resources-glassfish-remote</directory>
            </testResource>
        </testResources>

 Here in the build section of the pom.xml. Here you can identify filesor folders folders that are required but are not part of a standard Maven project. 


        <!-- Plugins are components that Maven uses for specific purposes beyond
        the basic tasks -->
        <plugins>
            <!-- Presence of this plugin suppress a warning about the existence 
            of the web.xml file -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
            </plugin>

Plugins are modules that add features to Maven. The Maven war plugin is used when we wish to modify how the war file is built. It is not required for the projects my students build. Unfortunately, leaving this plugin out results in a warning that reads “Warning: selected war files include a WEB-INF/web.xml which will be ignored”. This statement is false and the project’s web.xml is properly processed. Adding this plugin without any settings eliminates the warning message. 


            <plugin>
                <!-- Executes JUnit tests and writes the results as an xml and
                txt file Test classes must include one of the following in their
                name: Test* *Test *TestCase -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <argLine>-Dfile.encoding=${project.build.sourceEncoding}</argLine>
                    <skipTests>false</skipTests>
                </configuration>
            </plugin>
        </pluginn>
    </build>
</project>

The Surefire pligin controls running tests and it allows me to easily turn on or off testing with the skipTests tag.

Final Word

In preparing this article I removed two plugins that proved to be redundant and removed unnecessary tags from a third. These plugins were there because the articles that I read in researching Maven showed them. These Maven entries continue to appear on StackOverflow and in other articles. May I suggest that when writing about Maven or answering a question you consider testing your code by removing plugins. Otherwise we will propagate inflated Maven pom.xml files.

Here is the full pom.xml.

<?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/xsd/maven-4.0.0.xsd">
    <!-- pom.xml February 2017 version 1.0 -->

    <!-- Maven version of the xml document currently only 4.0.0 is valid -->
    <modelVersion>4.0.0</modelVersion>

    <!-- The GAV consists of an arbitrary descriptor that is usually in the
    form of a reverse domain name. -->
    <groupId>com.kfwebstandard</groupId>

    <!-- This is the name given to the packaged build -->
    <artifactId>KFWebStandardProject</artifactId>

    <!-- The version of the build. Any value is valid though a number and a
    string are common. SNAPSHOT means a project under development. FINAL is commonly
    used to refer to stable production version -->
    <version>0.1</version>

    <!-- Default value is jar but may be war or ear -->
    <packaging>war</packaging>

    <!-- The name given to the project. Unlike groupId and artifactId a name
    may have spaces -->
    <name>${project.artifactId}</name>

    <!-- A description of the program -->
    <description>Standard starting point for a JEE Web Profile application using Java Server Faces
        for students of Ken Fogel</description>

    <!-- Identifies the programmer or programmers who worked on the project -->
    <developers>
        <developer>
            <id>Enter your school id</id>
            <name>Enter your name</name>
            <email>Enter your email address</email>
        </developer>
    </developers>

    <!-- The company or organization that the programmer(s) work for -->
    <organization>
        <name>Enter school name</name>
    </organization>

    <!-- Global settings for the project. Settings can be accessed in the pom
    by placing the tag name in ${...} ex. ${endorsed.dir} -->
    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <!-- Dependencies listed here are usually bom or bill of materials-->
    <!-- The bom lists all the child dependencies that could be used and -->
    <!-- lists the current version number for each -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.arquillian</groupId>
                <artifactId>arquillian-bom</artifactId>
                <version>1.1.12.Final</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>

            <dependency>
                <groupId>org.jboss.shrinkwrap.resolver</groupId>
                <artifactId>shrinkwrap-resolver-bom</artifactId>
                <version>2.2.6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- Dependencies are libraries that either must be included in the -->
    <!-- jar/war file or are expected to be found in the container such as -->
    <!-- GlassFish -->
    <dependencies>
        <!-- These dependencies are required to run the project on the server -->

        <!-- Java EE 7.0 Web profile dependency -->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- MySQL dependency -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
            <scope>provided</scope>
        </dependency>

        <!-- PrimeFaces dependency -->
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>6.0</version>
        </dependency>

        <!-- EclipseLink dependency for the static metamodel generator -->
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
            <version>2.6.4</version>
            <scope>provided</scope>
        </dependency>

        <!-- These dependencies are required for testing only -->

        <!-- Arquillian dependency for running tests on a remote GlassFish server -->
        <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-glassfish-remote-3.1</artifactId>
            <version>1.0.0.Final</version>
            <scope>test</scope>
        </dependency>

        <!-- Resolves dependencies from the pom.xml when explicitly referred to
        in the Arquillian deploy method -->
        <dependency>
            <groupId>org.jboss.shrinkwrap.resolver</groupId>
            <artifactId>shrinkwrap-resolver-depchain</artifactId>
            <type>pom</type>
            <scope>test</scope>
        </dependency>

        <!-- Connects Arquillian to JUnit -->
        <dependency>
            <groupId>org.jboss.arquillian.junit</groupId>
            <artifactId>arquillian-junit-container</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- JUnit dependency -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- Selenium dependencies -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>htmlunit-driver</artifactId>
            <version>2.25</version>
            <scope>test</scope>
        </dependency>

        <!-- You will need a driver dependency for every browser you use in
        testing. You can find the meven dependencies at
        https://mvnrepository.com/artifact/org.seleniumhq.selenium -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-chrome-driver</artifactId>
            <version>3.2.0</version>
            <scope>test</scope>
        </dependency>

        <!-- Normally you must download an exe for each browser. This library
        will retrieve the the necessary file and place it in the classpath for
        selenium to use -->
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>1.6.0</version>
            <scope>test</scope>
        </dependency>

        <!-- A better way to write assertions -->
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>1.7.1</version>
            <scope>test</scope>
        </dependency>

        <!-- Selenium uses SLF4J and log4j so these dependencies are needed
        but just for test scope -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.23</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.8</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.8</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <!-- Information for compiling, testing and packaging are define here -->
    <build>
        <!-- Folders in the project required during testing -->
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
            </testResource>
            <testResource>
                <directory>src/test/resources-glassfish-remote</directory>
            </testResource>
        </testResources>

        <!-- Plugins are components that Maven uses for specific purposes beyond
        the basic tasks -->
        <plugins>
            <!-- Presence of this plugin suppress a warning about the existence
            of the web.xml file -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
            </plugin>

            <plugin>
                <!-- Executes JUnit tests and writes the results as an xml and
                txt file Test classes must include one of the following in their
                name: Test* *Test *TestCase -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <argLine>-Dfile.encoding=${project.build.sourceEncoding}</argLine>
                    <skipTests>false</skipTests>
                </configuration>
            </plugin>

        </plugins>
    </build>
</project>

 

 

Email this to someoneShare on Google+1Share on Facebook77Tweet about this on Twitter0Share on LinkedIn4

IoT without the Breadboard Part 3

      No Comments on IoT without the Breadboard Part 3

Payara Micro and GrovePi+ Mashup

https://gitlab.com/omniprof/PayaraMicroGrovePiMashup

In this project I have combined two other projects. These are Steve Millidge’s, of Payara, proof of concept Java EE application that highlighted the use of the Payara Micro server on the Raspberry Pi. You can see the original article at http://blog.payara.fish/piyara-payara-micro-on-raspberry-pi-demo. The other project is Eduardo Moranchel’s IoTDevices project that presents how to work with the GrovePi with Java. You can find it at https://github.com/emoranchel/IoTDevices.

The Payara project presents a simulated stock ticker where the numbers are presented on a line graph. The IoTDevices project presents code to communicate with GrovePi modules using either the JavaME dio library or the Pi4J library. The mashup I created simply replaced the random number generator in the Payara project with readings of the DHT-11 temperature sensor using the IoTDevices code.

The changes in the two projects that I made were quite minor. For the IoTDevices I stripped away the JavaME dio code and removed the samples. For the Payara code all I changed was a few lines to read the sensor. For both projects I did upgrade their pom.xml files to how I expect my students to write these files.

Hardware

Here is the hardware you will need to run this project:

2x Raspberry Pi version 2 or 3. Version 1 might work but I did not test it.

1x GrovePi+. This is a Raspberry Pi shield or daughter board that interfaces with the Grove modules

1x Grove Temp&Humi Sensor

1x Grove – LCD RGB Backlight v2.0

I recommend purchasing the GrovePi+ Starter Kit for Raspberry Pi that includes a number of modules including the two for this project but not a Raspberry Pi.

Raspberry Pi Software

Here is the software you will need for the Raspberry Pi.

Raspbian OS for the Pi (https://www.raspberrypi.org/downloads/raspbian/)

You only need the standard distribution, currently called Jessie, that already comes with Java 1.8. All other required libraries will be packaged in the application.

Payara Micro (http://www.payara.fish/payara_micro)

This is a single jar that you will need on each Raspberry Pi. You can download it directly on the Pi or download it to your dev system and copy it to the two Pi systems. Take note of its full name as you will need this in your WinSCP script. For simplicity I placed this jar in my home folder on both Pi systems.

Windows Development System Software

Here is the software you will need for your development system. I use Windows but the project will work from any Linux distro or Mac OSX system.

Java 1.8

The IoTDevices project uses Java 1.8 features such as lambdas.

NetBeans 8.1

While you could use pretty much any IDE I feel strongly that NetBeans is the best choice.

WinSCP (https://winscp.net/eng/index.php)

This is a windows application that allows you to connect to, upload to and execute on a remote Linux system. I experimented with some other options but I found WinSCP to be the best. It will run a script that Linux or Mac users should be able to turn into a shell script for their systems.

Raspberry Pi Setup

On one of the Pi systems attach the GrovePi+ shield. To the GrovePi+ attach the Temp&Humi Sensor and the LCD RGB Backlight module. The second Pi does not use a shield.

For my code I am using the default user and password for the Pi systems. You will need to know the IP number of each Pi. I use Ethernet rather than wireless but that should not make any difference. I assume that you have started up and verified the operation of each Pi. Either download on the Pi or copy to it the Payara Micro jar file.

Windows Dev System Setup

Verify that you have Java 1.8, download and install WinSCP, and download and install NetBeans. Run NetBeans and use its integrated Git support to clone this project. You will be confronted with many errors but you can ignore them as they will be resolved as you build each project.

Making it work

Clone the project from https://gitlab.com/omniprof/PayaraMicroGrovePiMashup. The four individual projects that appear in NetBeans when you clone my project are:

  • GrovePi-pi4j
  • GrovePi-spec
  • TemperatureTicker
  • TemperatureWeb

Before you build anything you need to edit the two WinSCP scripts. In NetBeans switch to File view and you find them in each project’s root.

TemperatureTicker is from Steve Millidge and is an EJB timer. I modified it to read from the GrovePi+ rather than generate a random number and display this value on the LCD display. The value is also sent our over a web socket. Its WinSCP script is called tickertopi.txt and contains:

open "scp://pi:raspberry@192.168.0.92" -hostkey="*"
put target\TemperatureTicker.jar
call java -jar payara-micro-4.1.1.162.jar --deploy TemperatureTicker.jar
close
exit

Change the IP number to that of the Pi with the GrovePi+ shield. Change the user name and password if necessary. Change the version number of the payara-micro jar file to match whatever you downloaded.

The TemperatureWeb, also from Steve Millidge, is a web socket client that receives data from the TemperatureTicker application and then feeds this to a JavaScript graphing application. Read Steve’s article and watch his video to understand how it all works. Its WinSCP script is called webtopi.txt and contains:

open "scp://pi:raspberry@192.168.0.85" -hostkey="*"
put target\TemperatureWeb.war
call java -jar payara-micro-4.1.1.162.jar --deploy TemperatureWeb.war
close
exit

Change the IP number to that of the Pi without the GrovePi+ shield. Change the user name and password if necessary. Change the version number of the payara-micro jar file to match whatever you downloaded.

IMPORTANT: This is not a secure project. It should not be using the default Raspberry Pi user and communication should be using SSL. This is a proof of concept only.

Building

All projects are Maven based so all you need is a working Internet connection on your development PC. You do not use the Run command. The first project that you will Clean and Build is GrovePi-spec. next, Clean and Build GrovePi-pi4j. They must be built in this order as GrovePi-pi4j depends on GrovePi-spec.

At this point both Raspberry Pi systems should be up and running. Now you can Clean and Build TemperatureTicker and TemperatureWeb. The order is not important as long as they are built after the GrovePi projects. The TemperatureTicker jar file will be large because it is packaged with all necessary libraries. This is why you don’t require a customized version of the Raspbian OS.

Seeing the results

Assuming that the build did not generate any errors and the WinSCP scripts ran without errors you will need to open a browser on your PC.

http://192.168.0.85:8080/TemperatureWeb

Change the IP number to match the Pi without the GrovePi+ shield. If all goes well it will look like:

I held the sensor and breathed on it to change the readings. Otherwise it was going to be 22 C constantly.

Graph

Stopping the Payara Server

You will need a remote terminal for each Raspberry Pi to kill each instance of the server. I have not learned how to do this from within NetBeans.

There you have it, the Payara/GrovePi+ mashup.

Email this to someoneShare on Google+1Share on Facebook3Tweet about this on Twitter0Share on LinkedIn2