Mango Java Developer IDE Setup and Usage

June 22nd, 2020


Overview

Mango’s use of runtime loading modules can be confusing for Eclipse developers until they understand how classes are loaded by Mango.

Note: These instructions are specifically for OSX but will be similar on Windows.

Runtime changes can be made while Mango is running to most classes (including module code) as Eclipse will hot-swap the changes into the running JVM.

Download Eclipse

Download and install the eclipse package for Java Developers here:

Eclipse Installer

Download Java JDK Latest

Get the latest JDK from Adopt https://adoptopenjdk.net:

Add Git Repositories

Git configuration

Please add this to your global gitconfig

[branch]
    autosetuprebase = always

Git repositories

First show the git repositories view. Window → Show View…

Eclipse Git

Then copy and paste these git repo URLs into the view window to connect to the repository. You may not have access/or need all these repos so only import what you need.

When importing the repositories place them on your file system in this structure, this is necessary for the build process to work properly.

  • git/infiniteautomation
    • /ma-core-public
    • /ma-core-private
    • /ma-modules-public
    • /ma-modules-private
    • /ma-modules-proprietary
    • /ma-dashboards-public
    • /dashboards-public

Configure Eclipse

Setup Memory settings

Open the Eclipse app by right click and ‘show package contents’ edit the eclipse.ini file and add/replace the memory settings with this:

-Xms256m
-Xmx8024m

Install Javascript Development Tools

Help → Install new software...

Install Javascript Dev Tools

Install JSHint

https://github.eclipsesource.com/jshint-eclipse/updates/

Setup Code Style/Format

Java Code Style

If you are using another IDE, we are using the Google Java style guide with indentation of 4 spaces. There are various setting files for other IDEs here.

  • Preferences → Java → Code Style → Formatter
  • Click Import...
  • Import the code style from here as an XML file.
  • Setup auto formatting

Auto formatting

Javascript Code Style

If you are using another IDE, we are using the AirBNB ES6 style guide with indentation of 4 spaces.

  • Preferences → JavaScript → Code Style → Formatter
  • Click Import...
  • Import the code style from here as an XML file.
  • Install JSHint from here
  • Preferences → JSHint→ Configuration
  • Use this JSHint configuration from here

Installed JREs

Preferences → Java → Installed JREs

Make sure the JDK is selected in this menu. At this point you can install other JDKs to choose from while testing and developing.

Setup Maven Inside Eclipse

  1. Create a settings.xml file (see example below)
  2. Go to Preferences → Maven → User Settings
  3. Point the User Settings: to new settings file, this will activate the set-ma-home profile that will set MA_HOME for the builds.
  4. Click the ‘Update Settings’ button to pick up the changes.

Eclipse Maven setup

Example User Settings file:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
    <profiles>
      <profile>
        <id>set-ma-home</id>
        <properties>
        <MA_HOME>Path to your /git/infiniteautomation/ma-core-public/Core folder</MA_HOME>
        </properties>
      </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>set-ma-home</activeProfile>
    </activeProfiles>
</settings>

Import Core Projects

Import all the projects from the ma-core-public repository. Note that references to private repository projects should be resolved automatically when Eclipse downloads the dependencies from the remote Maven repositories.

  1. Select: Window → Show View → Other... → Git Repositories
  2. Select: Clone a Git Repository from URI
  3. Check: Import all projects when clone finishes
  4. Refer to Appendix A to ensure you have the Push configured properly

Tip: keep your repositories organized by creating your local repository in the following folder structure. /{some path}/git/infiniteautomation/ma-core-public

The default branch is main and is where the latest Mango core development happens. After all the projects are imported Eclipse will do its first build and download all the required Maven dependencies automatically. When this finishes you are ready for the next step.

Note 1: Check the Markers tab to see if any Build problems occured. If so you may need to Right Click on some of the projects and Maven → Update Project… for any projects with problems.

Eclipse Markers

