Marc Schwieterman

That depends...

Maven Transitive Dependency Filtering

The other day I wrote a post about examining dependencies in maven plugins. Today I was working on a similar project, and I discovered some non-intuitive behavior with the Maven ArtifactResolver. Several of the resolveTransitively methods accept an ArtifactFilter, but the filter gets applied in an odd way.

The bulk of the resolution process takes place in the DefaultArtifactCollector and ResolutionNode classes. The collector basically does a breadth first search of the dependency tree, but it filters the entire path from the project to the node, as opposed to just filtering the final results. This means that depending on how your filter is defined, there could be dependencies that meet its criteria, but are not included in the ArtifactResolutionResult. Consider a project with the following dependency tree.

1
2
3
4
[INFO] [dependency:tree {execution: default-cli}]
[INFO] com.mydomain:module:jar:0.0.1-SNAPSHOT
[INFO] +- com.mydomain:dependency:jar:0.0.1-SNAPSHOT:compile
[INFO] |  \- com.mydomain:transitive-dependency:jar:0.0.1-SNAPSHOT:compile

You can filter on a groupId of “com.mydomain”, and you’ll get all of the artifacts. However if you were to try to filter on an artifactId or a type other than jar, you’d get zero results. I’m sure there’s a good reason for the filtering to work this way, but it can take you a while to figure it out if it’s not what you’re expecting. If what you really want to do is filter the final results of the transitive resolution, you need to do that yourself.

Hibernate: Automatic Versioning

One of the optimistic locking features that Hibernate provides is automatic versioning. Versioned objects need to contain either a version or timestamp property that Hibernate uses to detect concurrent modifications at flush time. Hibernate’s versioning mechanism works by checking the number of rows that were affected by an update statement. Consider an accounts table like the one below.

1
2
3
4
5
6
7
8
mysql> describe accounts;
+---------+---------+------+-----+---------+-------+
| Field   | Type    | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| id      | int(11) | NO   | PRI | 0       |       |
| balance | int(11) | NO   |     | NULL    |       |
| version | int(11) | NO   |     | NULL    |       |
+---------+---------+------+-----+---------+-------+

For the sake of our example, let’s assume that someone has just opened an account. Their balance is currently $0, so their row in the accounts table would look something like this.

1
2
3
4
5
6
mysql> select * from accounts;
+----+---------+---------+
| id | balance | version |
+----+---------+---------+
|  1 |       0 |       1 |
+----+---------+---------+

If our hypothetical user were to make a deposit of $100, Hibernate would increment the account object’s version property, and eventually execute the following update. Pay close attention to the values used for the version column. We’re setting the new version value to 2, but only if the row’s current value for version is 1.

1
2
3
4
mysql> update accounts
    -> set balance = 100, version = 2
    -> where id = 1 and version = 1;
Query OK, 1 row affected (0.00 sec)

After executing the update statement, Hibernate will check the number of rows that were affected. If nobody else modified the row, then the version will still be 1, the update will modify exactly 1 row, and the transaction commits. Our account now has a balance of $100 and a version of 2.

1
2
3
4
5
6
mysql> select * from accounts;
+----+---------+---------+
| id | balance | version |
+----+---------+---------+
|  1 |     100 |       2 |
+----+---------+---------+

What would have happened if somebody else had modified the row? Perhaps our bank offers a $5,000 sign up bonus for new accounts, and the bonus just happens to post at the exact same moment that we’re making our initial deposit. If the bonus transaction had committed after we read the account balance, but before we committed the deposit, the table would look like this.

1
2
3
4
5
6
mysql> select * from accounts;
+----+---------+---------+
| id | balance | version |
+----+---------+---------+
|  1 |    5000 |       2 |
+----+---------+---------+

Now when our update statement is executed, the account has a balance of $5,000 and a version of 2. Because we’re updating where the version is 1, the update will “miss”. Zero rows will have been modified, and an exception is thrown.

1
2
3
4
mysql> update accounts
    -> set balance = 100, version = 2
    -> where id = 1 and version = 1;
Query OK, 0 rows affected (0.00 sec)

This is exactly what we want to happen because if our transaction had succeeded, we would have just lost out on $5,000. At this point, our application will need to load a fresh instance of our account object and apply the deposit again.

1
2
3
4
mysql> update accounts
    -> set balance = 5100, version = 3
    -> where id = 1 and version = 2;
Query OK, 1 row affected (0.00 sec)

This time our update succeeds, and the account has the correct balance of $5,100, with a version of 3.

