Spring 4.1 finally!!!

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.

The nuclear option

I have been using open source software now for about 20 years. One of the things that I always saw discussed back in the day was if you don’t like the way a project is being run you can always fork it and do things differently. In all my years I have never actually felt the need to do such a thing because lets be honest running an open source project is a ton of work. As readers of my blog know I have been wanting to update to Spring 4.1. What has been holding us back was a change in aspectj 1.8.2 where it would automatically process annotations found in the code. This ends up generating the hibernate meta-model and dumping the files wherever maven was invoked. So trying to work within the project I opened up a jira for an enhancement which would allow me to pass a flag to the compiler to not process the annotations. There was a quick response at the beginning of January and I was left with the impression that this would be handled in a couple of weeks. Finally in the middle of February with the work still not done Ralph Engelmann submitted a patch which would actually implement the feature.

I thought certainly once someone had actually done the work and implemented this a new version would be forthcoming but it has gone to complete silence on that jira. Maybe this has fallen to the wayside with the news that Codehaus is shutting down. In any event my patience was up a few weeks ago so I was like let me group the source code and throw it on github and apply the patch. The first thing I found was they use Subversion instead of Git which seemed pretty suprising to me. Who would use SVN anymore, it is so terrible compared to git. Anyway I got the source code and threw it up on my github account. I applied the patch and for grins upped the version to a Java 7 minimum as I have no intention of using java 6. I changed the package name to avoid confusion. I have no desire to actually maintain this project so I haven’t done anymore to actually get it out into a maven repository. I think my plan in the short term is to just install this into our local nexus server and use it to bring us up to Spring 4.1. My hope for the medium and long term is that once they deal with the codehaus move this will get updated and I can back to the codehaus project as I don’t want to maintain this. But for now I am going nuclear and forking it and moving on…

Maven Compiler Plugins, AspectJ, and the Hibernate Metamodel generator

For a while now I have been avoiding upgrading the maven java compiler plugin. We are running 2.5.1 at work. The problem is, in the 3.x version, they seemed to have rewritten it, and it doesn’t want to play nice with the maven-processor-plugin that we used to run the hibernate meta model generator. So far it was like cool, I just won’t upgrade to the new version.

Then AspectJ came out with 1.8.2 and the new AspectJ compiler plugin which also seems to be built like the new compiler plugin. At this point I was like well then I might as well update both since Spring 4.1 wants at least AspectJ 1.8.2. But I still have the whole thing fall apart at that meta model step. I found a flag for the maven compiler about forceJavacCompilerUse but even that didn’t solve the problem for me. A coworker said basically AspectJ seems to be doing what we were using the maven-processor-plugin for and generating the meta models for the entities, so he disabled that plugin. However for some reason instead of dumping the generated files in the target directory it is putting them in whatever directory you are in for the build and we can’t seem to find a way to get it to drop them in the target folder.

So at this point we either need to keep banging our head against the wall on this, or consider rewriting the one place we use the meta model classes to not use them and throw that code out in order to be able to upgrade to Spring 4.1.