Using Error-Prone

Error Prone is static anaylsis tool for Java. It hooks into the compilation process. To use in your maven build you need do some configuration for the maven compiler plugin

An example of error prone being setup for maven compiler plugin

           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.2</version>
                <configuration>
                    <compilerId>javac-with-errorprone</compilerId>
                    <forceJavacCompilerUse>true</forceJavacCompilerUse>
                    <source>8</source>
                    <target>8</target>
                    <compilerArgs>
                        <!-- Promote this check to Error level for bug patters see http://errorprone.info/bugpatterns -->
                        <arg>-Xep:MissingOverride:ERROR</arg>
                    </compilerArgs>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.codehaus.plexus</groupId>
                        <artifactId>plexus-compiler-javac-errorprone</artifactId>
                        <version>2.8.2</version>
                    </dependency>
                    <!-- override plexus-compiler-javac-errorprone's dependency on
                        Error Prone with the latest version -->
                    <dependency>
                        <groupId>com.google.errorprone</groupId>
                        <artifactId>error_prone_core</artifactId>
                        <version>2.0.21</version>
                    </dependency>
                </dependencies>
            </plugin>

In the above we increased the severity error-prone’s MissingOverride bugpattern to Error (error-prone default was WARNING)

This how the output looks like if now in maven’s compilation goal a class that has a missing @Override annotation

Another feature of error-prone is that it has Intellij Integration
You need to install the https://plugins.jetbrains.com/plugin/7349-error-prone-compiler-integration once that’s done you can change the compiler that Intellij uses

Now within Intellij you will get the same compilation errors as you get from maven

For more details about the installation, see the error-prone documentation http://errorprone.info/docs/installation

JavaFX Draggable Tabs

The TabPane in JavaFX unfortunately does not provide mouse dragging / re-ording out of the box which is quite fustrating as users are now accustomed to doing that in their Browsers whey have Tabbed Browsing switched on.

There is a Jira Raised for this feature :

https://bugs.openjdk.java.net/browse/JDK-8092098

There Jira was targeted for Java 9, however Java 9 is now feature complete, so it’s likely Java 10 is the earliest we will see this being available.

Available Solutions

  1. https://github.com/sibvisions/javafx.DndTabPane

    This implementation draws a nice marker line as you drag the tabs around.

  2. http://berry120.blogspot.co.uk/2014/01/draggable-and-detachable-tabs-in-javafx.html
    This seems to be the simplest solution, its relatively easy to understand how it’s working (it works both Java 8 and Java 9-ea b158), in addition to the draggable tabs feature, it’s also detaching (tabs can be dragged out of the window into their own window).

    There is a few things you have to observe if you want to use it, as detailed in his blog.

  3. https://github.com/xylo/DraggableTabs

    There is this project which seems to based on similar solution to above, it’s more polished, has some sample code under tests, it’s also published onto maven central

JavaFX Undecorated Window Task Icon Minimize

The JavaFX undecorated window gives you a blank canvas, giving freedom to how your window looks without having to accept the default Windows title bar and buttons such as the Minimize, Maximise and Close buttons.

On Windows, the disadvantage of the Undecorated stage is if you click on the icon on the Taskbar, you don’t get the minimise behaviour compared to other Windows app. Likewise, if you use the keyboard shortcut “Windows Key + M” all your apps except for the Undecorated JavaFX app will minimise.

This can be quite fustrating.

There is a stackoverflow post on this issue:

http://stackoverflow.com/questions/26972683/javafx-minimizing-undecorated-stage

This answer from StackOverflow post seems to work

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import static com.sun.jna.platform.win32.WinUser.GWL_STYLE;