1
2
3
4
5
6
mysql> select * from accounts;
+----+---------+---------+
| id | balance | version |
+----+---------+---------+
|  1 |    5100 |       3 |
+----+---------+---------+

While automatic versioning solves the problem of concurrent modifications within the boundaries of a database transaction, if your business transactions span multiple server requests, automatic versioning alone isn’t enough. Hibernate has additional features that help with this situation, which I’ll go into in a future post.

Examining Dependencies in Maven Plugins

After you’ve worked with Maven for a while, you’ll eventually find a need to extend it. While there are some means of executing arbitrary code as part of your build, the best way to handle such needs is to create a maven plugin. The task may seem a bit daunting at first, but you’ll learn a lot about how maven works by doing it. Listed below are the properties that you need to define to examine the dependencies of a maven project from within a plugin. The following code would be placed inside a Maven Mojo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/** @parameter default-value="${project}" */
private MavenProject mavenProject;

/** @parameter default-value="${localRepository}" */
private ArtifactRepository localRepository;

/** @component */
private ArtifactFactory artifactFactory;

/** @component */
private ArtifactResolver resolver;

/** @component */
private ArtifactMetadataSource artifactMetadataSource;

The @parameter annotation will bind maven properties to the annotated property. You can refer to many properties on common Maven interfaces. The @component annotation binds Plexus components from maven’s DI framework. Unfortunately I’ve yet to find a single, concise documentation source, but the Codehaus Mojo Cookbook and the Maven API doc will point you in the right direction.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Set<Artifact> artifacts = mavenProject.createArtifacts(
      artifactFactory,
      null,
      new GroupIdFilter("com.mydomain")
);

ArtifactResolutionResult arr = resolver.resolveTransitively(
      artifacts,
      mavenProject.getArtifact(),
      mavenProject.getRemoteArtifactRepositories(),
      localRepository,
      artifactMetadataSource
);

Set<Artifact> completeDependencies = arr.getArtifacts();

for(Artifact art : completeDependencies) {
  // do something interesting
}

Once you have access to all the needed properties, you can use code similar to the above to examine the dependencies of your project. This particular snippet will collect all dependencies and transitive dependencies for artifacts with a group id of “com.mydomain” into the completeDependencies set. GroupIdFilter is a simple implementation of the ArtifactFilter interface. Note that these are the dependencies of the project that the plugin is executing in, not just those of the plugin itself.

1
JarFile jar = new JarFile(artifact.getFile());

The ability to determine all of the transitive dependencies of your project like this can be very powerful. Once you get ahold of an artifact, you can easily create a JarFile and inspect its manifest, entries or whatever you’re interested in. This allows you to do things like create artifacts that contain code or configuration that feeds into your build process, and automatically discover and take action merely by adding them as a project dependency.

Getting Files onto the iPad

The lack of a file system on the iPad and other iOS based devices can sometimes be frustrating. While applications like Dropbox make accessing your existing files trivial, getting new files onto your device directly from the web is not as easy. If you come across a PDF or other file that you’d like to open in a local application, you may be out of luck.

The best way I’ve found to get files onto the iPad without the aid of your computer is GoodReader. In addition to being an excellent PDF reader, GoodReader is also a robust file manager. It supports about anything you can think of, including Dropbox, iDisk, USB, FTP and even a web-based interface accessible via WiFi. Most importantly, you can give it a URL, and it will download the specified file into its local storage.

The GoodReader manual includes instructions on how to save a file from Safari into GoodReader. You have to either add a special prefix to the URL, or you can copy and paste it into the application. GoodReader supports this feature by registering a protocol handler for ghttp, grhttp, and a few others. While I think this is a great feature, I don’t particularly like doing things manually, so I created a simple bookmarklet to do this for me.

1
javascript: location.assign('gr' + location.href);

The bookmarklet uses the Location object to open a new page to the current URL with ‘gr’ prepended to it. This saves you from manually editing or copying the URL of the document you want to download. You can install the bookmarklet with the instructions below.

  1. Bookmark this page
  2. Copy the bookmarlet script above to your clipboard
  3. Edit the bookmark
  4. Set the name to something appropriate. I use ‘goodreadit’.
  5. Paste the code into the address field

The easiest way to copy the bookmarklet script on the iPad is to hold your finger down on it until the copy button pops up. Once the bookmarlet is installed, all you need to do is click on it, and whatever document you have open in Safari will automatically start downloading into GoodReader. According to the GoodReader documentation, the import feature may not always work correctly with SSL, but I’ve yet to have any trouble with it.

