Thursday, 15 October 2015

Gradle Introduction

I don't think Gradle gets enough love - checkout this short introduction to Gradle, from our Java Build Tools course. The next chapter goes on to create a full Gradle build, and you can see this by subscribing at

Thursday, 8 October 2015

Introducing OAuth

Our new module, which is a 4 hour training video showing how to build an OAuth2 Provider AND Client, is probably the hardest course I've recorded so far. I hope I've made a difficult topic approachable, without losing any of the essential detail.

Check out a preview video below, subscribe to see the whole thing at

Tuesday, 18 August 2015

One of the challenges of our new Membership package is that to deliver value to our members, we have to release new training packages regularly. Preferably at least once a month!

We've always been slow at VirtualPairProgrammers - we have always been determined to deliver only top quality material that we've taken time and care to write, record, re-record, edit, record again, edit again, post produce and then in many cases, re-write, re-record, re-edit and....well, you get the idea.

But we can still do all of this. From now on, we're going to be releasing our courses, to members only, in shorter "modules" - chunks of something like 3-5 hours.

The first release is a 6 hour course on Spring Security - it covers the core concepts, with some fun stuff like BCrypt along the way. And we've lots more to come in the next month, with HTML5, DevOps courses and OAuth.

Friday, 14 August 2015

I forgot to announce my new NoSQL course on my blog. This was very slack of me, but in my defence, we were very busy at the time launching our new membership scheme.

What this means is that you can now sign up to the website, and for a small monthly fee, get access to our entire library of Java training - 170 hours and counting.

So you can start on NoSQL right away. This course is designed to help anyone who wants to get a start in NoSQL but doesn't really know....well, where to start!

I talk about why NoSQL is so popular, what it's good for (and not), and then three parts of the course go through three of the big hitters in the NoSQL world - MongoDb, Redis and Neo4j. They're all very different, so you get a real tour of the NoSQL world.

If you've ever been curious about NoSQL, then this is the course for you.

Monday, 30 March 2015

Autodeploying to Glassfish

Our JavaEE video training course has always featured a chapter on how to Autodeploy your code to Glassfish. It's a simple process but it can be a little troublesome, so we spend around 15 minutes showing how it is done.

However, for reason (gremlins in the machine of course), the chapter has been missing from the course outline for sometime, so I think many of customers will not be aware that this is part of the course! So I've uploaded it to YouTube so that you can all catch up on this.

Sorry for the omission!

Friday, 6 March 2015

How to attach a Debugger to a running Tomcat or Glassfish instance

This is a frequently asked question from many of our customers at Virtual Pair Programmers, so I thought a blog post to capture the details would be in order. I'll focus on Tomcat and Glassfish here, because we use them on our courses - but the details are the same for other servers.
  • (for Glassfish) 1) Run the server under debug. The easiest way is to run as normal, then go to the admin console. Go to configurations -> server-config (not default config) -> JVM Settings. Click Debug Enabled. These options will be different on different glassfish versions (I'm on 4), but you should be able to find them. Check the port that the debugger will run on - it will be part of the debug options and usually the default is 9009

    (for Tomcat) 1) Add a JVM option called "agentlib" to your startup script. On our courses, we use a bootstrap script called startup.bat, and you can edit it to look like this:
    cd ./tomcat/bin/
    java -Dsun.lang.ClassLoader.allowArraySyntax=true -agentlib:jdwp=transport=dt_socket,address=9009,server=y,suspend=n -jar bootstrap.jar
    (note: we use a simple bat file for bootstrapping Tomcat on our courses to simplify support: if you're not using this script, then you need to put the JVM options in a new file bin/setenv.bat. Full details can be found here: )

  • 2) Restart the server (in Glassfish, a link may appear at the top of the page you can click. Otherwise, run the stopserv script and then startserv)

  • 3) Remember to add breakpoints in your code where required *AND re-deploy*. I sometimes forget to do this and wonder why I don't hit any breakpoints.

  • 4) Now you can attach Eclipse to the debugger: a) Debug icon -> Debug Configurations b) Click "Remote Java Application" c) click the tiny icon at the top left - it is for "new session" d) Enter the correct port number you noted earlier (we suggested 9009) e) click the debug button.

  • 5) I find this odd: you won't see anything special at this stage, you have attached to the running server *in the background*. There won't be a console window and you won't switch to debug perspective.

  • 6) You now need to hit a breakpoint, so to do this, exercise your code. This may be visiting one of your webpages, or running a test harness.

  • 7) When your client code causes a break to trigger on the server code, your run should be interrupted with a request to switch to the debug perspective, and you can now step through the code as usual.
I hope that's useful!

Friday, 13 February 2015

Writing a Custom HTTP Message Converter in Spring

The Spring Webservices course got so big that we had to cut a few minor topics, and I promised on the video that I would write some blog posts covering them. Here's the first of them, how to write a "Custom Message Converter".

You probably don't need to do this very often - I've never had to do this "in real life". But it is a useful exercise to get a better understanding of what those message converters are doing.

Recall that in Spring, a MessageConverter is a class that is capable of converting a regular Java domain object to a REST representation (and back again). Spring has a small set of default converters already built in, but the two main ones are for JSON (most common representation used in REST) and XML.

