How to Run Maven Based Projects on a Remote Raspberry Pi Using NetBeans Part 2 of 2.

In the first part of this series I presented a solution for developing on a Windows PC a Maven managed Java applications with NetBeans and then deploying it to a Raspberry Pi. In this part I will look at at a solution that allows you to accomplish these tasks from within NetBeans. It will work with any version of Windows and Linux.

Solution #2 Running an external command from Maven

For this solution you will need an additional program on your Windows PC. You need a program that will allow you to interact with a Raspberry Pi or any Linux system from the command line in Windows. This is necessary because we will write a script that will carry out the required tasks.

For this solution I have chosen WinSCP as my tool for connecting to the Pi, uploading a file or files and then executing the file. It is not the only solution but its ability to run a script when executed makes it an ideal choice. You can find WinSCP at https://winscp.net/eng/index.php . Here is a direct link to the download: https://winscp.net/download/winscp577setup.exe . Once installed you should add its location to the System PATH so that it can be run easily from the command line.

Test it with a script. Here is a script from for my MavenWinToPi project from the previous article. Save the script as wintopi.txt in the root folder of the MavenWinToPi project.

open scp://pi:raspberry@192.168.0.92 -hostkey="*"
put target\MavenWinToPi-1.0-SNAPSHOT.jar
call java -cp java -cp MavenWinToPi-1.0-SNAPSHOT.jar com.kenfogel.mavenwintopi.MavenWinToPi
close
exit

This script will:

  1. Open a session between the PC and the Pi accepting any ssh key from the pi
  2. Copy the jar file from the PC to your home directory on the Pi. You can place it any folder by adding a path at the end of the put command.
  3. Execute command line java to run the jar file you copied. If you are using a directory other than home, then you will have to include the full directory path to the jar file.
  4. Close the session
  5. Exit WinSCP

There are two programs named WinSCP that are installed. One is WinSCP.exe that produces a GUI display similar to Filezilla. You could use WinSCP in place of Filezilla in solution #1. The other is WinSCP.com that is the command line version and is the one we want to use.

The script assumes that it is running in the root of the project so remember to save the script to this folder. The pom.xml file is also in the project root. Open a console, improperly called the Command Prompt by Microsoft, in the root folder of the project and test the script by entering at the command line:

WinSCP.com /script="wintopi.txt"

If it fails because WinSCP.com cannot be found, then use its location in the command such as it is on my system.

"C:\Program Files (x86)\WinSCP\WinSCP.com" /script="wintopi.txt"

winscp_script_x

If you can see “Hello Universe.” You know it has worked. Don’t panic over the WARNING! message. It is a result of using a wildcard for the -hotkey switch. Once you decide to go production you should carefully examine security. Now its time to make Maven execute WinSCP.com and the script.

Get Maven to do the work

To have Maven execute WinSCP and its script we need to add to the pom.xml file.  Here is the original pom.xml as generated by NetBeans.

<?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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.kenfogel</groupId>
    <artifactId>MavenWinToPi</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <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>
</project>

We need to add a build section and in this section we need to add an exec plugin. Here is the new 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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.kenfogel</groupId>
    <artifactId>MavenWinToPi</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.5.0</version>
                <executions>
                    <execution>
                        <phase>install</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <executable>WinSCP.com</executable>
                    <arguments>
                        <argument>/script="wintopi.txt"</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The Maven exec plugin is usually used to indicate which class contains the main method and or to add switches or arguments to the execution of a Java program. In my example I am using the plugin’s additional capability to run any type of executable. In this case the executable is WinSCP.com and the argument points to the script. To carry this out the command must be associated with a specific phase. In this case it is the ‘install’ phase when the fully assembled jar file is stored in the local maven repository.

Only use Build or Clean and Build

In NetBeans the install phase occurs at the end of a Java build. This means that if you do a Build or a Clean and Build the executable will run. Unfortunately, if you use the Run command in NetBeans it executes WinSCP.com but immediately declares a bad host error. Therefore, only do a Build or Clean and Build when using this technique for working with a Raspberry Pi

When you do the build you will see the output of the WinSCP program as well as the output of the program from the Raspberry Pi. It is almost indistinguishable from NetBeans’s native capability to run code remotely. Here is what should appear in the Output window of NetBeans:

Installing D:\NB_jgrove\MavenWinToPi\target\MavenWinToPi-1.0-SNAPSHOT.jar to E:\dev\.m2\com\kenfogel\MavenWinToPi\1.0-SNAPSHOT\MavenWinToPi-1.0-SNAPSHOT.jar

Installing D:\NB_jgrove\MavenWinToPi\pom.xml to E:\dev\.m2\com\kenfogel\MavenWinToPi\1.0-SNAPSHOT\MavenWinToPi-1.0-SNAPSHOT.pom

--- exec-maven-plugin:1.5.0:exec (default) @ MavenWinToPi ---
Searching for host...
Connecting to host...
Authenticating...
WARNING! Giving up security and accepting any host key as configured!
Using username "pi".
Authenticating with pre-entered password.
Authenticated.
Starting the session...
Session started.
Active session: [1] pi@192.168.0.92
target\MavenWinToPi-1.0-SNAPSHOT.jar |           2 KB |    0.0 KB/s | binary | 100%
Hello Universe.
Session 'pi@192.168.0.92' closed.
No session.
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 3.833s
Finished at: Sun Jul 17 19:56:59 EDT 2016
Final Memory: 14M/243M
------------------------------------------------------------------------