Note 2: If the CoreBundle project has Java Build Path Problems, you may need to perform a Maven Install on the Core project. In that case right click on the Core/pom.xml file and Run As → Maven Install. Then Maven → Update Project on the CoreBundle project

Run as Maven Install

Copy Overrides

Make a copy of the env.properties file (from classes/env.properties) into the overrides/properties folder so you can make edits for your local instance. Also copy the debug-log4j2.xml file into the overrides/classes folder. This way you can modify them to suit your needs and they are automatically ignored by git.

Debug Mango Core

Add the Java Nature to the CoreBundle Project

Since there is no source code in the CoreBundle project Eclipse will not detect that it can be run. To help Eclipse you need to add the Java Nature. Right click on the CoreBundle project and choose properties.

Add Maven Nature

From the CoreBundle project, select Run → Debug Configurations and create a new Java Application Debug Configuration as shown:

Debug Configurations

Configure the VM Arguments on the Arguments Tab as follows:

-server
-Xmx8G
-Xms8G
-Dma.home=/path/to/git/infiniteautomation/ma-core-public/Core
-Dlog4j.configurationFile=file:/path/to/git/infiniteautomation/ma-core-public/Core/overrides/classes/debug-log4j2.xml

Configure the Classpath as follows by adding these folders from the Core project. On the Dependencies tab, select the Classpath Entries row and click the Advanced button. Then select Add Folders and add these 3 folders from the Core project

/Core/overrides/classes
/Core/overrides/properties
/Core/classes

Eclipse classpath entries

To start Mango click the ‘Debug’ button.

Note: The log4j configuration file is referenced from the overrides folder that you copied into before

Note 2: If you don’t see a com.serotonin.m2m2.Main class, you may need to do a Maven install of the core project, then right click on the CoreBundle in the package explorer and Maven → Update Project. You may need to run the Maven install again afterwards.

Install the Virtual Data Source

  1. Clone the ma-modules-public repository by adding a new repository to Eclipse using this URL
  2. Check Import existing projects into workspace
  3. It is always a good idea to keep your repositories organized i.e. in a folder structure similar to infiniteautomation/ma-modules-public
  4. Refer to Appendix A to ensure you have the Push configured properly

There is a maven profile to use when building modules install-module. The install-module profile will build a zip of the module and install into the MA_HOME directory defined in your settings.xml file, install-module should only be done when Mango is not running.

Right click on the Virtual Data Source’s pom.xml file and select Maven Build… Configure the settings as shown below and click Run to build the module.

Eclipse Virtual Data Source Configuration

When you start Mango should see a log output that has Installing module virtualDS

Remote Debugging the Mango Core

Mango can be remotely debugging by Eclipse if started with the correct parameters. Start Mango with these VM arguments:

-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n

The suspend option of y will wait for the debugger to connect before starting Mango. Otherwise Mango will start and you can connect the debugger at any time.

To connect to a Mango started in debugging mode Add a Remote Application run configuration as follows:

Core bundle debug configuration

REST API test development

The REST api should have tests written for all endpoints using the node-mango-client written in node.js. The project can be found here When checking out the code place it into the folder structure at the same level as your core and module repos.

Tests should be placed into the api-test folder in the root of the module. The tests will look for a file named config.json in the root of the module running the tests. The contents are as follows:

{
    "protocol": "https",
    "host": "localhost",
    "port": "8443",
    "rejectUnauthorized": false,
    "corsTestAllowedOrigin":"http://localhost:8080"
}

You need to install mocha to run the tests if you are adding tests for the first time. To do that run: yarn install