public class SimpleWindowApplication extends Application {



    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(final Stage stage) {
        Scene scene = new Scene(new Pane(new Label("Hello World")));
        stage.initStyle(StageStyle.UNDECORATED);
        stage.setTitle("Find this window");
        stage.setScene(scene);
        stage.show();
        long lhwnd = com.sun.glass.ui.Window.getWindows().get(0).getNativeWindow();
        Pointer lpVoid = new Pointer(lhwnd);
        WinDef.HWND hwnd = new WinDef.HWND(lpVoid);
        final User32 user32 = User32.INSTANCE;
        int oldStyle = user32.GetWindowLong(hwnd, GWL_STYLE);
        System.out.println(Integer.toBinaryString(oldStyle));
        int newStyle = oldStyle | 0x00020000;//WS_MINIMIZEBOX
        System.out.println(Integer.toBinaryString(newStyle));
        user32.SetWindowLong(hwnd, GWL_STYLE, newStyle);
    }
}

It uses the JNA library add the WS_MINIMIZEBOX style to the existing Window.

Dependencies required if your using gradle are

    compile 'net.java.dev.jna:jna:4.3.0'
    compile 'net.java.dev.jna:jna-platform:4.3.0'


Java 9

Java 9 modularity adds stronger encapsulation, if you attempt to run the sample program under Java 9, you’ll get IllegalAccessError as the com.sun.glass.ui package is not visible to unnamed modules

To make the example run on Java 9 you will need to add this additional VM Option

--add-exports=javafx.graphics/com.sun.glass.ui=ALL-UNNAMED

Enforcing Coding Standards using Checkstyle

Checkstyle is a great tool for enforcing agreed code style across a team.

To make sure everyone in your team is observing the agreed code style. You can get the checkstyle maven plugin to fail the build if a rule is violated

Here is a simple example demonstration a simple project with checkstyle rules applied. Here is an example of checkstyle failing our build, we have setup checkstyle config in this example project to enforce left curly is a line by itself, but as you can see in the example project, the Hello class has violated the rule.

Checkstyle has an an extensive list of checks you can configure and you even write your checks aswell.

checkstyle-build-check-goal

BoneCP

Recently switched to over from using the default connection pool provided by tomcat 7 (which is a re-repackage of DBCP) to BoneCP. Why did we switch? noticed that connection pool wasn’t performing as well as we wanted, under heavy load, the synchronzied blocks that DBCP uses is a performance bottleneck.

Updating tomcat to use BoneCP datasource is answered in this stackoverflow post.

Set the “type” to the BoneCPDataSource (we take advantage of the fact, tomcat supports javax.sql.DataSource out of the box) and the “factory” needs to the Tomcat provideded BeanFactory implemenation.

 <Resource name="jdbc/myReourceName"
         type="jcom.jolbox.bonecp.BoneCPDataSource"
         factory="org.apache.naming.factory.BeanFactory"
         auth="Container"
         <!-- the BoneCPDataSource properties -->
          maxConnectionsPerPartition="10"
          maxConnectionsPerPartition = "2"
         
</Resource>

BoneCP uses lock-free techniques to achieve it’s great performance. One neat thing, BoneCP provides is ConnectionCook you can set on the Pool, to get call-back events when new connection is created or statement is about to be executed / completed, in addition, it provides, a debugHandle on the ConnectionHandle to allow to store your own tracking information, this is for useful for example if we wish store the SPID for connections (to log the spid of the connection that is executing the sql).

// What CustomConnectionHook might look like
public CustomConnectionHook extends AbstractConnectionHook {
  @Override
  public void onAcquire(ConnectionHandle connectionHandle) {
    // get the raw Internal Connection from ConnectionHandle
    // execute query on the raw internal connection to get the SPID
    connectionHandle.setDebugHandle(mySPID);
  }

  @Override
  public void onBeforeStatementExecute(ConnectionHandle connectionHandle, StatementHandle statement, String sql, Map<Object, Object> params) {
    if (logEnabled) {
      // if you are managing multiple db pools, it might be useful to log the poolname
      String poolName = connectionHandle.getPool().getConfig().getPoolName();
      //get out the conn spid from connectionHandle debug variable
      Integer spid = (Integer) connectionHandle.getDebugHandle();
 
      // log "poolname" + "spid" + "sql"  --- Outputting the SPID so that DEVOPS team can track the SPID on the Database monitoring tools
    }
  }
}

