Get Application Context inside Aspect from Spring MVC Servlet
After spending some time using aspects to do various cross cutting application tasks like live profiling and logging mechanisms in one of my Spring MVC web applications, I found myself wanting to use Spring’s IoC mechanism without it’s AOP implementation. Spring provides a dynamic runtime pure Java implementation of Aspects that they promote as a complement to AspectJ. It works great with all of the injected components you use as spring already uses a proxy layer to manipulate them. If you want to be able to place join points on code that isn’t managed by spring you will find yourself looking for an AspectJ weaver/compiler.
If you use Maven2 much like I do, you’ll find it quite simple to setup an AspectJ compiler/weaver. I’m using the aspectj-maven-plugin configured to attach to the compile and test-compile life cycle goals. Here is the configuration I used:
org.codehaus.mojo aspectj-maven-plugin 1.3 compile test-compile src/main/aspect true true 1.6
Getting the Application Context...
Enough with this fluffy preamble, what I wanted to do was get the application context so I could access my Hibernate managed data access object and services tier. Initially, I wanted to autowire my service and declare the class as a component that would be injected with Spring’s IoC mechanism. Unfortunately, I could not discover a method of doing so without using Spring’s proxy based runtime AOP solution. One obvious solution would be to use the XML class path context loader and specify the context file via filename and location, but this was a very brittle method that would just introduce multiple points of context file configuration (not a very good solution.).
I realized my join points where on controller actions; therefore, I always had access to the incoming HttpServletRequest object supplied by our Apache Tomcat container. With the request object I was able to get the servlet context which gave me access to both the servlet configuration parameters and a method of retrieving the Spring application context that the servlet was configured with. We used the web.xml to define spring as the dispatch servlet (following the common MVC pattern) and had our context definition split into several XML documents. By using Spring’s WebApplicationContextUtils.getRequiredWebApplicationContext() helper one can get the entire application context that the servlet is configured with.
Here is an example of retrieving a dynamic setting from a database inside of an advice annotated method that wraps around a controller action:
public String getWebSetting(String settingName, Object[] joinPointArgs) {
for(Object arg: joinPointArgs) {
if(arg instanceof HttpServletRequest) {
return ((WebSettingService)WebApplicationContextUtils.
getRequiredWebApplicationContext(
((HttpServletRequest) arg).getSession(false).getServletContext()
).getBean("webSettingService"))
.getNameValuePairedWebSettings().get(settingName);
}
}
return null;
}
@Around("xxx.yyy.profiling.ControllerRequestActionProfilerAspect.inControllers()")
public Object profileControllers(ProceedingJoinPoint pjp) throws Throwable {
String setting = getWebSetting("enable_performance_logging", pjp.getArgs());
[...]
}
@Pointcut("execution(@org.springframework.web.bind.annotation.RequestMapping * (@org.springframework.stereotype.Controller *).*(..))")
private void inControllers() {}
Setting up Netbeans 6.8 with Maven2 and SVN
For anyone new to the Netbeans IDE, like myself, you might find yourself perplexed by the fact that you can't execute any substantially large projects. Netbeans relies heavily on 3rd parties for their integration with other tools, i noticed while setting up a simple SSH tunneled SVN connection. This might be a little confusing to a new developer or someone not very familiar with the two technologies.
Let's jump into configuring this beast:
SubVersion svn+ssh://
Seeing i'm setting everything up on the new workstation my office gave me, this will be a guide for Windows 7 x64bit users.
Packages
- SilkSVN (Client Only)
- TortoiseSVN 1.6.9....
Both are quite easy to install with their standard Microsoft MSI bundles. The need for TortoiseSVN is two fold: 1. It is an awesome SVN client, and 2. It comes with TortoisePlink, which I had better luck with than the PuttyPlink base itself.
Now in the Netbeans IDE follow the menus 'Team >> Subversion >> Checkout' this will produce a dialog where you can setup your SVN repository. This example is exclusively for the svn+ssh protocol so the URL will look like: svn+ssh://servername.net/path/to/repo
The external Tunnel command will look like: TortoisePlink -l username -pw password
This assumes you have updated your windows environment variable PATH to include the bin directories of both TortoiseSVN and SilkSVN, which by default get installed to your C:\Program Files\ directory. The really nice thing about TortoisePlink is that it will not continue to ask for your password!!!! Major pain in the a** when working with the standard plink out of the box.
Maven2
This one was a little more confusing to find the solution for, but luckily it has gotten much easier thanks to the Netbeans dev team. The Netbeans team have released an update to the codehaus exec mojo SNAPSHOT that fixes the fun execution problem (https://netbeans.org/bugzilla/show_bug.cgi?id=153644).
After setup of a brand new maven 2.2.3 install, Netbeans will fail to execute any project/file that has a dependency chain over a certain length. To rectify this problem add the codaus snapshot repository to your maven 2 settings.xml as suggested in the bug report above. It will look something like:
<pluginRepositories>
<pluginRepository>
<id>s.r.c.org
<name>Codehaus SNAPSHOT repository
<url>http://snapshots.repository.codehaus.org
<layout>default
</pluginRepository>
</pluginRepositories>
Next you will need to setup your project to use the new version, luckily this is rather easy as they define the version in the execution string. Right click on your project and select properties. A dialog with a list of forms on the left should appear, select the 'Actions' button. Here you will need to go through each action that uses the exec plugin and update the Execute Goals changing the '1.1.1' string to '1.1.2-SNAPSHOT'. This data is then saved to an XML file; however, editing the XML file directly did not seem to work properly (probably because i did it while netbeans was running).
Hope this helps save some hair from getting pulled out!
Installing Xvfb on Ubuntu 9.10 (Karmic Koala)
Today I spent several hours wrestling with Xvfb on a fresh new Ubuntu 9.10 (Karmic Koala) installation. The initial stages of the install are very promising, simply running:
>> aptitude install xvfb
Seems to work its charm and successfully install the software package. Unfortunately, if you attempt to test the Xvfb using something like:
>> Xvfb :99 -ac
You will most likely see a long list of error messages, something like:
[dix] Could not init font path element /usr/share/fonts/X11/misc, removing from list! [dix] Could not init font path element /usr/share/fonts/X11/cyrillic, removing from list! [dix] Could not init font path element /usr/share/fonts/X11/100dpi/:unscaled, removing from list! [dix] Could not init font path element /usr/share/fonts/X11/75dpi/:unscaled, removing from list! [dix] Could not init font path element /usr/share/fonts/X11/Type1, removing from list! [dix] Could not init font path element /usr/share/fonts/X11/100dpi, removing from list! [dix] Could not init font path element /usr/share/fonts/X11/75dpi, removing from list! sh: /usr/bin/xkbcomp: not found (EE) Error compiling keymap (server-42) (EE) XKB: Couldn't compile keymap [config/dbus] couldn't take over org.x.config: org.freedesktop.DBus.Error.AccessDenied (Connection ":1.74" is not allowed to own the service "org.x.config.display99" due to security policies in the configuration file)
Let us tackle this mess of an automated installation...
1. xkbcomp
Try running:
>> sudo aptitude install x11-xkb-utils
This will install the xkbcomp required.
2. Missing Font Errors (unnecessary?)
The font issues, probably, do not require fixing from a functional standpoint; nonetheless, you can install them with the following command:
>> sudo aptitude install xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic
3. HAL
Apparently, some of the required components of this fake X server are within the core package of the actual X server. Try installing:
>> sudo aptitude install xserver-xorg-core
4. dbus
This last fix, is not going to work for everyone. I can use it because my intended use is on a remote server configuration not requiring any packages that depend on DBUS messaging system.
>> sudo aptitude remove dbus
These four steps enabled my 9.10 Ubuntu server to run Xvfb. I tested the xvfb-run command like:
>> xvfb-run firefox
It launches the firefox browser (if installed, if not installed it just exits) and waits for you to CTRL+C cancel it.
Android Development; the beginnings.
Google continues to out do themselves with the release of the android SDK 2.0 and the event of the new Verizon phone coming out this month. I was incredibly impressed with the developer resources available to jump right into Android development. Google's www.android.com site provides easy to understand information and tools to work with their framework. The design of the framework is one of much forethought, with their 4 component pattern application integration and code reuse will be second nature for Android developers.
In comparison to Apple's iPhone SDK, the first thing that will draw developers to Android is that it is free and cross platform. You don't need to buy a Mac or spend hours trying to do a hackish install of OSX through VMWare to get started. iPhone development has an extremely large entry blockade which pushes away any casual developers. This elitist mentality is continued with the high level of review to get an application placed in the Apple store; nevertheless, the iPhone platform is a strong performer as Apple does design and elitist marketing very very well.
Given a few years and the continued devotion of Google, the Android platform will be a top contender when considering a cell phone. Coincidentally, cellphones are likely to become much similar to todays laptops and further promote the idea of ubiquitous computing (Information Weekly - Google CEO Images Era of Mobile Supercomputers). This is the world top executives at Google predict and they are trying hard to position themselves accordingly; as such, I plan to do the same and get into mobile device development before I'm too far behind.
Considering the user base of the two platforms you'll be sure to see the geekier software developer types signing alliance with Android, while the creative and trendy aligning with iPhone. With Blackberry & Trio still commanding much of the Business sector, it will be a task of deciding the right audience for your goals to decide your development platform.
With my lack of direction at this point Android is the clear winner with its low entry requirements and open source licensing. It will be interesting to see the user base for Android as more and more phones become available.
Learning ruby and rails; why i left php and almost java
Still being relatively new to the rails framework, I figured it would be a good time to step back and reflect upon my newbee adventures and discuss some of the common hang ups I ran into.
Thinking back to the beginning, the hardest part was deciding rails was worth learning. I was a somewhat seasoned PHP developer at the time rails 1.0 came out and I would have never thought I would ever be pulled away from php for web applications.
Admittedly, my first look at the framework sparked a little interest but not enough for me to devote any amount of time dealing with it. Instead I took some of the ideas that I had heard rails was implementing and tried implementing them in PHP. It worked out ok, and I was able to create a rather verbose framework that had some of the key features that rails had developed. Then as I took a step back I realized that almost everyone in the PHP community was racing to generate Rails like MVC (Model, View, Controller) frameworks. I was amazed and disheartened slightly that my framework was nothing more than a fun side project.
Now, certainly side projects like these are great for education so I would never recommend anyone not try to mimic state of the art software design, but realize that rarely would this work be more than for your education! Anyways, i digress, the other important realization I made was the lack of unity in the PHP community.
Nothing is more frustrating (ok, mabye this is an exaggeration...) than having 10 to 20 frameworks to choose from that are nearly identical in functionality. Which one is going to lose developer interest within the next 5 years? Does one seem to have a better community than the others? Gee, framework one is great at this but fails in this other area, and the opposite for framework two! It can be a real headache dealing with these types of questions, then income the fresh and consolidated Ruby on Rails framework.
Now also during this same period of time where I spent my hours developing PHP web applications I was also employed as a Java developer at the University of Minnesota. Java and PHP are both massively popular languages and for good reason. So at this point I was comparing the three: Java, PHP, and Ruby with Rails plugins.
Dealing heavily with Java SOAP Web Services, JSP, and JSF I quickly became annoyed by the amount of work that went into my Java applications and the amount of code that was cluttering my source files. Granted Java is great because of the massive amount of tools that automatically generate code; This is the reason productivity estimates in Java can be compared closely to those in more domain specific languages like PHP.
My disappointments in Java and PHP where still not enough to make me seriously consider Ruby on Rails! Amazing, I know, but the time investment to learn it just did not provide enough expected utility. There was still a few compounding events that needed to occur to push me over the edge.
Luckily, one of them was a friend from college who seemed in love with Ruby on Rails. One of his senior projects used the framework extensively to implement user interface plans and provide some basic backing services to test against. He asked me to help out a little bit with the project and offer user test reflections. This was a big help in promoting the hype of the framework and getting me used to some of the design patterns.
The last straw was when I was working on a simple sales website for a real-estate slash car dealer agent. I was working several hours implementing simple database scripts and refactoring code so it was as DRY (Do not repeat yourself) as possible. I began to realize how much easier most of the stuff I was doing would be if I was using the Rails conventions and framework.
That brings me to an important point about the efficiency of rails. One of the big reasons Ruby on Rails is my favorite and fastest web specific languages is because of its conventions. If you are not familiar with rails at all you will be amazed by the amount of assumptions that are made that reduce the amount of code you need to write. Conventions range from database table and column naming to helper functions and RESTful routing. Of course they don't force you to follow these conventions but you better have a damn good reason not too! Now all of these magnificent design patterns that are enforced by the rails framework are not going to be described in this post because 1.) I'm not a rails guru by any means, yet... and 2.) It is beyond the scope of this article (cliche?).
When I was just beginning software development I didn't mind writing almost everything myself, after all it was a great way to learn how higher level operations where handled. Life gets shorter as you get older and the necessity becomes a driving force instead of in the moment "just cause" logic. Time is more precious and frameworks that help you get more done faster are like water sources in a barren desert.
Rails is new and the future of it is not completely transparent, which is why many companies are afraid to commit to it long term. Judging by the continued explosion in community around the project rails does indeed have a bright future and is worth any serious web developer's time. I recommend investigating the advanced features implemented by the rails development team in their latest release and at bear minimum follow the project as if your like me you'll eventually warm up to it!
