Java 8 Streams Intro

One of the cool new features in upcoming Java 8 release is the update to the the Collections API with the new Streams API.

Say if I have a Project class with an isCompleted method. If want a list of all completed projects. Now I want to retrieve a list of projects that have been completed.

Using Java 6 I could do this….

List<Project> completedProjects=new ArrayList<Project>();
for (Project project : allProjects) {
    if (project.isCompleted()) {
        completedProjects.add(project);
    }
}

The above is correct and would work, few criticism of this way, many people (especially with functional language background) would argue its very verbose for what it’s doing, the problem that I’m trying to solve is just to get the released projects – ( do I need to specify it needs to be done in a loop?).

So a few issues with the above

  1. Have to do the filtering using a loop, is something I shouldn’t have to decide, instead I should delegate it to library to decide the best implementation
  2. The looping used above is sequential, so doesn’t take advantage of multi-cores in todays machines
  3. Being pedantic, I had to mention the the type “Project” 3 times in this simple code (ok, with Java 7 Diamonds you could reduce it to 2).

The Java 8 Way of doing this would be..

List<Project> completedProjects = allProjects.stream()
    .filter(project -> project.isCompleted())
    .collect(Collectors.toList());

Now the stream library is free to decide if it’s going to use sequential loop or use some clever algorithm to best use the CPU on the machine. i also like the fact, I only have to mention the type “Project” once in all of this.

What confused me at first, is why the .collect is required the end. The way I think about this, is that Stream API could be applying the filter in parallel, so you need a collector at the end to pickup all of those results from the filters and place them into the result list.

The neat thing about the streams, is that you add other stuff onto the pipeline, say, I want to get the sorted list of completed projects…

List<Project> completedProjects = allProjects.stream()
    .filter(project -> project.isCompleted())
    .sorted()
    .collect(Collectors.toList());

SecureRandom is very slow when large number of files in java.io.tmpdir

Working on application that took a long to startup. Upon investigation, it turns out the issue is SecureRandom is using “java.io.tmp” directory to set up some entropy (the temp directory on this machine had thousands of files – no wonder it was slow!!).

Work round for Java 6 was to clear files from the temp directory.

http://bugs.sun.com/view_bug.do?bug_id=6705872

According to the bug report, this issue is fixed in Java 7 and will at most use 1024 files.

Creating videos in Java

I was looking into various options in dynamically creating a video in Java and came across xuggler, it’s really cool and it works works nicely in a maven project. The recent updates to the library means you don’t have to install the binaries before you run your Java program.

I had to use this repository below to pull down the artifact as it wasn’t hosted on Maven Central.

<repository>
    <id>xuggleRepository</id>
    <name>Xuggle Repository</name>
    <url>http://xuggle.googlecode.com/svn/trunk/repo/share/java</url>
</repository>

Reporting Unit Test and Integration Test Coverage In Sonar

If you are familiar with sonar, then the standard setup of the sonar plugin in your maven project will report Unit test coverage using Cobertura.

Sonar can also report Integration Test coverage using Jacoco

http://www.sonarsource.org/measure-coverage-by-integration-tests-with-sonar-updated/

However to report Integration test coverage on Multi-module maven projects, you may need you to tweak your build

Lets take this example

Projects:
Parent
Project A (jar)
Project B (jar)
Project C (Webapp utilising A and B)

Now if you do

mvn clean install sonar:sonar

on the parent project

What happens is the following

clean, install sonar:sonar will get run on project A
clean, install sonar:sonar will get run on project B
clean, install sonar:sonar will get run on project C

This setup may work if you want to report Unit Test coverage, but if you want to report Integration test coverage (where your integration tests get run against the final assembled war built in project C). The above is running sonar analysis too early for project A and B – as its project C that is will run integration test and produce the IT dump file for sonar to analyse.

You will need redo you your build to a multi-step one,

Multi-Step Build

Step 1 , You run mvn clean on the parent project, to delete everying in the target folder (including any Jacoco dump from previous runs )

Step 2 you run mvn install on the parent project, to run your unit tests and integration tests and produce the single Integration Test Jacoco dump file.

Step 3 from the parent, you run mvn sonar:sonar

Why run multi-step, well, it’s so that when you run sonar:sonar in Step 3, when its comes to analysis project A, B, C, sonar can refer to the single jacoco IT dump file which was produced in Step 2.

Details about Step 2