Tests can be executed against a running Mango in a few ways.

  1. To execute all tests: yarn mocha **/api-test/*.spec.js
  2. To execute matching suite(s) or test(s): yarn mocha **/api-test/*.spec.js --grep="pattern to match”
  3. To execute all tests for all modules, from the node-mango-client directory execute: NODE_PATH=node_modules yarn run mocha ../*/*/api-test/*.spec.js

Debugging

To debug a NodeJS test add --inspect-brk to the command and open Chrome developer tools. In the toolbar open the NodeJS icon to show the debugger. To easily find the location in the code where you want to start debugging it helps to put the command debugger; into the source before running the test.

debugger

Node Mango client development

When writing tests it may be necessary to update the client code. After checking out the client project and modifying the source you can install it locally by executing the following in the node-mango-client root (or mango-module-tools) directory:

yarn link

And then adding this to any module while developing by executing the following in the root of the module’s directory:

yarn link “@infinite-automation/mango-client”
yarn link “@infinite-automation/mango-module-tools”

Web development

HTML5 UI

The HTML5 UI is enabled by installing the MangoUI module. This code is located in this repository ma-dashboards. Checkout this code and install the module using a similar procedure to the Virtual Data source described above.

General Information

Most Mango modules contain a web-src folder which contains JavaScript and HTML files which are bundled into the web folder using webpack during the module compilation process.

When working on the web project you probably want to run Webpack using development mode so you can debug your JavaScript files in your web browser. To do this you can add a parameter to the Maven build dialog in Eclipse (shown above). Click “Add” and add a parameter named webpack.mode with value development.

You can set this via the command line by adding -Dwebpack.mode=development after your mvn install command.

Automatic recompilation of web-src files

Another helpful thing to use while working on the web projects is automatic recompilation (Webpack) of web-src files. You can do this by running yarn run webpack --mode development --watch from the project root. Whenever you change a file in web-src, the bundled JavaScript files in web will be updated.

To make your life even easier so you can just hit F5 and refresh for changes, create a symbolic link from your running Mango’s $MA_HOME/web/modules/$MODULE_NAME/web folder to your development directory. e.g. on Linux run ln -s $DEV_ROOT/ma-dashboards/UI/web $MA_HOME/web/modules/mangoUI/web Equivalent commands exist on OSX (ln command with slightly different syntax) and Windows (mklink command). Note that if you reinstall the module using Maven or from a zip file, you will need to recreate your symbolic link after Mango unpacks the zip file.

Note: Mango 3.7 has a development mode that automates the process of creating the symbolic link for your web directory. See section below.

Appendix A - Eclipse General Settings

Setup Java Code Templates

Add default templates for comments on all new files and types.

Setup Comments for new Files

/**
 * Copyright (C) ${currentDate:date('yyyy')}  Infinite Automation Software. All rights reserved.
 */

Setup the File template with a comment for every file with the Copyright information as shown:

Eclipse file templates

Be sure to check the ‘Automatically add comments for new methods and types’ checkbox.

Setup Comments for New Types

Eclipse setup comments for new types

Remove Non-Javadoc for Overrides

Be sure to remove the comments for the overrides, the default is a non-javadoc comment.

Eclipse remove non-javadoc for overrides

Properly Configure Maven Push

Choose: Switch to the desired branch main and be sure to configure the branch for rebasing of commits rather than merging in the Configure upstream for push and pull. This can also be done at any point by right clicking on the project and selecting Team… → Push to branch ‘...’.

Eclipse push branch main

Debug Tools

MAT - Memory Analyzer Tool

Very useful to explore heap dumps and identify Memory usage/leaks. Check here

This tool integrates nicely into eclipse using the update site

Development Mode Mango 3.7+

Mango can be placed into development mode to simplify development.
At startup mango will load the class files from your development environment instead of the jar files for the modules and create links between the module’s web folder in your development tree and the MA_HOME/web/modules/<your-module>/web folder. You can then run the webpack build to pick up changes in your development web folder, e.g. yarn run webpack --mode development --watch.

You must first install a module once before it will work. By default all modules will be loaded in development mode unless the whitelist/blacklist options are set.