You know that all is well because you can see the ‘Hello Universe.’ Message.

Exception

The technique described her in part 2 will only work for applications that only have console output. If you must interact with the program in the console or if the program has a GUI then you will have to use solution #1.

In the remaining articles in my IoT without the Breadboard series I will be using this technique. If you know a better way to accomplish this, then let me know about it and I will update this information.

Acknowledgement

I’d like to thank fellow NetBeans Dream Team member Johannes Weigend for pointing out that the maven exec plugin could be a solution.

 

Email this to someoneShare on Google+0Share on Facebook0Tweet about this on Twitter0Share on LinkedIn0

How to Run Maven Based Projects on a Remote Raspberry Pi Using NetBeans Part 1 of 2.

In the course of writing a series of articles entitled ‘IoT without the Breadboard’ I came across an issue that I felt could be fun to resolve. The issue is how to copy to and execute on a Raspberry Pi a compiled Java application. As a NetBeans Dream team member my IDE of choice is NetBeans.

If you are already a NetBeans user playing with Pi systems, you already know it can be done if you create a native NetBeans project. My issue derives from the fact that I use Maven rather than NetBeans or any other IDE’s internal build system.

NetBeans has the capability to use an internal ssh client to copy a file to a remote Linux based system, such as a Pi, execute the code, and display its output in the NetBeans console window. This really cool standard feature is not available if the project is using the Maven build system.

So why don’t I just ditch Maven? As a teacher I believe that it is important for students to learn how to build projects independent from the IDE. When I teach Java I want my students to submit code that is IDE agnostic. My Raspberry Pi project is personal but I felt that it would be hypocritical of me if I chose not to use Maven when I rant and whine at programmers who don’t use it.

There are two solutions to getting code from a Windows PC to a Linux PC. The solutions should work with any Linux based system and any version of Windows.

Here is the first solution. The next solution will be in the second part of this series.

Solution #1 Multiple Tools

My real interest in coding but I realized I was going to have to be a DevOp to make this work. There are three tasks to accomplish. First I have to write and compile my Java code and for this I use, of course, NetBeans. Secondly, I need to copy the jar, war or ear file to my Raspberry Pi. For this I chose Filezilla, https://filezilla-project.org/ .

The third task is to execute the Java program from the command line. Here I was excited to find a program called xrdp, http://www.xrdp.org/, that runs on the Pi and allows me to use Microsoft Remote Desktop to access the Raspbian OS desktop on my Windows machine. To install xrdp you need to open a terminal window on your Pi that I assume you have currently connected to a keyboard, mouse and display. Here is a good article on installing xrdp, https://www.maketecheasier.com/enabling-remote-desktop-access-on-raspberry-pi/ . From this point forward you should rarely need to connect a keyboard, mouse and display to your Pi, use Remote Desktop instead.

With NetBeans I created a new Maven Java Application.

NBNewProject

When the project is created by NetBeans this is what the pom.xml file should look like. If you are using an older version of Java or NetBeans it may be slightly different.

Maven_pom

In the project I created a single class that simply writes to the console “Hello Universe.” when run.

HelloCode

Running the project now will output the message “Hello Universe”.

HelloUniverse

Now you need to transfer the jar file to the Raspberry Pi. Start up Filezilla. If you are unfamiliar with Filezilla then you can use other programs such as PuTTY or WinSCP. There are probably many others that will allow you perform a secure copy from Windows to a Linux system.

Using Filezilla, locate the folder ‘target’ in the MavenWinToPi project. In this folder you should find a jar file. If there is no jar file, go back to NetBeans and perform a Clean and Build on the project.

Now connect to your Raspberry Pi. Here is the Filezilla display after locating the target folder and then configuring the connection. You will need to know the IP number of the Pi. I use my router’s control panel to see what internal (192.168.x.x) number it has been given.

filezilla

Take note of the file name of the jar file, in my case its ‘MavenWinToPi-1.0-SNAPSHOT.jar’. Click on connect and you should see your home directory on the Pi.

If this is the first time that you are using this program, you will be asked to accept the unknown ssh key from the Pi. If the IP number of your Pi changes, you will also be asked to verify the key again.

hostkey

Check off the ‘Always trust . . .’ box otherwise you will have to approve the host key every time you connect. Assuming that all has gone well you should see your Pi on the right side of the Filezilla window.

filezillaconnect

 

Now you need to transfer the jar file. Right mouse click on the file and select upload.

upload

Your jar file should be transferred to the Pi.

upload_success

 

Now its time to execute the code. On Windows run the Remote Desktop Connection and configure it to connect to your Pi. You can let windows hold the user name and password or have it ask you for them for every connection. I let Remote Desktop hold my credentials.

rdp

By default Remote Desktop will open full screen when it connects. I set the Display option to 1024 x 768 so that the Pi is running in a window I can move around. If all has gone well you should see:

xrdp_desktop

Open a terminal window on the Pi. You should now be able to execute your program at the command line by entering:

java -cp MavenWinToPi-1.0-SNAPSHOT.jar com.kenfogel.mavenwintopi.MavenWinToPi

execution

You should see Hello Universe.

This workflow for Java development for a Raspberry Pi works well and you don’t need to read any further. It is your only option if the program is interactive in the console or has a Swing or JavaFX GUI. If you are interested in automating this further so that everything happens in NetBeans, read the second article in this series.

 

 

 

Email this to someoneShare on Google+0Share on Facebook0Tweet about this on Twitter0Share on LinkedIn0