Simple Stub Creation with Mockito Partial Mocks

When testing code that interacts with lower layers, I often stub out the lower layer to return objects to the code that I’m actually testing. I mostly use stubs generated by a mocking framework, but I occasionally come across cases where the stub needs to do something other than just return a known object. Take the case of a DAO that assigns a generated identifier to a domain object. Here we see a service that takes a name, creates a User object with it, persists the object and returns the generated id to the caller.

1
2
3
4
5
public interface UserService {

  Long create(String name);

}

In this situation, I would want to test that the following are true.

  1. the service calls the persist method on the DAO
  2. the service returns the correct id value

Testing the DAO call is easy enough using a mock.

1
2
3
4
5
6
7
8
9
@Test
public void create_calls_persist() {
  UserDao dao = mock(UserDao.class);
  UserService service = new UserServiceImpl(dao);
  
  service.create("bob kelso");
  
  verify(dao).persist(any(User.class));
}

How do we test that the service returns the correct id? The id will be null by default because it’s a Long. At the very least we should make sure it’s a non-null value, and we would prefer to assert that it’s something specific. We can’t stub the domain object because the service creates it. One option is to create a stub implementation of the DAO that simply sets the object’s id to a known value. Assume that our DAO interface looks like the one below.

1
2
3
4
5
6
7
8
9
public interface UserDao {

  void persist(User user);
  void update(User user);
  void delete(User user);
  User load(Long id);
  User findByName(String name);
  
}

While there aren’t too many methods, we really don’t care about anything but persist, so it’d be nice if we only had to deal with the things we do care about. This is where Mockito comes in. Using the partial mocks feature added in version 1.8.0, we can create an abstract class that only implements the persist method, and let Mockito supply its useful default implementations for the rest of the methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class UserServiceTest {
  
  public static final Long ONE_OF_TYPE_LONG = 1L;

  public static abstract class UserDaoStub implements UserDao {

      @Override
      public void persist(User user) {
          user.setId(ONE_OF_TYPE_LONG);
      }

  }

}

We now have an abstract stub for our DAO that will set the id of any objects it persists to a 1 of type Long. You can obviously do something more complicated if needed. Next we use Mockito to provide the rest of the implementation.

1
2
3
4
5
6
7
8
9
10
@Test
public void create_returns_generated_id() {
  UserDao dao = mock(UserDaoStub.class);
  doCallRealMethod().when(dao).persist(any(User.class));
  UserService service = new UserServiceImpl(dao);
  
  Long id = service.create("bob kelso");
  
  assertThat(id, is(ONE_OF_TYPE_LONG));
}

The only thing different about creating a partial mock, is that you need to call either thenCallRealMethod() or doCallRealMethod() to indicate which method calls to delegate to the real object. The example above uses doCallRealMethod() because persist has a void return type. I’ve found this technique to be a very effective way to create focused stubs that allow you to specify what you need to, and not worry about the rest.

Update 2012-05-31

Someone pointed out in the now gone comments that this approach does not work if the stub class needs to carry state. If this is the case for you, you may want to consider a fake. This may also be an opportunity to refactor your code to make it easier to test the desired behavior in isolation.

MarsEdit: Preview with SyntaxHighlighter

I’ve recently been trying out the MarsEdit blog editor. One issue I’ve run into is that SyntaxHighlighter doesn’t work with the preview feature because the page in the preview window only gets loaded once. Fortunately there is a workaround. A typical SyntaxHighlighter configuration will look similar to the code fragment below.

1
2
3
4
5
6
<script type="text/javascript">
  ...

  SyntaxHighlighter.all();

</script>

To get SyntaxHighliter to work in the preview pane, you need to write a javascript function to execute the highlighting code repeatedly at some interval. The following code will highlight the page once, then highlight it again every second. The main difference is that you must call SyntaxHighlighter.highlight(), as SyntaxHighlighter.all() will only highlight your text when the page’s onLoad event is executed.

1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
  ...

  function refreshHighlighting() {
      SyntaxHighlighter.highlight();
      setTimeout("refreshHighlighting()", 1000);
  }

  refreshHighlighting();

</script>

That’s all there is to it. The timeout is in milliseconds, and I haven’t noticed any appreciable load at 1 second. You can set the refresh interval to something higher, but be aware that you’ll have to wait that long for your code to be highlighted again in the preview window. Refer to the setTimeout reference if you have more robust refresh timing needs.