For this exercise, let's assume that for some reason, our REST application needs to support YAML as well. YAML is Yet Another Markup Language (literally) that aims to be simpler than XML. It's used a lot in Rails.

As a starting point, I've fired up the REST project that we built on the training course. I've also started up the standard Spring REST shell:

baseUri mywebapp
get /customers

< 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 12 Feb 2015 17:56:33 GMT
  "customers" : [ {
    "customerId" : "100029",
    "companyName" : "Acme",
    "email" : null,
    "telephone" : null,
    "notes" : "No Notes",
    "calls" : null,
    "version" : 1,
    "links" : [ {
      "rel" : "self",
      "href" : "http://localhost:8080/mywebapp/customers/customer/100029?fullDet

As on the course, if the client wants XML instead, they can change the accept headers:

headers set --name accept --value application/xml

And now we repeat the get request....

get /customers
> accept: application/xml

< 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/xml
< Transfer-Encoding: chunked
< Date: Thu, 12 Feb 2015 18:04:06 GMT
><customerId>100029</customerId> ... lots of XML snipped

But there is no YAML message converter installed by default in Spring....

headers set --name accept --value application/yaml
get customers

> accept: application/yaml


So let's write a YAML Message Converter!

Step 1: Add the JAR file for YAML

One Java YAML parser is called SnakeYAML ( You can download the JAR from there, but if you have done our course, I actually supplied this JAR in the "Additional JARs" folder. So pull it from there and add it to your build path.

This library is very easy to use. If you want to try it out, you can easily convert an object into YAML (and back again) in a test harness.

public class TestYaml 
 public static void main(String[] args)
  Customer c = new Customer("10012", "Acme","Notes");
  Yaml yaml = new Yaml();

This gives an output like this:

calls: []
companyName: Acme
customerId: '10012'
email: null
notes: Notes
telephone: null
version: 0

Step 2: Write the converter

This is the bulk of the work. To write a message converter, extend the Spring AbstractHttpMessageConverter, and override the three methods as below.

  • readInternal() describes how Spring should convert the data (YAML) into a Java object.
  • writeInternal() is the opposite - it generates a YAML String from a Java object (this will be done in a similar way to our test above).
  • The supports() method is used to determine whether the converter actually supports conversion to and from the type of object in question. You might decide that you're not going to support collections for example. We'll simply return true and support any object.

In the constructor, we call the superclass constructor, which requires a MediaType object to denote what the HTTP media type is. We're supporting application/yaml.

The implementations of the read and write methods are fairly routine, we're just using the SnakeYaml library. It takes a bit of fiddling with the API of the HttpInputMessage and HttpOutputMessage classes to get what you need. In the read method, the getBody() method returns a standard Java InputStream, which luckily SnakeYaml can accept. In the write() method, we have to convert the YAML String into a byte array so we can send it to the write() method of the HttpOuputMessage. It's all a bit fiddly but straightforward in the end.

public class YamlMessageConverter<T> extends AbstractHttpMessageConverter<T>
 public YamlMessageConverter()
        super(new MediaType("application","yaml"));
 protected T readInternal(Class<? extends T> arg0, HttpInputMessage arg1)
   throws IOException, HttpMessageNotReadableException 
   Yaml yaml = new Yaml(new Constructor(arg0));
   T object = (T)yaml.load(arg1.getBody());
   return object;

 protected boolean supports(Class<?> arg0) {
  return true;
 protected void writeInternal(T arg0, HttpOutputMessage arg1)
   throws IOException, HttpMessageNotWritableException 
  Yaml yaml = new Yaml();
  String result = yaml.dump(arg0);  

Step 3: Register the converter

The magic that makes the default message converters automatically happen is the tag in your Spring configuration.

We can add our new YAML Converter into the this tag:

<!-- This will automatically switch on the default httpmessageconverters -->
 <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
  <mvc:message-converters register-defaults="true">
   <bean class="com.virtualpairprogrammers.messageconverters.YamlMessageConverter"/>

Note: the "register-defaults=true" is needed - without it, the default converters will not be registered and you will end up with only the YAML one.

And that's it. We can now deploy the application and test:

headers set --name accept --value application/yaml
get customer/100029

< 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/yaml
< Transfer-Encoding: chunked
< Date: Fri, 13 Feb 2015 12:55:47 GMT
calls: []
companyName: Acme
customerId: '100030'
email: null
notes: No Notes
telephone: null
version: 1

Our representation is now in YAML.

I hope this exercise may prove useful to someone - to be honest I'm not really interested in YAML, the main point of the exercise is to get an understanding of what those mysterious HttpMessageConverters are doing!

Minor bug in our Webservices course

I've discovered a minor fault in our Webservices course. We supply a JSON file containing a data graph - and there's a missing curly bracket! This is important because without it, any attempt to record a call via the REST Shell will fail with a JSON properties exception.

The file should look like this:

 {"notes":"Customer called to complain about late delivery.",

 "actions":[{"details":"Return call.",
            {"details":"Check handled ok",

The missing curly bracket is added to the end of the line with the timeAndDate.

Many apologies for the error, I hope it hasn't caused too many problems.