Saturday, September 28, 2013

You Don't Need Frameworks As Often As You Think

Mockito is a wonderful tool. It has helped me on a lot of occasion where I had to deal with code that wasn't under my control, yet had to be mocked and/or tested.

Powermock is also a wonderful tool. It builds upon what Mockito (and EasyMock) provide and enables you, among other things, to mock out static method calls. In a pinch, having these tools in your arsenal can be invaluable.

But like any tool, they can be overused. A lot of frameworks are in fact overused, and used where a simpler solution can be achieved without it. This bears some dangers, especially with these testing frameworks.


An Example

How so? Let's consider an example, where we provide a little helper class to deal with configuration, coming from a .properties file. To have some degree in flexibility, we also want to be able to override certain settings using system properties, given at runtime.

Now, we can do this in two ways, as always: test first, or test after. Let's begin with test after, i.e. write the class as we envision it:

Next up, the test. This hits a barrier pretty early: while checking that loading the property file and returning the values from there is easy enough, you now have to mock a value gained by calling a static method... How to do this? There are at multiple ways:
  • you can set the property with System.setProperty() before the test and remove it after the test. This can easily prove very dangerous: if you forget to reset the property, you're in for some interesting debugging of things that happen after this test was run. Depending on the type of thing you mock in this way, you might even change the running system started after this test! So this is clearly not an option.
  • use a mocking framework. Remember that Powermock has this wonderful "mock out static method calls" feature? 


A Powermock Solution

Okay, let's go with Powermock. First, we have to add a couple of dependencies to the pom:


Now, we are ready to have our test use Powermock. We "only" have to change the JUnit test runner, declare which classes are to be pimped by Powermock, replace the System class with a mock, tell that mock to return our mocked value when asked for the key, and we're done. Oh, and don't forget to have Powermock alter your subject under test (SUT). This one confused me for a while - without mentioning the SUT in the @PrepareForTest annotation, your SUT will actually work with the old System.class. While this might be a good safety guard against effects on following tests, it's somewhat counter-intuitive, at least for me. Well, easily remembered, I guess.

This is what the result looks like:


This tests does the trick. It needs roughly 0.6 seconds on my machine. To be fair, this includes initialization, and following tests using Powermock are likely faster in setup. But, I am a firm believer in Infinitest, which means this test will be run whenever I safe a change that relates to Configuration. If that is the case, I am bound for a minimum 0.6 seconds wait. For a unit test, that is almost unacceptably slow. Plus, it adds up. Slows tests tend to not be executed often.


A POJO Solution

There's actually a third option (there's bound to be more, but let's leave it at three): you can use POJOs and write your own mock. Incidentally, this is the solution you arrive at almost every time if you to the test first approach (also called TDD). Because with this, you write the test first, and realize you need a way to mock out the access to to System.properties. How to do this? Easy enough, just wrap it into a little class and have that passed into the subject under test (SUT):