# Overall enable of development mode, may be used to turn on other development features in modules
development.enabled=true
# Development home directory, i.e. the directory where all your git repositories are checked out
development.home=C:\\Users\\Jared\\mango-main
# Directories in which to look for modules, resolved relative to development.home. You can also use absolute paths. (comma separated)
development.moduleDirectories=ma-dashboards,ma-modules-private,ma-modules-proprietary,ma-modules-public
# Skip the persisting of paths inside the module web directory (defined in module.properties as persistPaths) (DOES NOT APPLY TO Mango versions >=3.8.x)
development.skipPersist=true
# Creates a symbolic link from ${MA_HOME}/web/modules/${moduleName}/web to module dev directory web
development.linkWeb=true
# Creates a symbolic link from ${MA_HOME}/web/modules/${moduleName}/resources to module dev directory resources
development.linkResources=true
# Adds the development classes directory to the module's classpath (i.e. use the i18n.properties files from the development directory)
development.linkClasses=true
# Loads the module's Java classes from the maven-target/classes directory instead of the installed jar file
development.loadMavenClasses=true
# List of module names to whitelist i.e. only link these modules (comma separated)
#development.whitelistModules=
# List of module names to blacklist i.e. do not link these modules (comma separated)
#development.blacklistModules=

IntelliJ IDEA setup

  • Create root directory to checkout git repositories into
  • Checkout ma-core-public, ma-modules-public etc
  • Import ma-core-public, ma-modules-public, etc, pom.xml files into your IDEA project as modules

Note: I have a dummy root pom.xml that includes all the git repositories as modules and I imported that into IDEA, you will need to remove the private repos you do not have access to

The project structure looks like this

Project structure

  • Import the ma-core-public/CoreBundle project into IDEA (right click on pom.xml, Import As Maven Project)
  • Add the Core/classes, Core/overrides/classes, and Core/overrides/properties directories to the mango-bundle project dependencies
    • Choose classes and change the scope to runtime

Classes IntelliJ

  • Create run configuration as follows (working directory is important)

Run config

Script to build Mango

#!/bin/bash
RED="\033[1;31m"
GREEN="\033[1;32m"
NOCOLOR="\033[0m"
MA_DEV_DIR="/<YOUR_PATH>/git.nosync/infiniteautomation"
MA_HOME="/<YOUR_PATH>/mango-nightly-build.nosync"
# Build mango
function build-mango() {
    find "$MA_DEV_DIR" -name "ma-*" -mindepth 1 -maxdepth 1 -type d -print -exec git -C {} checkout main \;
    echo -e "${GREEN}CHECKED OUT ALL MAIN BRANCHES${NOCOLOR}"
    find "$MA_DEV_DIR" -name "ma-*" -mindepth 1 -maxdepth 1 -type d -print -exec git -C {} pull \;
    echo -e "${GREEN}PULLED ALL REPOS${NOCOLOR}"
    cd "$MA_DEV_DIR"/ma-core-public
    echo -e "${GREEN}READY TO BUILD MANGO ...${NOCOLOR}"
    mvn install --settings=/Users/ppuccinir/.m2/settings.xml -Pma-modules-public,ma-modules-private,ma-modules-proprietary,ma-dashboards,core-zip -DskipTests=true
    cp "$MA_DEV_DIR"/ma-core-public/CoreBundle/maven-target/m2m2-core-4.0.0-SNAPSHOT.zip "$MA_HOME" 
    echo -e "${GREEN}COPIED ZIP TO MANGO HOME${NOCOLOR}"
    echo -e "${GREEN}READY TO INITIALIZE MANGO ...${NOCOLOR}"
    "$MA_HOME"/bin/start-mango.sh
    cd "$MA_HOME"/bin
}
# Start mango
function start-mango() {
    cd "$MA_HOME"/bin
    ./start-mango.sh
}
# Stop mango
function stop-mango() {
    cd "$MA_HOME"/bin
    ./stop-mango.sh
}

Then, run:

source /<SCRIPT_PATH>/.custom_bash_commands.sh

source /<YOUR_PATH>/.zshrc

Copyright © 2020 Radix IoT, LLC.