tag:blogger.com,1999:blog-69014943919598282042024-03-12T22:49:40.153-04:00rachitskillisaurusEugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.comBlogger9125tag:blogger.com,1999:blog-6901494391959828204.post-69918584061058397622014-06-11T18:24:00.000-04:002014-06-11T18:24:35.970-04:00Percona PAM authentication in JDBC<div dir="ltr" style="text-align: left;" trbidi="on">
Percona's MySQL distribution supports PAM based authentication. Unfortunately this currently confuses the heck out of the latest MySQL JDBC driver. First of all, the percona server asks the client to use the "dialog" authentication plugin. Unless percona binaries are installed on the machine, this plugin is not available. One can substitute the clear text password plugin, but it depends on SSL being present. <br />
<br />
What can you do if your Percona server is configured to use pam authentication and does not support secure connections? Write your own MySQL connector authentication plugin. Assuming the connector jar distribution is on your classpath, simply compile the below:<br />
<br />
<pre class="Java" name="code">
public class DialogPasswordPlugin extends MysqlClearPasswordPlugin {
@Override
public String getProtocolPluginName() {
return "dialog";
}
@Override
public boolean requiresConfidentiality() {
return false;
}
}
</pre>
put the compiled class on your classpath and add "<span style="background-color: #f8f8f8; color: #333333; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: 20px; white-space: nowrap;">authenticationPlugins=com.rubiconproject.mysql.percona.DialogPasswordPlugin"</span> to your JDBC URL.
<br/>
You should now be able to authenticate with the Percona server.
</div>Eugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.com0tag:blogger.com,1999:blog-6901494391959828204.post-81192735424715288422013-11-17T17:34:00.000-05:002013-11-17T17:34:04.562-05:00Resolving generic method return types<div dir="ltr" style="text-align: left;" trbidi="on">
Java supports generic/parameterized return types:
</div>
<pre class="Java" name="code">public <t> T anyType();</t></pre>
<div>
A method with a generic return type like above is now expected to return different types depending on its caller. For example -
</div>
<pre class="Java" name="code">String string = anyType();</pre>
<div>
expects "anyType()" to return a String. Whereas
</div>
<pre class="Java" name="code">Integer i = anyType();</pre>
<div>
expects "anyType()" to return an Integer. There does not appear to ber a way of determining a method's expected return type at runtime. To get around this, many APIs tend to specify the expected return type by describing it in method parameters - for example:</div>
<pre class="Java" name="code">public <t> T anyType(Class<T> type);
public <T> T getBean(String beanName,Class<T> beanType);</pre>
<div>
I put together a <a href="https://github.com/ProfessorEugene/rrd-generics-inspector">library</a> that provides an alternative -
</div>
<pre class="Java" name="code">public <T> T anyType(){
Class<?> myReturnType = Resolver.getConcreteReturnType();
..
}</pre>
<div>
The library works by inspecting a method's call stack. The call stack typically includes class names, method names, and line numbers. Using these, the library locates the code surrounding method invocations using the <a href="http://asm.ow2.org/">ASM</a> bytecode manipulation library and inspects it for "CHECKCAST" operations. The found type is the expected return type of the parameterized method. Extracting parameterized return types (e.g. Map<String,List<Integer>>) is a little trickier but also possible.
<br/>
<br/>
Instead of going with the google code route to share the project like I'm used to, I've decided to give github a try. I've also set up continuous integration using <a href="http://drone.io">drone.io</a> - so far, it's been an excellent experience.
Read more over at <a href="https://github.com/ProfessorEugene/rrd-generics-inspector">https://github.com/ProfessorEugene/rrd-generics-inspector</a> !
</div>Eugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.com0tag:blogger.com,1999:blog-6901494391959828204.post-25181308400744204352013-10-05T04:24:00.003-04:002013-10-06T14:05:53.000-04:00Extending static methods in java<div dir="ltr" style="text-align: left;" trbidi="on">
Java doesn't allow extending static methods. I put together <a href="http://code.google.com/p/rrd-static-extender/">a library</a> with an <br />
<pre>@OverrideStatic</pre>
annotation that allows one to change this behavior over at <a href="http://code.google.com/p/rrd-static-extender/">http://code.google.com/p/rrd-static-extender/</a>.<br />
<br />
Having recently done a bit of dirty copy/pasting to extend a third party library with a bunch of static methods at work, I've given some thought to what it would take to allow one to extend static methods. <br />
<br />
<div>
<br /></div>
<div>
Take the below hierarchy for example:</div>
<pre class="Java" name="code">class Base{
void instanceMethod(){
staticMethod();
}
static void staticMethod(){
...
}
}
class Subclass extends Base{
static void staticMethod(){
...
}
}
</pre>
<div>
When one creates an instance of Subclass and invokes "instanceMethod" , Base#staticMethod() instead of Subclass#staticMethod() is invoked. Other than using something like <a href="http://eclipse.org/aspectj/">aspectj</a> or maybe <a href="https://code.google.com/p/powermock/">powermock</a> there isn't really a good way to change this behavior. </div>
<div>
<br /></div>
<div>
In some cases, one might want all instances of Subclass to invoke Subclass#staticMethod() instead of Base#staticMethod when "instanceMethod" is invoked. The desired behavior seems pretty simple to explain:</div>
<ul>
<li>subclasses should have the ability to override their super-class' static methods</li>
<li>instance methods of such classes should invoke the overriding method</li>
<li>any inner and local classes of the super-class who's enclosing instance is a subclass should also invoke the overriding method.</li>
<li>instance methods of such classes' super classes should invoke the overridden method</li>
<li>in order to not interfere with expected behavior one should be able to mark an overriding method with an annotation</li>
</ul>
<div>
Starting with an @OverridesStatic annotation, there's a couple of approaches one could take to implement this behavior. At the end of the day, the bytecode of the base class needs to be instrumented to dispatch method calls to "staticMethod" to the appropriate place depending on the context of such calls. </div>
<div>
<br /></div>
<div>
Having intercepted a static method call, the instance of the caller needs to be inspected to check whether it is assignable from a class which contains the overriding method. If said instance is an inner class, it's enclosing class reference (something like this$1) needs to be recursively inspected. If the instance is a type of a subclass with the overriding method, the overriding method should be called in place of the overridden method.</div>
<div>
<br /></div>
<div>
Using the <a href="http://asm.ow2.org/">ASM</a> bytecode manipulation framework to detect and modify any invocations of static methods in a class is a breeze. The problem is to how to load the modified bytecode. There's a few alternatives:</div>
<div>
<ul style="text-align: left;">
<li>Use your own class loader that overrides the "defineClass" method for loading any classes that might need to have their static methods overridden. The problem here is that portions of your application now needs to be loaded through a custom class loader - something like <a href="http://docs.spring.io/spring/docs/2.5.x/api/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.html">TomcastInstrumentableClassLoader</a>.</li>
<li>Rename classes (eg. the popular <a href="http://cglib.sourceforge.net/">CGLib</a> enhancer approach) as @OverrideStatic annotations are detected and load them in a separate class loader. Create a deep-proxy loaded in the application class loader that recursively copies fields and invokes methods on instances in the separate object hierarchy. This path is laden with traps - your proxy gateway won't work on final classes and the amount of reflection that has to happen is going to take a toll on performance.</li>
<li>Instrument the entire virtual machine using a java agent. While this is the cleanest way to go, it typically requires one to start the JVM with some funky looking command line arguments.</li>
</ul>
<div>
As anyone that's used jconsole before must be suspicious of, Java provides an way to allow one to instrument running virtual machines. Launching jconsole shows you a list of java virtual machines currently executing on your machine and allows you to 'attach' to one.</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_xSV-6L55mi4wTkhRG0sqd0VXXgL0rWFpJCkHduv9MSnoeqGZLWdVi4b2Lg9xSsWE1yuuI4wNl7NcTx2pyl1H4sEZe4NoBkVn6rcjgUphOycgvxkQLCW0L9A-U3hPPzja6FA-f5rKSU0/s1600/jconsole.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_xSV-6L55mi4wTkhRG0sqd0VXXgL0rWFpJCkHduv9MSnoeqGZLWdVi4b2Lg9xSsWE1yuuI4wNl7NcTx2pyl1H4sEZe4NoBkVn6rcjgUphOycgvxkQLCW0L9A-U3hPPzja6FA-f5rKSU0/s320/jconsole.png" width="284" /></a></div>
<br /></div>
<div>
</div>
<div>
<br /></div>
<div>
Presumably, jconsole achieves this via the <link></link><a href="http://docs.oracle.com/javase/6/docs/jdk/api/attach/spec/com/sun/tools/attach/package-summary.html"> java attach API</a>. This API lets you list any running virtual machines and attach to them and load agents. While the implementation of the API is proprietary, the "Instrumentation" framework used by such agents is not. Indeed, coding against the <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html">java.lang.instrument.Instrumentation</a> interface seems to be a portable endeavor.</div>
</div>
<div>
<br /></div>
<div>
In light of this, I came up with the <a href="http://code.google.com/p/rrd-attach-util/">rrd-attach-util</a> library to allow one to attach to and instrument the virtual machine in which it is executed. The library provides a very simple API to obtain an Instrumentation instance for the running VM without having to jump through hoops packaging an actual agent:</div>
<div>
<br /></div>
<div>
<pre class="Java" name="code">LocalInstrumentationFactory.getLocalInstrumentation();
</pre>
<div>
<br /></div>
<div>
Once an Instrumentation object is obtained, <b>all</b> loaded classes can be inspected and instrumented. Since attach API implementations are proprietary, as far as I know rrd-attach-util only works with Sun/Oracle JDK6 and later. This doesn't seem like a big deal since most folks seem to be running Oracle JREs these days.</div>
<div>
<br /></div>
<div>
I used this API to create a simple implementation of a "static extender" To use it, one annotates static methods with an @OverrideStatic annotation, calls OverrideStatics.enable(), and all such annotations are picked up and static method invokation changes to the behavior described above until such time that OverrideStatics.disable() is invoked.</div>
<div>
<br /></div>
<div>
A unit test that demonstrates this behavior in action:</div>
<div>
<br /></div>
<pre class="Java" name="code">static class BaseClass{
public String callStaticMethod() throws Exception{
return staticMethod();
}
public static String staticMethod(){
return "BaseClass";
}
}
static class SubClass extends BaseClass{
@OverrideStatic
public static String staticMethod(){
return "Subclass";
}
}
@Test
public void demonstrateOverrideStatic() throws Exception{
/* instantiate a base and sub class */
BaseClass baseClass = new BaseClass();
SubClass subClass = new SubClass();
/* BaseClass#callStaticMethod will always route to BaseClas#staticMethod */
assertEquals("BaseClass",baseClass.callStaticMethod());
/* SubClass#callStaticMethod will always route to BaseClas#staticMethod */
assertEquals("BaseClass",subClass.callStaticMethod());
/* lets see what happens when we enable static overrides */
OverrideStatics.enable();
/* SubClass#callStaticMethod will now route to SubClass#staticMethod */
assertEquals("Subclass",subClass.callStaticMethod());
/* BaseClass#callStaticMethod will still route to BaseClass#staticMethod */
assertEquals("BaseClass",baseClass.callStaticMethod());
}
</pre>
<div>
<div class="p1">
<br /></div>
<div class="p1">
<br /></div>
<div class="p1">
My implementation works great for my needs and doesn't seem to cause a big performance hit. There is however a lot of room for improvement:</div>
<div class="p1">
</div>
<ul style="text-align: left;">
<li>The actual code could use a cleanup.</li>
<li>Calls to overridden static methods are intercepted and routed to a <a href="http://code.google.com/p/rrd-static-extender/source/browse/src/main/java/com/rrd/tools/lang/staticextender/annotation/OverrideStatics.java?name=rrd-static-extender-1.0.0#450">utility method</a> that uses reflection to decide which method to invoke. It seems like this can be done through bytecode manipulation like the <link></link><a href="http://code.google.com/p/rrd-static-extender/source/browse/src/main/java/com/rrd/tools/lang/staticextender/annotation/OverrideStatics.java?name=rrd-static-extender-1.0.0#140"> actual interception</a> of these calls.</li>
</ul>
<div>
In general though, this is a great example of what one can do in a few days to totally modify Java behavior through bytecode manipulation. The library also serves as a functional showcase of the utility provided by the <a href="http://code.google.com/p/rrd-attach-util/">rrd-attach-util</a> API. Until I've got the time to clean up, use at your own risk!</div>
</div>
</div>
</div>
Eugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.com0tag:blogger.com,1999:blog-6901494391959828204.post-67725652662166832952013-10-02T19:40:00.001-04:002013-10-02T19:40:49.091-04:00Spring: Force a bean to be the first to initialize<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Spring provides the "depends-on" bean attribute to control bean initialization order. Unfortunately, there are some rare cases where you really want to run some code before the application context initializes. An example scenario might involve messing around with the thread class loader before something like "PropertiesPlaceholderConfigurer" has a chance to initialize.<br />
<br />
There are a number of ways to go about this, but the easiest might be through implementing a PriorityOrdered BeanFactoryPostProcessor. After all spring beans are defined, spring calls all BeanFactoryPostProcessor s defined in the application context. Post processors that implement PriorityOrdered, and have the highest precedence are called first.<br />
<br />
To execute some code before <b>any</b> other spring beans or processors have a chance to initialize, one can therefore use something like the following:<br />
<pre class="Java" name="code">
/**
* An example spring pre-initializer. Referncing this class as a bean in an
* application context will cause it to be the first executed PostProcessor
* after all beans in the application context are defined.
*/
public class PreInitializer implements BeanFactoryPostProcessor, PriorityOrdered {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
/* put initialization code here */
}
}
</pre>
<br />
This is an easy hack to perform initialization tasks that might affect the application context before anything else - including property resolution has a chance to run.
</div>
</div>
Eugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.com1tag:blogger.com,1999:blog-6901494391959828204.post-50779982478879637812013-08-24T17:41:00.001-04:002013-10-02T19:41:22.183-04:00Computing path to maven module base directory<div dir="ltr" style="text-align: left;" trbidi="on">
Having spent a bunch of time writing functional tests for maven projects with many modules, I tend to end up needing access to the project base path (typically the path with the pom.xml file in it). This isn't much of a problem when running a single module - new File(".") pretty much does it. On the other hand when attempting to access modules outside of the jvm base path, things start to get tricky. <br />
<br />
There's a couple ways to skin this cat - probably one of the more portable ones is a utility method that accepts a Class and a path and returns a File by checking the supplied Class' classloader:<br />
<br />
<br /></div>
<pre class="Java" name="code">
public static File getPathInModule(Class<?> classInModule,String ... items){
String tcPath = classInModule.getProtectionDomain().getCodeSource().getLocation().getFile();
String[] tcPathParts = StringUtils.split(tcPath,File.separator);
StringBuffer pomPath = new StringBuffer();
for(String part:tcPathParts){
pomPath.append(File.separator);
if("target".equals(part)){
break;
}
pomPath.append(part);
}
pomPath.append(StringUtils.join(items,File.separator));
return new File(pomPath.toString());
}
</pre>
This works fairly well as long as there is a target directory present, which is for my purposes - always. It could be modified to look for a pom.xml file instead though.Eugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.com0tag:blogger.com,1999:blog-6901494391959828204.post-91594985862954980542013-08-21T18:50:00.002-04:002013-08-21T18:50:12.067-04:00Hadoop 3.0.0 maven repository<div dir="ltr" style="text-align: left;" trbidi="on">
Recent maven hadoop artifacts are pretty hard to come by. The central repository contains stable and 2.0.0-alpha releases, CDH repositories have 2.0.X releases, and the apache repository has 3.X snapshots. That means if you want 2.3.X or 3.X functionality, you're either stuck pulling in snapshots or building/hosting your own releases.<br />
<br />
The apache snapshots are problematic because individual build snapshots don't appear to be retained for very long. Building/hosting your own artifacts seems like a pain. Hopefully, this is a temporary issue until hadoop 3.X is released. Until then, <a href="https://code.google.com/p/rrd-hadoop-maven/">here's a maven repository</a> that has (unofficial) 3.0.0 release artifacts with source jars.<br />
<br />
It is pretty easy to put in pretty much any hadoop version into the repository. Visit the <a href="https://code.google.com/p/rrd-hadoop-maven/">project page</a> or shoot me a email to request one!</div>
Eugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.com0tag:blogger.com,1999:blog-6901494391959828204.post-55106660785599533932011-09-09T00:00:00.002-04:002011-09-09T00:09:04.507-04:00First Project in Central Maven Repository - spring-event-router<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgow-mq88c3YEvurJPmzW-_KlAOnAp8ujWWBjOLLZk_zF-trKuDP7tQgRdVR4YHGydSkq26RvTu7Ttil3vmjQ-BSfS0iJTSf28eigqML7rR1Wv09GUw6sgzbTVwXECL3pSIygZQ5Bfjobo/s1600/sonatype.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgow-mq88c3YEvurJPmzW-_KlAOnAp8ujWWBjOLLZk_zF-trKuDP7tQgRdVR4YHGydSkq26RvTu7Ttil3vmjQ-BSfS0iJTSf28eigqML7rR1Wv09GUw6sgzbTVwXECL3pSIygZQ5Bfjobo/s1600/sonatype.png" /></a>I've started a few open source java projects built with maven before, but have always ended up using a private repository to host binaries. One project of note was the CampusEAI portlet-archetype. Though under a GPLv3 licence, the CampusEAI repository was not publicly accessible until very recently. I am delighted that CampusEAI appears to have opened up their previously closed maven repository to the world. The CampusEAI portlet-archetype is an exciting project that deserves a post of its own and is now publicly available at <a href="http://svn.campuseai.org/site/portlet-archetype/">http://svn.campuseai.org/site/portlet-archetype/</a><br />
<br />
Unfortunately, the CampusEAI repository has not been publicly accessible for almost a year after I left the company. Noticing this, I have committed to publishing any future OSS Java work into the central maven repository. <br />
<br />
I've been working a bit with Spring Framework ApplicationEvents at work and thought it would be neat to write a simple dispatch mechanism by which listeners could subscribe to specific types of events without tons of instanceof operations. I saw a couple of posts on velocityreviews that contained snippets of code tackling similar issues. There's even a google code proejct over at <a href="http://code.google.com/p/spring-custom-annotations/">http://code.google.com/p/spring-custom-annotations/</a> that attempts to solve a similar problem with their "@EventListener" annotation. That project appears to no longer be maintained and has some warnings against usage in production code. In light of this, I decided to hack up some code myself and try out google code's new git source control as well as using Sonatype to publish my first artifacts into the Central Maven repository.<br />
<br />
I put together a tiny library called "spring-event-router" hosted over at <a href="http://code.google.com/p/spring-event-router/">http://code.google.com/p/spring-event-router/</a> and followed the <a href="https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide">Sonatype OSS Maven Repository Usage Guide</a> to try and publish my binaries to the Central Maven Repository. Setting up a project with Sonatype was a (necessarily) manual process but it only took around 24h to get my first binaries into the repository. The gist of the ordeal is creating a JIRA issue and having Sonatype review your project to validate some requirements before granting you the ability to stage and publish your artifact. Once your artifact has been published, a secondary review is performed; upon completion any releases into the Sonatype repository are synced with Central on an hourly basis without further Sonatype oversight.<br />
<br />
Though admittedly a very simplistic project, I was very happy with the ease of being able to use "mvn release:prepare; mvn release:perform" to publish artifacts into the central maven repository. The binaries are available <a href="http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.googlecode.spring-event-router%22">here</a> and should resolve as valid dependencies for any maven project without the need of a custom <repositories> section! </repositories>Eugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.com0tag:blogger.com,1999:blog-6901494391959828204.post-4426484460257820622010-08-19T01:25:00.001-04:002011-09-09T00:01:49.734-04:00A first stab at an IntelliJ plugin<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1moiMb8lp6mh8ZA7pWgeLVl5UD9Fp787iatZ1w_fjloCY7oQdEG_w5KAX0YLx7NZS6KbLb5wFOMq4f3elg-JsOqtYsNg9XYki0mvIv48Irm9ZybsAJTF4H-UUvSk_IqjnszZQOS_-88Y/s1600/idea.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1moiMb8lp6mh8ZA7pWgeLVl5UD9Fp787iatZ1w_fjloCY7oQdEG_w5KAX0YLx7NZS6KbLb5wFOMq4f3elg-JsOqtYsNg9XYki0mvIv48Irm9ZybsAJTF4H-UUvSk_IqjnszZQOS_-88Y/s200/idea.png" width="148" /></a>While I'm not the biggest fan of IntelliJ's IDEA, I have been using it an awful lot lately. The IDE definitely has some neat features such as their Live Templates. One can get away with all kinds of tricks using the Live Template stuff; but not what I wanted.<br />
<br />
What I really wanted was an added "Generator" for generating Chained setter methods (i.e. public T setF(F f){this.f=f;return this;})<br />
<br />
I've spent some time working on eclipse plugins (about five years ago) so I figured I'd check out IDEA's plugin API. Not having high expectations, I was pleasantly surprised and managed to actually knock out a plugin that does exactly what I wanted in just a few hours. The API documentation appears scarce but luckily there seem to be quite a few open-source plugins out there. Browsing through a few of these made comprehending the API a breeze (granted - I am doing something extremely simple here). The <a href="http://www.jetbrains.com/idea/documentation/howto_03.html">"Basics of Plugin Development"</a> document was also pretty nifty.<br />
<br />
IntelliJ provides a neat web interface you can use to upload plugins, so I've uploaded my plugin (<a href="http://plugins.intellij.net/plugin/?idea&id=5049">generate-chained-accessors</a>) and put it up on<a href="http://code.google.com/p/intellij-idea-generate-chained-accessors/"> google code</a>. It was pretty neat to see the plugin appear as an available plugin in the IDE almost immediately after it was uploaded to IntelliJ's website.Eugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.com4tag:blogger.com,1999:blog-6901494391959828204.post-9984645964908660682010-03-29T13:35:00.000-04:002010-03-29T20:22:44.287-04:00My attempt at Spring MVC custom annotationsWhile working on a simple project using SpringMVC, I stumbled upon the need to access a request or session attribute directly from within a controller method. I needed to bypass the binder and just access a request attribute set by a filter. This is obviously easy enough to do:<br /><pre name="code" class="Java"><br /> @RequestMapping<br /> public String view(WebRequest request){<br /> ...<br /> request.getAttribute("someAttribute", WebRequest.SCOPE_REQUEST);<br /> ...<br /> }<br /></pre><br />Given modern mocking frameworks like <a href="http://mockito.org">Mockito</a> and spring's own test libraries, it's easy enough to mock a WebRequest or even an HttpServletRequest. But I am pedantic, so I decided to see if I could create my own @RequestAttribute annotation instead! Ideally, I figured I'd be able to create a new annotation representing new behaviour without touching any of the spring source code. <br /><br />An initial cursory look over <a href="https://fisheye.springsource.org/browse/spring-framework/tags/spring-framework-3.0.1.RELEASE/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java?r=HEAD">AnnotationMethodHandlerAdapter</a> did not reveal any clean hooks, so I decided to go with an aspect.<br /><br /><h4> First Approach - Aspects </h4><br /><br />At first, I tried creating a pointcut around <a href="https://fisheye.springsource.org/browse/spring-framework/tags/spring-framework-3.0.1.RELEASE/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodInvoker.java?r=3011#l176">HandlerMethodInvoker#resolveHandlerArguments</a>. At this point I discussed my plan with coworker and friend <a href="http://www.0835648327.co.za/">Martin Snyman</a>, who quickly pointed out that it might be simpler to write the pointcut to intercept @RequestMapping annotated controller classes instead.<br /><br />Starting out, my original pointcut looked like this:<br /><pre name="code" class="Java"><br />@Around("execution(@org.springframework.web.bind.annotation.RequestMapping * *(..))")<br /></pre><br />This worked well enough, but it created unncessary proxies. The pointcut picked up the execution of all methods annotated with @RequestMapping - or worse.<br /><br />What I really needed was to pick up execution of all methods annotated with @RequestMapping that had at least one parameter annotated with my special annotation - "@RequestAttribute". This turned out to be difficult. I could not for the life of me figure out how to write a pointcut that picked up annotated parameters rather than matching annotations on the actual classes of passed parameters. After a couple of stabs during the weekend, I found a <a href="http://andrewclement.blogspot.com/2009/02/aspectj-advising-methods-with-parameter.html">blog post</a> that discussed the issue I was facing in some detail. With that, I was able to write the following pointcut:<br /><pre name="code" class="Java"><br />@Around("execution(@org.springframework.web.bind.annotation.RequestMapping * *.*(..,@o.c.RequestAttribute (*),..))")<br /></pre><br />I wrote a supporting interface to allow my aspect to support any number of annotations:<br /><pre name="code" class="Java"><br />public interface ArgumentModifyingAnnotationBehavior<T extends Annotation> { <br /> public Object getArgumentValue(Object argumentValue, T annotation);<br />}<br /></pre><br />The actual aspect then looked something like this:<br /><pre name="code" class="Java"><br />protected final Map<Class<Annotation>, ArgumentModifyingAnnotationBehavior<Annotation>> annotationRegistry = new ConcurrentHashMap<Class<Annotation>, ArgumentModifyingAnnotationBehavior<Annotation>>();<br />...<br /> @Around("execution(@org.springframework.web.bind.annotation.RequestMapping * *.*(..,@o.c.RequestAttribute (*),..))")<br /> private Object resolveHandlerArguments(ProceedingJoinPoint pjp)<br /> throws Throwable {<br /> MethodSignature sig = (MethodSignature) pjp.getSignature();<br /> Annotation[][] annotations = sig.getMethod().getParameterAnnotations();<br /> Object[] arguments = pjp.getArgs();<br /> if (annotations != null) {<br /> /* iterate arguments */<br /> for (int argumentIndex = 0; argumentIndex < annotations.length; argumentIndex++) {<br /> Annotation[] argumentAnnotations = annotations[argumentIndex];<br /> if (argumentAnnotations != null) {<br /> for (int annoationIndex = 0; annoationIndex < argumentAnnotations.length; annoationIndex++) {<br /> Annotation argumentAnnotation = argumentAnnotations[annoationIndex];<br /> ArgumentModifyingAnnotationBehavior<Annotation> behavior = annotationRegistry<br /> .get(argumentAnnotation.annotationType());<br /> if (behavior != null) {<br /> arguments[argumentIndex] = behavior<br /> .getArgumentValue(arguments[argumentIndex],<br /> argumentAnnotation);<br /> }<br /> }<br /> }<br /> }<br /> } <br /> return pjp.proceed(arguments);<br /> }<br /></pre><br />I was very proud of myself. Then disaster struck... <br /><pre name="code" class="Java"><br />@RequestMapping<br />public String view(@RequestAttribute("stringAttribute") String stringAttribute){...<br /></pre><br />worked like a champ.<br /><pre name="code" class="Java"><br />@RequestMapping<br />public String view(@RequestAttribute("objectAttribute") java.util.Map objectAttribute){...<br /></pre><br />however, grenaded. My annotation worked great with concrete types but blew up when it was used to annotate interfaces or abstract classes. <br /><br /><h4> Second Approach - WebArgumentResolvers </h4><br /><br />Debugging revealed that <a href="https://fisheye.springsource.org/browse/spring-framework/tags/spring-framework-3.0.1.RELEASE/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodInvoker.java?r=3011#l293">HandlerMethodInvoker</a> was attempting to resolve "objectAttribute" to a model attribute and actually attempted to instantiate java.util.Map.<br /><br />Debugging also revealed the curious new <a href="https://fisheye.springsource.org/browse/spring-framework/tags/spring-framework-3.0.1.RELEASE/org.springframework.web/src/main/java/org/springframework/web/bind/support/WebArgumentResolver.java?r=HEAD">WebArgumentResolver</a> class. By this point, I've spent hours of my time writing and debugging my awesome aspect only to find <a href="https://fisheye.springsource.org/browse/spring-framework/tags/spring-framework-3.0.1.RELEASE/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodInvoker.java?r=3011#l777"> that HandlerMethodInvoker actually *did* have a hook for allowing custom behaviour using a WebArgumentResolvers</a>! <br /><br />A little bit more digging revealed that one can actually register any number of WebArgumentResolvers with the <a href="https://fisheye.springsource.org/browse/spring-framework/tags/spring-framework-3.0.1.RELEASE/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java?r=HEAD">AnnotationMethodHandlerAdapter</a>, which would pass these on through to the <a href="https://fisheye.springsource.org/browse/spring-framework/tags/spring-framework-3.0.1.RELEASE/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodInvoker.java?r=3011">HandlerMethodInvoker</a><br /><br />After 8+ hours of screwing around with my Aspect, I found I could actually achieve what I needed to do without the creation of any proxies with this:<br /><pre name="code" class="Java"><br />public class RequestAttributeCustomArgumentResolver implements WebArgumentResolver {<br /> public static @interface RequestAttribute {<br /> String value() default "";<br /> }<br /> public Object resolveArgument(MethodParameter methodParameter,<br /> NativeWebRequest webRequest) throws Exception { <br /> RequestAttribute annotation=methodParameter.getParameterAnnotation(RequestAttribute.class);<br /> if(annotation!=null){<br /> return webRequest.getAttribute(annotation.value(),WebRequest.SCOPE_REQUEST);<br /> }else{<br /> return UNRESOLVED;<br /> }<br /> } <br />}<br /></pre><br />and the following in the applciation context XML:<br /><pre name="code" class="Xml"><br /> <bean id="handlerAdapter"<br /> class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <br /> <property name="customArgumentResolvers"><br /> <list><br /> <bean class="org.campuseai.spring.webmvc.annotation.RequestAttributeCustomArgumentResolver"/><br /> </list><br /> </property><br /> </bean><br /></pre><br />Ouch. Googling "WebArgumentResolver" also resulted in <a href="http://karthikg.wordpress.com/2009/11/08/learn-to-customize-spring-mvc-controller-method-arguments/">this</a> blog post which does something similar to what I attempted to do.Eugene Rachitskiyhttp://www.blogger.com/profile/14364996042013063175noreply@blogger.com0