To my eyes, this looks a lot cleaner. It communicates the intent well, the mock is easy to understand and works by hand-made DI (another thing you don't need a framework for as early and often as you might think). It runs, works and is done in roughly 0.022 s. That's a whopping 25 times faster than the Powermock solution! Plus, there is no magic involved here, it's all just plain POJOs. It took me roughly a minute to write, and requires no knowledge of any framework. Some would say the downside is that there now is one more class, but you shouldn't be scared of classes if you're doing Java. Classes are only bad if they serve no purpose.

I would prefer this implementation over the Powermock/test-after one every day, especially since it also gives me a cleaner solution in the context of the Single Responsibility Principle (SRI). I've made the experience that whenever you write code using TDD, this makes you adhere to the SRI more often, and this in turn leads to cleaner code that is much easier to extend, maintain and refactor. Unfortunately, this is something you have to experience to be able to believe it. But once there, people usually wonder how they could live without these techniques at all.

But the biggest thing is: using Powermock like shown above actually hides a problem in your code. It leads to sloppy (well, sloppier) design by making you think there is no problem in using static method calls and having core classes directly depend on system resources and other things not under your control. You pay the price in terms of speed and magic, and tend to not think further. All the while, a clean and simple POJO solution may be available, giving you the benefits of code that is easy to understand, maintain and change.

Don't let frameworks be the answer to every problem. They certainly have their uses, but keep an eye out for an even simpler solution that can be understood without having to be intimate with at least three frameworks. Strive for fast tests, and write tests before the code. This way, you will soon notice your need for frameworks lessen a lot. At the same time, the mind is freed up to apply design and architectural decisions which put frameworks to work in their rightful place: as a tool for the implementation of the design that you decided on, taking away boilerplate code and problems that arise in a pure POJO implementation. Use frameworks when - and only when - they are useful enough to pay the price for using them. Don't let buzzwords and framework-hype deter you from building a good solution.

Monday, January 21, 2013

Fixing slow typing with DbVisualizer

DbVisualizer was very laggy for me. Every keystroke I made, I could watch appearing on the screen. It was so bad that I tried out a lot of different alternatives. Unfortunately almost none seem capable of displaying table data for a Vertic cluster, so I came back and looked for a fix to this.

Luckily, this thread showed the solution: turn off Direct3D support in Java. Don't ask me why this should be a problem, but it seems to be. Must be something with my drivers.

 I just had to insert some Text into the startup script
dbvis, right down at the bottom: 
$INSTALL4J_JAVA_PREFIX "$app_java_home/bin/java" \
   ... -Dsun.java2d.d3d=false \
   -Dinstall4j.jvmDir="$app_java_home" ...
The above is one line in the script, I just formatted it to be easier readable. The part to insert reads
-Dsun.java2d.d3d=false.  
Just put it anywhere in that line. Restart DbVis and the problem is gone!

Thursday, November 15, 2012

Using Maven on multiple separate poms in one go

Ever found yourself in the need to execute Maven on a set of projects, all in the same dir, but they don't share a parent pom? You can of course run the Maven command once for each file. Or, you can use find:
$ find -maxdepth 2 -name pom.xml  -exec mvn eclipse:eclipse -f {} \;
Using find, you can get as crafty as you want in collecting the poms you need to process, and the exec call (see "man find") runs maven, giving each call the current file as the argument for -f.

Tuesday, August 28, 2012

Measuring CPU usage of Node.js from inside the program

or: Learning the hard way that you have to watch your CPU load yourself sometimes

These days, it feels like we are stretching the limits of what can (or should) be done with Node.js. While running a distributed crawler on EC2, we noticed that the central control server did get into trouble working off the events that it received. At least, that was how it seemed. The problem manifested itself in queries not coming trough to the MySQL instance. After ramping up the load for a while, the Node process was continuously running at 100% CPU and finally got kicked because sequelize was repeatedly disconnected while trying to reconnect to the database.

Googling around suggested that this is usually caused by a flaky network connection. Wich felt strange, because the network was highly saturated, but had bandwidth left. The rest of the communication was doing fine.

We're using socket.io for communication between the modules, and react to inter-module messages with custom event handlers. After a while, we narrowed the problem down to one central function that did some unoptimized computation whenever a page was to be analyzed after being downloaded.

It turns out that when the CPU is blocked by one function running continously, Node's asynchronicity comes to a forced end - no timers are called again before the function exits. Here is an example:


Look at this for a minute. It starts a cpu hogging function and sets a timer to stop that after a second. At least, I was certain that the timer would kick in and end the busyWait procedure. But it doesn't. Because it can't. If you think about it, this makes sense - having only one thread, there is no way for the timer to be fired. I fell into the trap of thinking about Node like Java - where a timer is usually in another thread and able to fire regardless of what other threads are doing. It might get slow, but it will fire eventually. Not so with Node.js, in extreme cases.

So, the lesson is this: Node.js timers make things asynchronous, but CPU intenvise functions can severely interfere with this. Write your functions so that they yield from time to time. If necessary, factor out the work and process it in batches, to give the rest of the program some time to catch up with new events coming in. If you do this, Node once again can run with the amazing speed it usually does.

Apart from applying the necessary optimization to the function in question, we introduced a throttler that would feed new messages into the system only if the current CPU load wasn't too high. If the system is too busy, the message gets queued. I found a great way to measure the current CPU usage on linux on StackOverflow and wrapped it into easy to require in your script:


It works by reading out /proc/[pid]/stat, where linux reports status of process [pid] [link]. The two fields read in the script report user and system cpu cycles spent on the process. I had to experiment a bit to find out how many cycles are run per second - the StackOverflow answer impliess 1000 per second and processor, but for me, 500 worked. If you'd like to verify that it calculates correctly on your machine, you can use this little script to generate some load:


If you look at top while running this, you can easily verify the values and adjust accordingly.

Friday, January 13, 2012

You gotta love git's merge capabilities

One often cited advantage to using git over svn is that merges are better supported. In my experience, that argument is valid. For example, I just merged upstream changes into my repository. One local change I had checked in was a change in the visibility of one class - it had to go from package private to public. My colleague had the exact same change already committed. A miscommunication that would have resulted in a merge conflict, using svn. Git just told me that the patch was already applied and went on:

Applying: class has to be public
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.

Not only did I not have to resolve a conflict, but my now unecessary commit is just optimized away, which helps to keep history clean and understandable.

In addition to this I'm using git svn to interact with the company repo. So, even when svn is the backend, using git as an interface helps to avoid unecessary merge conflicts. I very much appreciate that in my daily work.

Monday, April 18, 2011

Selenium 2, Wicket and Ajax

So we've moved from using Selenium to Selenium 2. All in all, this has been a positive experience up to now. The new API does a very good job in overcoming the problems we had with Selenium 1. It fells quite object-oriented, and I've had my share of learning from the fluidity and the expressiveness, especially with the "lift" Finder API.

But alas, some problems have migrated along with us, as well. Foremost these surface when dealing with Ajax. While the Selenium API has some patterns to deal with that (for example it waits implicitly if a command causes a page to load), these do not work too well for our use of Ajax. It seems geared to web application that don't use too much Ajax. But that doesn't mean it can't help with an Ajax-heavy application. We'll just have to see how.

To find out, we will create a simple Web Application that uses Ajax to update a panel and see how Selenium 2 deals with this situation. We'll do this with wicket because it's pretty easy and quite fun, too.

So, first we instantiate a Maven Project using mvn archetype:generate and using the wicket-quickstart archetype. I selected version 1.4.7, which is not quite up to date, so I pimped it up to 1.4.16 in the pom. While being there, add Dependencies for Selenium and jUnit and correct the one for the maven-jetty-plugin. Throw in a dependency on hamcrest-all for good measure, we're going to use it later. The final pom looks like this for me:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>de.tk.examples</groupId>
 <artifactId>wicket-selenium</artifactId>
 <packaging>war</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>wicket-selenium-example</name>
 <description></description>
 <dependencies>
  <!--  WICKET DEPENDENCIES -->
  <dependency>
   <groupId>org.apache.wicket</groupId>
   <artifactId>wicket</artifactId>
   <version>${wicket.version}</version>
  </dependency>
  <!-- LOGGING DEPENDENCIES - LOG4J -->
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-log4j12</artifactId>
   <version>1.4.2</version>
  </dependency>
  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.14</version>
  </dependency>

  <!--  JUNIT DEPENDENCY FOR TESTING -->
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.8.2</version>
   <scope>test</scope>
  </dependency>

  <!--  JETTY DEPENDENCIES FOR TESTING  -->
  <dependency>
   <groupId>org.mortbay.jetty</groupId>
   <artifactId>jetty</artifactId>
   <version>${jetty.version}</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>org.mortbay.jetty</groupId>
   <artifactId>jetty-util</artifactId>
   <version>${jetty.version}</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>org.mortbay.jetty</groupId>
   <artifactId>jetty-management</artifactId>
   <version>${jetty.version}</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>org.seleniumhq.selenium</groupId>
   <artifactId>selenium</artifactId>
   <version>2.0b3</version>
   <type>pom</type>
   <scope>compile</scope>
  </dependency>
  <dependency>
   <groupId>org.seleniumhq.selenium</groupId>
   <artifactId>selenium-firefox-driver</artifactId>
   <version>2.0b3</version>
   <type>jar</type>
   <scope>compile</scope>
  </dependency>
  <dependency>
   <groupId>org.hamcrest</groupId>
   <artifactId>hamcrest-all</artifactId>
   <version>1.1</version>
   <type>jar</type>
   <scope>compile</scope>
  </dependency>
 </dependencies>
 <build>
  <resources>
   <resource>
    <filtering>false</filtering>
    <directory>src/main/resources</directory>
   </resource>
   <resource>
    <filtering>false</filtering>
    <directory>src/main/java</directory>
    <includes>
     <include>**</include>
    </includes>
    <excludes>
     <exclude>**/*.java</exclude>
    </excludes>
   </resource>
  </resources>
  <testResources>
   <testResource>
    <filtering>false</filtering>
    <directory>src/test/java</directory>
    <includes>
     <include>**</include>
    </includes>
    <excludes>
     <exclude>**/*.java</exclude>
    </excludes>
   </testResource>
  </testResources>
  <plugins>
   <plugin>
    <inherited>true</inherited>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
     <source>1.5</source>
     <target>1.5</target>
     <optimize>true</optimize>
     <debug>true</debug>
    </configuration>
   </plugin>
   <plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>maven-jetty-plugin</artifactId>
    <version>${jetty.version}</version>
   </plugin>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-eclipse-plugin</artifactId>
    <configuration>
     <downloadSources>true</downloadSources>
    </configuration>
   </plugin>
  </plugins>
 </build>
 <properties>
  <wicket.version>1.4.16</wicket.version>
  <jetty.version>6.1.4</jetty.version>
 </properties>
 </project>

Import this into Eclipse any way you like. I'll use the m2eclipse and run the project using mvn jetty:run for now.

In the Wicket application, we just add a simple Panel that will update itself when clicked:


package de.tk.examples;

import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;

public class UpdatingPanel extends Panel {

 int timesClicked=0;
 String messageText = "This panel has not been updated";
 public UpdatingPanel(String id, IModel model) {
  super(id, model);
 }

 public UpdatingPanel(String id) {
  super(id);
 }

 @Override
 protected void onConfigure() {
  super.onConfigure();
  
  addOrReplace(new Label("message", messageText)
   .setEscapeModelStrings(false));
  add(new AjaxEventBehavior("onClick") {
   
   @Override
   protected void onEvent(AjaxRequestTarget target) {
    messageText = "This panel has been updated 
     "+(++timesClicked)+" times.";
    target.addComponent(UpdatingPanel.this);
   }
  });
 }
}

Wicket being Wicket, this goes along with the necessary markup file:

<html xmlns:wicket=
 "http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
    <head>  
        <title>Self-Updating Ajax Panel</title>
    </head>
    <body>
     <wicket:panel>
         <strong>This panel updates itself when you click it.</strong>
         <br/><br/>
         <span wicket:id="message">This is the default text</span>
        </wicket:panel>
    </body>
</html>

What do we have now? The Panel will initially say that it has not been clicked yet. Once clicked, it will replace itself with a new version of itself, saying how often it did that. This way we can easily check if every click got processed.

So, along for the testing. We'll start by using a naive approach - we just find the element and click it, three times. Then we check the message text to see if all went well:

@Test
public void findPanelWhileHoldingOnToTheElement() {
 WebDriver driver = new FirefoxDriver();
 driver.navigate().to("http://localhost:8080/wicket-selenium/");
 
 WebElement element = driver.findElement(By.cssSelector("div"));
 element.click();
 element.click();
 element.click();
}

Let's do a mvn jetty:run and run the test - and be slightly disappointed that it fails, complaining about a StaleElementException it got. What happened? Well, after the first click the Element got replaced. So the WebElement you're holding is not on the page anymore. It was replaced by another, quite similar one, but with different text. You might think 'well, so what? It's still the same thing, just give me text!', but you wouldn't really want that. Because it is not the same thing, it's a second instance. Imagine you had a JavaScript listener it it, one that not on the second version of that element anymore. Or the text is different, as is the case with this one. You're likely to want to know about that.

Now knowing one thing more, we can try a slightly smarter Approach: we'll just re-find the element every time we access it.

@Test
public void findPanelWhileRefindingTheElement() throws Exception {
 WebDriver driver = new FirefoxDriver();
 driver.navigate().to("http://localhost:8080/wicket-selenium/");
 
 driver.findElement(By.cssSelector("div")).click();
 driver.findElement(By.cssSelector("div")).click();
 driver.findElement(By.cssSelector("div")).click();
 
 assertThat(driver.findElement(By.cssSelector("div"))
  .getText(), containsString("3 times"));
}

Ah, so now it passes! Not very surprising, but satisfying nonetheless. But this approach is brittle, too. Imagine the Ajax call takes a while, let's say one second. We can simulate this by putting a Sleep in the EventHandler:

@Override
protected void onEvent(AjaxRequestTarget target) {
 try {
  Thread.sleep(1000);
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 messageText = "This panel has been updated "
  +(++timesClicked)+" times.";
 target.addComponent(UpdatingPanel.this);
}

(Please note that I am NOT advising you to program like this. This is just some quick and dirty test-driven exploration.)

Start the test again. (remember to restart Jetty ;-) What I got is the following JUnit error:
java.lang.AssertionError: 
Expected: a string containing "3 times"
     got: "This panel updates itself when you click it.\n\nThis panel has not been updated"

This one struck me dumb for a while. What I finally figured out is this: The Selemium commands seem to get queued and executed as quickly as possible. Which actually makes sense, if you think about it, the 'a' stands for 'asynchronous'. So, while the Ajax requests rumble along slowly, the assertion extracts the text of the panel and checks it. But up to now it has not even been replaced once, hence jUnit's complaint. If you look closely, you'll see that the test even ends as failed while the first request is still pending. While we could peruse the source code to look if this assumption is true, we might as well explore with a new test case:

@Test
public void findPanelWhileRefindingTheElement() throws Exception {
 WebDriver driver = new FirefoxDriver();
 driver.navigate().to("http://localhost:8080/wicket-selenium/");
 
 driver.findElement(By.cssSelector("div")).click();
 driver.findElement(By.cssSelector("div")).click();
 driver.findElement(By.cssSelector("div")).click();
 
 // sleep longer than the ajax requests need
 Thread.sleep(4000); 
 assertThat(driver.findElement(By.cssSelector("div"))
  .getText(), containsString("3 times"));
}

Now it passes again.

So, what do we do with this? Guessing how long the request will take is not an option. If the Ajax request would bring some new element to the page we could check repeatedly for its presence. This was a viable option in Selenium 1 and it still is. Selenium even provides helper classes for this (more on that later, perhaps). But our request just re-renders the same elements. Or does it? A change in the text is a change in the DOM, too. So I don't see why checking for this shouldn't work. Let's try it out:

@Test
public void findPanelWhileRefindingTheElement() throws Exception {
 WebDriver driver = new FirefoxDriver();
 driver.navigate().to("http://localhost:8080/wicket-selenium/");
 
 driver.findElement(By.cssSelector("div")).click();
 driver.findElement(By.cssSelector("div")).click();
 driver.findElement(By.cssSelector("div")).click();
 
 String text = driver.findElement(By.cssSelector("div")).getText();
 while (!text.contains("3 times")) {
  Thread.sleep(500);
  text = driver.findElement(By.cssSelector("div")).getText();
 }
 assertThat(driver.findElement(By.cssSelector("div"))
  .getText(), containsString("3 times"));
}

The result is rather promising, if clumsily achieved. The test passes, and it does not end before the Ajax requests do. We can actually do better, since we're using wicket.

We can take advantage of Wicket's Ajax implementation, which allows for adding of Listeners before and after each Ajax request. Let's try if we can use these to observe our calls and wait for them to finish.

@Test
public void canObserveWicketAjaxViaJavaScript() throws Exception {
 final WebDriver driver = new FirefoxDriver();
 driver.navigate().to("http://localhost:8080/wicket-selenium/");

 // register wicket handlers
 final JavascriptExecutor js = ((JavascriptExecutor) driver);
 js.executeScript(
  "if (typeof tk  == 'undefined') tk = "
  + "{activeAjaxCount: 0, ajaxCallsTried: 0, ajaxCallsCompleted: 0}; "
  + "Wicket.Ajax.registerPreCallHandler(function()"
  +"{tk.activeAjaxCount++;tk.ajaxCallsTried++;});"
  + "Wicket.Ajax.registerPostCallHandler(function()"
  +"{tk.activeAjaxCount--;tk.ajaxCallsCompleted++;});");

 // start ajax requests
 new DivFinder().findFrom(driver).iterator().next().click();
 new DivFinder().findFrom(driver).iterator().next().click();
 new DivFinder().findFrom(driver).iterator().next().click();

 // and wait for processing
 new Wait("Ajax calls did not finish in time!") {
  public boolean until() {
   return (Boolean) js
    .executeScript("return tk.activeAjaxCount == 0 "
    +"&& tk.ajaxCallsCompleted==3");
  }
 }.wait("waiting for finishing Ajax Call");

 // Finder API for expressive condition checks
 WebElement div = new DivFinder().findFrom(driver).iterator().next();
 assertThat(div.getText(), containsString("3 times"));
}

Run the tests, and rejoice! It works.

Let's summarize a bit. Selenium 2 does a great job on static pages. It also does quite a good job on pages that use Ajax. What can happen to you when you use WebElements as a basis, however, is that they grow stale on you when an Ajax request is sent. This can actually happen in a rather unpleasant way - in one line of code, the WebElement behaves just fine, in the next it's gone. Since it is rather unproductive to wrap each access in a try/catch and refresh the WebElement when necessary, I'd advise to have a look at the Finders in the Selenium Lift API. We've just used one of those in the last test. They take some getting used to, if you're not so much into predicates and the like, but I for one really like the expressiveness they give the code. On the plus side, you can use that style in jUnit to receive better error messages with assertThat(...) than with the simpler assertion messages. And it's a great example of the flexibility you gain when using objects even for simple tasks, like filtering a list of elements on some predicate. This lesson alone is worth a lot.

While the wait-for-ajax part in the last test can certainly benefit from some heavy refactoring and will not work in every situation, it shows how you can deal with the need to wait for Ajax in Wicket applications. Using a test-style approach you can easily experiment with different scenarios. When you find something you want to use, refactor the code out, or even better, TDD yourself a proper implementation based on your experiments. That way, you still have you old tests/experiments to retrace your steps.

Wednesday, December 29, 2010

Configuring checkstyle in eclipse via the maven-eclipse-plugin

I like to keep my eclipse configuration files in a central place, so that I can change them more easily. Currently, I tend to have a build-resources Maven project around. Inside this, amongst other things, lies the checkstyle configuration for use during the Maven build. The build-resources project is then added as a build extension, so that the files are accessibly during the build.

For projects using this way of configuration, it is desirable to have the eventually created Eclipse project to be able to use the same configuration file. The following steps allow me to access the checkstyle configuration file, create a configuration for the Eclipse Checkstyle plugin, and have that set up automatically whenever i call mvn eclipse:eclipse.

Create a template configuration file for the Eclipse Checkstyle Plugin

Head over to the project's configuration in Eclipse. In the "Checkstyle" menu entry, switch to "Local Check Configurations". Here, create a "New" configuration with the following data:


Type:
Remote Configuration
Location: jar:file:///[your local maven repo]/[path-to-build-resources-project]/build-resources-1.1.5.jar!/checkstyle/checkstyle-maven-config.xml

This configuration will access the build-resources project's jar file and select the proper file inside it. It uses Java's built-in jar-Protocol to access this file.

Use this configuration set with your Eclipse project. Configure any inclusions/exclusions or such as you like.

Configure eclipse:eclipse to use your configuration template

Now that we have our template, we must make sure it will be used whenever eclipse:eclipse is called. To do so, first copy the Eclipse Checkstyle configuration file (".checkstyle" in your project directory inside the Eclipse workspace) over into your build-resources project. I saved it to eclipse/checkstyle-config.xml. Now you can tell the maven-eclipse-plugin to copy over that file during the creation by addin this to your global maven parent pom:

<pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-eclipse-plugin</artifactId>
            <version>2.8</version>
            <configuration>
                <additionalConfig>
                    <file>
                        <name>.checkstyle</name>
                        <location>eclipse/checkstyle-config.xml</location>
                    </file>
                </additionalConfig> 
                <additionalProjectnatures>
                    <projectnature>
                        net.sf.eclipsecs.core.CheckstyleNature
                    </projectnature>
                </additionalProjectnatures>       
            </configuration>
        </plugin>
    </plugins>
</pluginManagement>
Since you have added the build-resources project as a build extension, its contents will be on the classpath. Hence, the location "eclipse/checkstyle-config.xml" will be copied to [project base dir]/.checkstyle and picked up by the Checkstyle Plugin. So from now on, every time you release a new version of your build-resources, all eclipse projects will automatically be updates to these changes as soon as the new build-resources version makes it to your local repository (i.e.: on the next run of maven).

All that's left to do is run mvn eclipse:eclipse and refresh/import the Eclipse project.

Note: I have not checked if the m2eclipse plugin will pick up the configuration too. I do not use it much for bigger projects, in my experience it slows down the builds, especially on projects with many modules. The eclipse:eclipse way gives me the best of two worlds: a clean eclipse projects without any Maven magic - and a console in which I can use Maven without eclipse getting confused.