March 13, 2017

Java NIO, Files & Paths - Single Statement to Read File as a String

Quick Tip

Here is a quick example (Listing 1) of a single Java statement to read the contents of a file into a single String instance.

NOTE Don’t forget to specify the charset! It’s essential when working with text data.

Listing 1 - Single Statement File to String

String content = new String(
  Files.readAllBytes(
    Paths.get("File_To_Read.txt")
  )
  ,Charset.forName("UTF-8")
);

February 03, 2017

Simple Windows mirror directory backup with robocopy

Quick Tip

This is a simple Visual Basic script (Listing 1) that uses the windows robocoy command to perform a simple mirroring backup of a directory structure. Typically, use this to backup from your local machine to a network location just in case something happens to your hard drive.

NOTE This is a simple MIRROR copy backup strategy. There is no history maintained. If it’s obliterated during the backup, it’s gone!

Listing 1 - Single Statement File to String

Set WshShell = WScript.CreateObject ("WScript.Shell")
Return = WshShell.Run("cmd.exe /C robocopy C:\source X:\destination /MIR", 1)

January 18, 2017

Jacoco, Surefire & Argline: Why jacoco.exe isn't created

Abstract

Are you using Jacoco to give you statistics on the unit test coverage of your source code? Have you encountered a problem where jacoco.exe is not created by jacoco-maven-plugin?. Then keep reading, I’ve got your answer.

Disclaimer

This post is solely informative. Critically think before using any information presented. Learn from it but ultimately make your own decisions at your own risk.

Requirements

I did all of the work for this post using the following major technologies. You may be able to do the same thing with different technologies or versions, but no guarantees.

  • Java 1.8.0_65_x64
  • jacoco-maven-plugin 0.7.5.201505241946
  • maven-surefire-plugin 2.17
  • Maven 3.0.5 (Bundled with NetBeans)

Where are your tests?

Does your project even have unit tests? You sure? Take a look! If your project doesn’t have any unit tests, then jacoco.exe is not created. I’m sure your project already has unit tests, but, it’s always good to check that the lamp is plugged in first :). Now let’s get to a more interesting reason why jacoco.exe is not being created: <argLine>.

Watch out for <argLine>

If you have been using Jacoco and suddenly the jacoco.exe is not created, then chances are you have an <argLine> problem. Jacoco connects itself to the surefire plugin by editing the <argLine> value of that plugin. If you don’t set <argLine> then you’re fine. But if you do, you’ll mess up Jacoco if you don’t do it properly.

Let’s take a look at how NOT to do it. The <properties> tag is typically used to configure plugins and Listing 1 shows you what NOT to do.

Listing 1 - Don’t use <properties> to configure plugins

<properties>
  <!-- Do not configure plugin with properties -->
  <surefire.plugin.argline>-XX:PermSize=256m -XX:MaxPermSize=1048m</surefire.plugin.argline>
</properties>

Instead, configure <argLine> in the plugin itself, and include in the configuration the assumption that Jacoco has already set the <argLine> value. Listing 2 shows how to properly configure Surefire.

Listing 2 - Prepend Jacoco’s argLine value to your value

<build>
  <plugins>
      ...
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
           <argLine>${argLine} -XX:PermSize=256m -XX:MaxPermSize=1048m</argLine>
         </configuration>
      </plugin>
      ...
  </plugins>
</build>

This may look a little funny - <argLine>${argLine} -XX:PermSize=256m -XX:MaxPermSize=1048m</argLine> - but this is really nothing more than string concatenation. The Jacoco plugin automatically sets the value argLine. So if you need to set its value too, you use a standard variable reference to ${argLine} to prepend Jacoco’s value to your value. Finally, Listing 3 shows a very basic jacoco-maven-plugin configuration.

Listing 3 - Very basic Jacoco configuration

<build>
  <plugins>
    ...
    <plugin>
      <groupId>org.jacoco</groupId>
      <artifactId>jacoco-maven-plugin</artifactId>
      <version>0.7.5.201505241946</version>
      <configuration>
        <excludes>
          <exclude>org/company/*</exclude>
        </excludes>
      </configuration>
      <executions>
        <execution>
          <id>default-prepare-agent</id>
          <phase>initialize</phase>
          <goals>
            <goal>prepare-agent</goal>
          </goals>
        </execution>
        <execution>
          <id>default-check</id>
          <phase>verify</phase>
          <goals>
            <goal>check</goal>
          </goals>
          <configuration>
            <rules>
              <rule implementation="org.jacoco.maven.RuleConfiguration">
                <element>BUNDLE</element>
                <limits>
                  <limit implementation="org.jacoco.report.check.Limit">
                    <counter>INSTRUCTION</counter>
                    <value>COVEREDRATIO</value>
                    <minimum>0.0</minimum>
                  </limit>
                  <limit implementation="org.jacoco.report.check.Limit">
                    <counter>BRANCH</counter>
                    <value>COVEREDRATIO</value>
                    <minimum>0.0</minimum>
                  </limit>
                  <limit implementation="org.jacoco.report.check.Limit">
                    <counter>CLASS</counter>
                    <value>MISSEDCOUNT</value>
                    <maximum>1000</maximum>
                  </limit>
                </limits>
              </rule>
            </rules>
          </configuration>
        </execution>
        <execution>
          <id>default-report</id>
          <phase>verify</phase>
          <goals>
            <goal>report</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    ...
  </plugins>
</build>

In listing 3, you can see the prepare-agent goal is configured to be executed at the initialize phase of the Maven life cycle. This goal is what sets the <argLine> value. Then, when the Surefire plugin runs, the jacoco.exe file gets created correctly and the unit test statistics are collected.

Summary

If jacoco.exe is not being created for you, the <argline> value is moste likely your problem. Remove any <properties> that set the argline value and configure <argLine> in the plugin itself. When you do so, remember to include Jacoco’s value by prepending the value like <argLine>${argLine} -XX:PermSize=256m -XX:MaxPermSize=1048m</argLine>.

References

Ryan Nelson. (2016, September 27). jacoco’s prepare-agent not generating jacoco.exec file [Web log comment]. Retrieved from http://stackoverflow.com/questions/21633277/jacocos-prepare-agent-not-generating-jacoco-exec-file.

Hoffmann, Marc R. (2013, October 3). jacoco.exec file is not generated after running jacoco maven ‘prepare-agent’ goal [Web log comment]. Retrieved from https://groups.google.com/forum/#!topic/jacoco/LzmCezW8VKA.

jacoco:prepare-agent. (n.d.). In EclEmma. Retrieved January 12, 2017, from http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html.