Last Monday I got into the office and I decided that is it, I am going to get our app upgraded to Spring 4.1. I had been working on this off and on for like 9 months, updating dependencies in the pom, doing some testing, wash, rinse, repeat…
As I had mentioned in a previous posts one of the first issues I had was the new aspect j running the hibernate metamodel generator and dumping a bunch of generated class in the root level directory of wherever maven was running. I had opened a Jira against the aspectj-maven-plugin. There was even a user who contributed a patch for the issue, and the developer promised to look at it in January but months went by with no effort to resolve the issue. Now CodeHaus is shutdown and the active projects have moved to MojoHaus. As of yet the aspectj-maven-plugin hasn’t been moved so more and more it looks like my decision to download the code from their SVN repository and fork it on github was correct.
The first thing I did on Monday was to clone that repository and fix a couple of broken unit tests I had in it and then install it locally in our nexus server. Next up I updated the pom files to use my new version of the plugin and added the
<proc>none</proc> config option that was introduced in aspectj 1.8.2. I fired up my local environment to test everything and discovered one of the major features of the app was broken. It looks like the way Spring 4.1 handles the ConverterFactories. We use a lot of Hibernate UserTypes in our app to map things to enums. The enums implement a common interface that handles the mapping between the storage of that enum and the value. With a little tweaking on how those enums were used I was able to get Spring to convert them correctly again using our Converter Factories.
I was thinking everything was good to go at this point and my testing discovered that our new feature that is Angular.js driven was broken. After much tracing and debugging I determined that some
@ResponseBody parameters that in Spring 4.0 would accept an empty string in 4.1 that empty string was converted to a null and then the method was failing. I marked those methods to be
@ResponseBody(required = false) and we were back up and running.
By this point it was already Wednesday morning. So I submitted the code to git and let jenkins run our tests on it. I immediately started getting some unit test failures saying that it couldn’t find the
aspectOf() factory method. This didn’t make any sense as when you do compile time aspect weaving this method is supposed to be automatically added to your classes. I ended up digging through the aspectj source code as my first thought was what if somehow
@Aspect isn’t being processed when you turn off annotation processing. I wasted way too much time down this path before I realized that it wouldn’t make sense as the whole point of ajc is to compile the aspects. Then in digging through the jenkins build log I realized what was really happening. The maven-java-compiler plugin 3.1 was actually running after the ajc compiler thus rewriting my woven classes with unwoven classes. When researching this issue I see a lot of people set the java-compiler plugin under maven to be
<phase>none</phase>. We have ours set to
test-compile with the ajc compiler set for the
compile phase. When I tried to move
test-compile to the ajc compiler it didn’t like some things we were doing with generics. I feel like the ideal fix would be to do that and don’t use the maven one at all. But since I just wanted to get this in and working I just reverted back to the maven-java-compiler version 2.5.1 which doesn’t seem to fire up again and rewrite the class. Todo for the future will be to try to entirely use the ajc compiler for the modules which need aspects woven into them.
After I had the aspectj issues solved I started seeing out of memory errors in our unit test phase. I banged my head on this for a day and a half before I figured out for some reason the combination of powermock-1.6.2 and junit-4.12 seem to be leaking memory or not shutting down some threads that are fired up when running the test. I tested going back to powermock-1.5.6 and junit-4.11 (since 4.12 isn’t compatible with powermock-1.5.6) and finally everything was happen and working. It was code reviewed yesterday and is now merged into master. So I am pretty excited to finally have reached the end of this project. I am hoping that the aspectj-maven-compiler will be resurrected from the dead and brought into mojohaus with my fix so that I can go away from my forked copy, but time will tell on that. Up next will be figuring out how to migrate to Spring Security 4.0.