In Step 2, when you run you Integration tests, its good idea to separate Unit Test and Integration Test. maven-sure-fire plugin to run your Unit Test and maven-fail-safe plugn to run your IT tests.

Maven-fail-safe plugin extends the sure-fire-plugin.

The difference between the two plugins
The default convention for Surefire is that Tests follow the pattern **/Test*.java,**/*Test.java or **/*TestCase.java
Main goal is “test”

The default convention for Failsafe is that Tests follow pattern **/IT*.java, **/IT*.java or **/*ITCase.java
Main goal is “integration-test”

Right thats the difference between the two plugins sorted. We can use surefire to run our Unit Tests. and failsafe plugin (or launch external Java process e.g. Tomcat) to run our Integration Test

Now how to we get the failSafe plugin (or other Java process) to generate the IT Jacaco file in step 2 of our build?

If you are using fail-safe-plugin to run your Integration Test.
You’ll need to set the “argLine” config of the plugin to something like this

-javaagent:C:\tools\jacoco-agent.jar=destfile=C:\build\myparentprojectpath\target\itjacoco.exec,append=true,includes=com.mypackage.*

If for example you intend to run your integration tests as part of Tomcat, you can set the above argLine as your “CATALINA_OPTS” environment variable.

Note
One thing to bear in mind, the IT jacoco file is intially 0 bytes when but when the failsafe plugin or your java program ends, you should see the jacoco file being populated.

Super, now when your run your Integration Test in Step 2, you will have an produced an single itjacoco.exec file ready for Step 3 of your build

More about Step 3

Because we’ve already run our unit and integration test in phase 2, we want to avoid sonar having to re-run unit tests and integration test if possible, so we set this property in our maven build

-Dsonar.dynamicAnalysis=reuseReports

When sonar tries to work out the integration test coverage for project a, b, and c it needs to know where the global IT jacoco file is. So we need to pass another property to maven for this.

-Dsonar.jacoco.itReportPath=C:\build\myparentprojectpath\target\itjacoco.exec

Now sonar can report integertion test coverage in your mutli-module project.

Nexus 7 Tablet, First impressions.

Got my Nexus 7 tablet. Was impossible to slide it out from the box sleeve, I had the cut the sleeve to get to the box.

What was inside box, however I was most pleased with, it a fantastic tablet, a bargain for the price. I watched Transformers 3 on it and it looked great on the 1280 by 800 screen, the tablet also gave me 15 pound google play store credit. Google play store had various computer books selling for a penny so I used my Google credit to buy some of these books. The 7 inch tablet is the perfect size for reading books on the Tube and by lucky coincidence the tablet slips snuggly into my inside jacket pocket.

Getting Java HTTP Requests to appear in Fiddler

Fiddler is a handy tool to inspect http request/responses. When Fiddler starts-up by default it sets itself up to act as the proxy so any libraries that uses WinInet will have their http calls proxyied through Fiddler. For Java programs however you will need to instruct it to use Fiddler as a proxy if you want to see the calls in Fidder.

The properties you need to launch your Java application with, are:

-Dhttp.proxyHost=localhost -Dhttp.proxyPort=8888

Where 8888 is the default port that fiddler sets itself up, you can check this in Fiddler through Tools -> Fiddler Options

Refer to this StackOverflow post for more details

Few things to note :

  1. the above properties will work if you are using the standard Java libraries for making http requests. If you are using any other libraries for this (e.g. Commons HttpClient), then you’ll have to check if they have a different way of setting the proxy configurations.
  2. Secondly, requests for localhost for someone reason I can’t get them to go via the proxy (I guess the standard Java libraries has special rule for localhost). The work-round I had to employ is to use localhost. (note the dot after localhost this isn’t a typo )

If your using RestTemplate in conjunction with CommonsClientHttpRequestFactory (which uses Apache HttpClient underneath) then you need to set the HostConfiguration with proxy configuration. This blog I came across to describe the spring updates to do this

Google Nexus 7 Tablet

Really looking forward to receiving my pre-order for Google Nexus 7 tablet, at 7 inch with 1280 * 800 resolution, quad core NVidia Tegra 3 Cpu with 12 Core GPU and at 340g, along with the updated 4.1 Jelly Bean OS, Early techrader preview sounds positive, I think google are onto a winner. Shame that it doesn’t come with a micro-sd slot and the shipping is 2-3 weeks 🙁

Waffle

A very useful open source project I stumbled up on is waffle a Windows active directory authenication framework for C#/Java.