Enforcing Minimum Code Coverage

If you want to enforce minimum code coverage check, JaCoCo worked really in the projects that I’ve worked on so far.

JaCoCo works as agent (there is another option where it can do offline instrumentation). The prepare-agent goal sets up the “jacocoProperty” property to setup JaCoCo as agent on the the surefire argLine (so it will only work if sure-fire is configured to run your unit tests in forked process)

Here is basic maven project that demonstrates how to check minimum line and branch coverage of 80% is met.

Prepare Agent Goal

<plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.7.9</version>
       
         <executions>

           <!--  (1)  Prepare agent runs in the init phase, it setups the jacocoProperty,  so we can insert this to the maven sure fire argLine and get to run jacoco as agent -->
          <execution>
            <id>prepare-agent</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
            <configuration>
              <propertyName>jacocoArgLine</propertyName>
              <includes>
                <include>com.choudhury.codecoverage.*</include>
              </includes>
            </configuration>
          </execution>

SureFire Plugin Argline

We run sure fire and we add the “jacocoProperty” as part of the argLine

 <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.19.1</version>
        <configuration>
            <!-- (2)  setup the argLine and run the unit tests.   **NOTE the "jacocArgeLine" property was configured the "prepare-agent" goal of Jacoco  (see below) -->
            <argLine>${jacocoArgLine} -Xmx256m</argLine>
        </configuration>
      </plugin>

After the forked sure fire process is has completed it write the jacoco.exec file in the target file. This file is required for both the “check” and “report” JaCoCo goals.

jacoco_coverage_file

Check Goal
In verify phase, we execute the check goal of JaCoCo

          <!--  (3) the check goal by default runs in the verify phase, we want to fail the build if mimimum code coverage checks aren't met -->
          <execution>
            <id>check</id>
            <goals>
              <goal>check</goal>
            </goals>
            <configuration>
              <rules>
                <!-- All classes must have 80% line and branch coverage . Note we use 2 d.p so that we get can any check failure messages reported to 2 d.p  -->
                <rule >
                  <element>CLASS</element>
                  <limits>
                    <limit >
                      <counter>LINE</counter>
                      <value>COVEREDRATIO</value>
                      <minimum>0.80</minimum>
                    </limit>
                    <limit >
                      <counter>BRANCH</counter>
                      <value>COVEREDRATIO</value>
                      <minimum>0.80</minimum>
                    </limit>
                  </limits>
                  <excludes>
                    <exclude>com.choudhury.codecoverage.Bye</exclude>
                  </excludes>
                </rule>
              </rules>
            </configuration>
          </execution>
        </executions>

Example Project

Example maven project can be found here

With the example project, when we run “mvn clean install” we expect to fail on code coverage checks.

To confirm that Jacoco agent is correctly being appended to the Java argLine for maven SureFire plugin, temporarily put a long enough pause in the Unit Test (and whilst the Unit Test are running) launch jvisualvm to check that jacoco is correctly setup as an agent.

jacoco_run_as_agent

min_check_failed

If we update the HelloTest to test the missed branch and re-run “mvn clean install” we should see the lines “All Coverage checks have been met” to appear and the the build should pass 🙂

min_check_passed

JaCoCo Code Coverage Reports

Another nice feature of JaCoCo maven plugin is the report goal allowing you to see which lines have been covered by your tests.

Execute the report goal of the JaCoCo maven plugin

mvn jacoco:report

(Note : this reads the jacoco.exec file in your target folder, do make sure it’s present when you run this goal, otherwise you will get no reports produced).

The report goal should produce the html files under target/site/jacoco folder.

  • Green shows the covered lines
  • Yellow shows partially covered branches (you can hover over the diamond icon to get tooltip of how many branches covered)
  • Red is the missed lines.