JMRI Code: Building with NetBeans
- Introduction
- Getting and Installing NetBeans
- Checking out code
- Updating the code from Git
- Building and running JMRI
- Making a Jar File
- Making a release package for Windows using NSIS
- Using NetBeans XML tools
- Running SpotBugs
- NetBeans and compiling individual files
- Loading a Specific Branch from GitHub
- Making a Patch File
Introduction
NetBeans 8 (available at www.netbeans.org) makes a great platform for working with JMRI. The JMRI code is set up to work with NetBeans with almost no additional setup. (The description below is accurate for the Windows version of NetBeans 8. NetBeans is supposed to be identical across platforms, but this hasn't been checked on anything else).
NetBeans is a very powerful Integrated Development Environment (IDE), which can make working with the JMRI code pretty easy. But it takes a little getting used to, and reading the tutorials on the NetBeans web site will be helpful.
Getting and Installing NetBeans
- Download NetBeans 8 or late (The Java SE version is
fine) from www.netbeans.org
(If you don't yet have Java Development Kit 8 (JDK) installed on your system, download a JDK-NetBeans bundle - on the NetBeans download page, look for a link similar to "JDK with NetBeans IDE Java SE bundle".) - Run the NetBeans package installer
Many Linux distributions have NetBeans available in their software repositories - search your package manager for NetBeans.
Important note for Windows users
Due to different handling of Line Endings characters
(LF / CR LF
) between Windows and other systems -
namely Unix and OS X (see Handling Line Ends) - it is of
the utmost importance that all Windows users adopt the
following settings for their development environment. This is
absolutely required so that Git can track individual changes
on files that you commit.
If you don't follow these instructions, you'll mess up the line endings in the files you commit, which will in turn make their revision history much harder to access. Files in this condition will not be accepted as pull requests.
As a first step, as JMRI has adopted LF
as a
convention for Line Endings, it is required to set the
core.autocrlf
setting to true
(see
"Dealing
with line endings" on GitHub Help)
Additional important note for Netbeans Windows users
Moreover, if you are using NetBeans on Windows, you must install the "Change Line Endings on Save" plugin before using Git via NetBeans.
Please install the plug-in to make sure that NetBeans properly maintains the LF characters at the ends of source-code lines.
Actually the plug-in is already available in the NetBeans
distribution, so go to Tools > Plugins >
Available Plugins
and there select Change Line
Endings on Save
and then Install
.
You can check that the plug-in is properly installed by
going to go to Tools > Plugins >
Installed
, where you should see something like this
(versions might differ):
Once the plug-in has been installed and activated, it is
necessary to configure it for the desired line ending
character(s), via the Tools > Options > Editor
> Line Endings
tab.
For JMRI, we want to use the Unix-style line ending
character, LF
.
The plug-in may be enabled via a button in the toolbar.
And the plug-in may be disabled via that button.
When a file is saved (assuming the plug-in is configured and is enabled) and that file has line-endings which do not match the type configured for the plug-in, the following message pops up.
When "OK" is selected, the plug-in updates the line-endings to the configured form and saves the file. If "CANCEL" is selected, the file will be saved WITHOUT changing any line-endings.
Java "Heap" size and "low memory" notifications.
Netbeans may provide notification of "Low Memory" situations when perfroming some operations, including running certain JMRI "targets" within the build.xml file. Netbeans can become very sluggish when it encounters these low memory conditions. This can happen regardless of the amount of memory your machine has, unless you take steps to re-configure Netbeans.
By default, Netbeans uses a strategy to allocate a given amount of "Heap" space which is insufficient for projects which are as large as JMRI. JMRI developers who use Netbeans are encouraged to increase the Netbeans default Heap allocation which is made when Netbeans is launched. This is generally done via a change to the "netbeans.conf" file. See FaqSettingHeapSize for details.
Using NetBeans with JMRI's Git Code Repository
GitHub provides JMRI's code repository using the Git tool. For more information on how JMRI uses Git, see the JMRI Help on Getting the code via Git and Git FAQ.
Once set up, NetBeans provides built-in support for using Git.
For more information on Git and NetBeans, see the NetBeans Git help page
Checking out code
In NetBeans, under the "Team" menu, select Git, then Clone Repository. Enter the https://github.com/JMRI/JMRI.git repository URL from the JMRI GitHub page on the NetBeans form under "Repository URL". We recommend that you also enter your GitHub user name and password on the form, so we can attribute your contributions to you later. Click "Next". Make sure that the "master*" box is checked to pull down the main version of the code. Click "Next", and then click "Finish".It'll take a long time to pull down a copy of the code (note the progress bar in the lower right), but then you're good to go.
Local Commits
When using Git, the "commit" operation is local to your computer. It doesn't make any changes to the main JMRI repository.You're encouraged to commit often, so that your changes are safely stored away from your working directory. Having each small change separately recorded can be incredibly helpful later on if you have to track down where a problem was introduced.
Updating the code from Git
From time to time, you should update your local copy of the code to match the current "HEAD" of the main JMRI Git repository contents. The basic process is to pull the most recent copies from the main JMRI repository, doing any merging that's needed if you've made conflicting changes, and then pushing that up to your own GitHub repository.
To do this, use the NetBeans [Team] -> [Remote] -> [Pull from Upstream] menu choice. Tell NetBeans to pull from the "github" remote you defined above.
You may also update a single file or the contents of a folder, by right-clicking on an item in the "Files" window, then selecting [Git] -> [Remote] -> [Pull from Upstream].
Creating a Pull Request
A "Pull Request" (PR) is an easy way to gather up all your changes, even if they span multiple files, into something that you can then submit for inclusion in the main JMRI repository.
First, you need to set up a GitHub account and your own repository.
- Get a GitHub account and login
- Tell GitHub to "fork" JMRI's repository into one of your own. There's a good help page, but basically you go to the JMRI repository page and click the "fork" button in the upper right.
Next, push the changes up to your repository. (Anybody can push to their own repository, but most people don't have permission to directly modify the main JMRI repository; that's why the pull request is needed) To do this:
- Use the NetBeans [Team] > [Remote] > [Push ...] menu choice. (If you try to use the "Push to Upstream" choice, it will try to write back to the main repository, and will fail.)
- Click on Specify Git Repository, and enter the URL for your own repository, e.g. https://github.com/yourname/JMRI.git
- Then click next.
- NetBeans will check with the repository, and show an indication of branches to push e.g. "master -> master" Check the appropriate box to for the branch you've been working on.
- Click Next and Finish. Netbeans will do the actual push to your repository.
Finally, when your change is ready to submit, go to the GitHub web site to fill out and submit a pull request.
Eventually, somebody will look at the pull request and decide whether to merge it in. Sometimes they'll ask for additional changes. In that case, you can update the pull request by just pushing new changes to the your repository, where they'll automatically be picked up.
Building and running JMRI
To build and run DecoderPro, all you have to do is
select "Run Project (JMRI)" from the Run menu, or click
the Run icon in the tool bar.
A new JMRI checkout should build cleanly. If not, please
check with the JMRIusers or jmri-developers mailings
lists for help.
- [Run] -> [Run Project (JMRI)] will compile and invoke DecoderPro
- You can choose other targets (i.e. PanelPro...) by right-clicking (or control clicking) to get the project contextual menu. This works in various places, but most certainly on the "JMRI" icon under Projects in the left side-bar. In the middle of that menu are items for launching PanelPro, launching DecoderPro and doing other build steps.
- The "Debug" target is a special case. Which program (PanelPro vs DecoderPro) is defined by a line near the end of the nbproject/ide-targets.xml file in the JMRI source directory. Perhaps somebody can some day figure out a better way to configure that...
If you want to run the program under the NetBeans debugger, first set JMRI to be the Main project via [Run]->[Set Main Project]->[JMRI] then select "Debug Main Project" from the "Debug" menu.
Making a Jar File
Most of the code in a normal JMRI installation lives in a file called jmri.jar. If you want to replace this with your updated version, you need to create a new jmri.jar file from your modified code.To do this, ctrl-click (or right-click) on the name of the "JMRI" project in the "Projects" window. This will open a pop-up menu, on which you'll find "Make Jar File". Select that, and a new jmri.jar file will be produced in the project's main directory.
Alternately, from the "Files" window, right-click on the build.xml file, and select "Run Target", then "jar".
Making a release package for Windows using NSIS
It is possible for NetBeans users to create a release package for use on the Windows platform. This requires installation of the Nullsoft Scriptable Install System (NSIS), which can be downloaded from the NSIS project web site on SourceForge.
Once NSIS is installed on the computer, it is necessary to create a file called local.properties in the same directory as JMRI's build.xml file. This file is specifically not checked in via GitHub, so that your machine-specific tool installation paths are not checked in to GitHub. Create the file, and add a variable definition with the correct path to the directory which includes the NSIS executable, such as:
nsis.home=C:/Program Files (x86)/NSIS/
or
nsis.home=/opt/nsis/nsis-2.46/
Note: Make sure the trailing / is present.
If you will be installing the SpotBugs tool, you will also define spotbugs.home in this file. You may also define several other machine-specific and user-specific information as described in various locations in the build.xml file.
With the NSIS package installed to your computer, and build.xml properly modified, the Windows package may be created by running the "package-windows" ant target in build.xml.
Using NetBeans XML tools
NetBeans has nice tools for working with XML files, including editing and validating them. JMRI uses XInclude to include "fragment" XML files in other ones via URLs that point to the main JMRI web site: http://jmri.org/xml/decoders/types/foo.xml JMRI programs convert these at run time to local file references, but by default NetBeans doesn't know to do this.You can tell NetBeans how handle this by adding the xml/catalog.xml file (from the JMRI distribution to NetBeans at Tools -> DTDs and XML Schemas. This will allow NetBeans to use your local schema when validating an XML document in the editor. Note that this is global setting in NetBeans, so if you are working on multiple JMRI branches, whichever branch you add the catalog from, that branch's schema is what is used.
Running SpotBugs
The SpotBugs tool is a static code analysis tool which examines JAVA source code for common coding issues. Installation of a SpotBugs tool allows an ant task defined in build.xml to run SpotBugs analysis across all of the JAVA source code in JMRI.
It appears that the build.xml file is not configured to allow a NetBeans SpotBugs "plugin" to run analysis on the JMRI code except on a one-file-at- a-time basis. As such, it seems advisable to download and install the appropriate stand-alone SpotBugs tool for your operating system. SpotBugs downloads may be found at the SpotBugs web site.
Once you have the SpotBugs tool installed, you must provide a path to the directory containing the executable for use by the build.xml ant file. If necessary, create the local.properties file in the same directory as the JMRI build.xml file. In the local.properties file, add the variable spotbugs.home with a path to the spotbugs executable, such as:
spotbugs.home=C:/spotbugs-3.1.1
or
spotbugs.home=/opt/spotbugs-3.1.1
To run the SpotBugs tool on JMRI code, execute the ant target "spotbugs" which is defined in build.xml. Within NetBeans this can be accomplished by right-clicking build.xml in the "Files" pane and "Run"ing the "spotbugs" target. When SpotBugs completes, the NetBeans Output window will show the path to a report file in HTML format. Open that file with a browser to review the SpotBugs results.
NetBeans and compiling individual files
The NetBeans IDE shows icons to the side of each object in the Projects window, and to the side of each file in the Files window. These icons can reflect the status of each item, including local change and proper compilation status.
At this time, the files (in the project's nbproject/ directory) which control how NetBeans performs individual file compilation, do not properly reflect all of the requirements of the JMRI project. Until these files are properly updated, the error icons will persist within the JMRI project. These error icons do not affect the ability of NetBeans to compile the source files using the Ant tasks defined in the project's build.xml file.
Building the JMRI .jar file, and executing a JMRI tool from within NetBeans is generally done via Ant tasks, which are defined in the project's build.xml file. JMRI's developers have generally kept this file up-to-date, so building the JMRI .jar file, and executing a JMRI tool from within NetBeans generally does not suffer from the shortcomings of the configuration information found in the files in the project's nbproject/ directory.
Loading a Specific Branch from GitHub
The process for building from a branch (i.e. the one where someone has put a change) is a bit different from the standard instructions. (The following is NetBeans 8.2, but it doesn't vary with versions much)- Under "Team" -> "Remote" select "Fetch" (not Fetch from Upstream)
- Fill out the form to specify the correct user's repository
(After the 1st time you do this, you'll be able to select by name in the top choice)
- On the next screen to select a branch, you can either select all of them (there's a button)
or find and select just the name of the branch that holds the desired change:
- Click "Finish"
- Back on the main menu, select "Team" -> "Checkout" -> "Checkout Revision...".
On the window you get, click "Select":
- In the upper left, find the imported branch you want, which in the example is "bobjacobsen/ast-clock-power-bit".
Either click to highlight (show) and then click "Select", or just double click on it.
(Don't worry about the upper right or the lower box, they'll be automatically set right)
- Back on the "Checkout Revision ..." window, make sure the "Checkout as New Branch" is not checked, and then click "Checkout"
Important note: When you want to get back to the standard JMRI version, from the main repository, you need to check out the "master" branch. The process is similar, and simpler. Go to "Team" -> "Checkout" -> "Checkout Revision...", type just "master" (no quotes) in the "Checkout Selected Revision" box, and click "Checkout"
Making a Patch File
Now that we're using Git and GitHub, we ask you to only contribute your code changes as a GitHub Pull Requests intead of using patch files.
If you need a patch file for some other purpose:
- From the [Team] menu, select "Export Diff Patch ..."
- A file browser will open; enter a new file name in your preferred location and hit "Save" or "Open", depending on what the dialog shows.
- After it finishes calculating the diffs, the file you selected will contain the patches, along with an information header.
See Also
- The NetBeans.org Integrated Development Environment web site
- The Apache.org Subversion project web site
- The NSIS project web site
- The SpotBugs web site