Archive for the ‘Java’ tag
With Grape, Groovy Is On Par with Native Scripting Languages
If you haven’t heard, the latest version of Groovy was released this week and included with it, among many other great features, was Grape (Groovy Advanced Packaging Engine). Grape is an annotation based dependency management system that provides functionality similar to that of Maven and Ivy with one clear advantage, namely, no build file.
If Grape doesn’t use a build file, how does it know what dependencies are necessary to run the code? Does it figure it out for you on the fly? Unfortunately, it is not that smart (yet), perhaps the next release. If it doesn’t figure it out for you, then how do you specify your dependencies? You configure your dependencies by using the@Grapes or @Grab annotations.
What is so good about being able to configure your dependencies via annotations?
If you are working with Groovy scripts, it frees you up from having to worry about dependency management and allows you to focus more on what the script needs to do much like when working with other scripting languages like Ruby or Perl. In order to clearly demonstrate the advantages of Grape, lets walk through an example.
The problem
Trying to keep up with my ever changing IP address after switching ISP’s earlier this year. There are several services running at my home that I need access to on a daily basis. If my IP changes over night, after a brown out, or for some other reason, I need to know about it asap.
In order to keep up with my IP address, I wrote a set of scripts that perform the following:
- Obtains the current IP address of the server where it is running
- Looks up the most recent IP address of the server in a log file
- If the current IP address is different that the most recent IP address:
- Updates the log file with the current IP address
- Send the new IP address in a customizable email to a configurable address
- If the IP address’s are the same, it does nothing.
The Solution
It took a total of three Groovy classes/scripts to solve this problem. We are not going to get in to the details of the solution because I want to stay focused on Grape.
You can find all of the code discussed in this post on github. Please feel free to download and use it. Feedback is welcome as well.
This simple Groovy class first connects to a mail server, and then sends the change of address message.
import javax.mail.Session
import javax.mail.Message
import javax.mail.internet.MimeMessage
import javax.mail.internet.InternetAddress
@Grapes([
@Grab(group = 'javax.activation', module = 'activation', version = '1.1'),
@Grab(group = 'javax.mail', module = 'mail', version = '1.4')
])
class Mailer {
static def s_config = new ConfigSlurper("message").parse(new File('MailProperties.groovy').toURL())
static def deliverIpAddressChangeMessage(ipAddress) {
def subject = "IP Address Changed to ${ipAddress}"
def message = "IP Address changed to ${ipAddress}.\nPlease update your configurations."
sendMail("${s_config.message.to}".toString(), "${s_config.message.from}".toString(), subject, message)
}
//...
}
Download Source: Mailer.groovy
The most interesting things to pay attention to are:
- The
@Grapesblock after all of the imports, you can see this groovy class depends on javax.activation and javax.mail jars. - Thanks to Grapes, you can compile this class simply by invoking
groovyc Mailer.groovyas opposed to having to configure either Maven, Gant, Ant, or some other build tool to manage the dependencies and classpath for you. - What’s the big deal? Read more to find out!
This next code snipped represents the “main” entry point of my solution. It simply obtains the current IP address of the machine it is running on, checks the current address against the most recent known address stored in a log file, and then uses the previous class to send an email if the IP address has changed.
#!/usr/bin/env groovy
// IP Address Regex http://www.regular-expressions.info/examples.html
currentIp = ("http://whatsmyip.us/".toURL().text =~ /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/)[0]
println currentIp
def ipLog = new File("ip-log.txt")
recentIp = ipLog.readLines().last().tokenize(",").last().trim()
if (currentIp != recentIp) {
Mailer.deliverIpAddressChangeMessage currentIp
println "IP Address has changed, it is now: ${currentIp}. Sending Message."
ipLog << "${new Date()}, ${currentIp}\n"
}
Download Source: whatsMyIp.groovy
The most interesting thing to pay attention to in this script is:
- The
#!/usr/bin/env groovyon the first line on the script. - This line enables the script to be called directly from the command line like:
./whatsMyIp.groovyinstead ofgroovy whatsMyIp.groovy
The Big Deal!
If Grape didn’t exist the only way to invoke this script would be to invoke it with a build tool such as Maven, GAnt, or some other. If a build tool didn’t suit you then you would have to invoke groovy -classpath=/path/activation.jar... and manage the dependencies there. Both of these solutions work fine, but are clunky.
If you were to solve this problem using a language such as Ruby, you would not have to worry about dependency management since Ruby is so closely integrated with the OS. You would simply run gem install some gem, and this would install the dependencies at the OS level. Thus allowing you to focus on your script and letting the Ruby runtime focus on the dependencies. Invoking ./someScript.rb is common in Ruby.
Grape gives Groovy scripts the same clean dependency abstraction. It is possible to invoke ./whatsMyIp.groovy without having to worry about any dependency management. Once the groovy runtime comes across the Grape annotations, it loads the dependencies on demand freeing the Groovy script from having to be wrapped with a dependency management layer.
This is a huge deal because now simple Groovy scripts can leverage the entire Java ecosystem from the command line without having to wrap the invocation with a build tool. Groovy Scripts are now clean, simple, and easy. I hope this inspires you to go out and convert some Ruby or Perl script to Groovy.
Going Functional with Scala
Lately it seems like functional programming has been the talk of the town, the new (old) paradigm that is making a comeback in a major way. For a while, I resisted the urge to follow the paradigm de jour, being the hard core OO guy that I am, but now it is clear to me that it is more than just hype. There are many reasons functional programming makes sense as a paradigm for developing software today, but the one that I am most interested in is the fact that it handles concurrency so well, thus providing us the building blocks to develop extremely scalable applications.
FP (Functional Programming) has been on my mind for a while. The seed was placed there in late 2007 by the Java Posse listening to their interview with Martin Odersky. They were not talking about FP per se, but more about a specific JVM language called Scala (pronounced skah-lah not scale-la). Scala is not a pure functional language, it is actually a fusion between functional and object oriented programming. It brings together the best of both worlds. My exposure to Scala did not end there, as I got another huge dose at Java One 2008. Two of my favorite sessions there were either on Scala, or Scala was a major discussion point.
The first session was the Script Bowl. This session was not specifically about Scala, it was more of a JVM scripting language battle, and in the end JRuby was crowned king by the audience. In my mind, Scala was the clear winner, because of the simple, yet elegant and powerfull concurrency demonstrated. The presenter wrote what looked like a relatively simple program, and it was capable of indexing tons of RSS feed dumps in real time on a typical multi-core laptop computer. I remember thinking to my self, wow, it would take me a lot more time and effort to write a similar program in Java, and it probably wouldn’t have the same level of scalability as the one demonstrated. The Scala code was able to fully utilize the multi-core processors it was running on.
The second session was on Scala presented by the father of Scala him self Martin Odersky. During that session I was wowed again with some of Scala’s features like it:
- is scalable because it works for very small and very large systems.
- “is the Java programming language of the future.”
- is object oriented, functional, and a scripting language.
- leverages Actor’s as the primary concurrency construct.
- fits seamlessly in to a Java environment.
- is a composition language, as it adds the notion of Traits.
- has an updated type system supporting type inference.
After those two sessions, I headed over to the Java One bookstore to check out the Beta version of Programming in Scala. I was impressed, but couldn’t help thinking, is Scala for me? Can I use it at work? Is it viable in the enterprise?
Fast forward 7 months to today, and let me answer my own questions with one word: yes!
- Is it for me? Yes, because Scala is not only something new, it is something advanced, because it was written in a no compromise academic environment. If nothing else it is a great way to broaden my horizons as a programmer.
- Can I use this at work? Yes, Scala code compiles down to Java byte code, so theoretically, if I was very evil, I could write all my code at work in Scala, run Scalac on it, and add the class files to the application, and no one would be any the wiser. Will I do that? No way, I am simply trying to illustrate a point that Scala is totally compatible with any existing Java environment.
- Is it viable in the enterprise? Yes, with its advanced concurrency model, I can only imagine the type of throughput you can achieve. (Looking forward to finding out)
Now you know where my interest in Scala comes from. Hopefully after reading this post, you will be a bit curious about it as well.
Keyboard Shortcuts
Do you want to learn all of the keyboard shortcuts to your favorite Java IDE, but just don’t have time to study a cheat sheet? Are you envious of your team lead because when you peer program with them, they are able to get things done without using the mouse?
You ask your self how did they do it? Do they memorize a cheat sheet while on the Subway? Do they go home and practice coding every night? Are they gifted with great memories? Well, they may be all of these things, but you don’t have to be!
All you need to do is install a plugin called Key Promoter that is available for both Intellij and Eclipse. The way it works is every time you use your mouse to accomplish a task that can be accomplished via a keyboard shortcut, it pops up a window and lets you know. In the Intellij version, it actually keeps track of how many times you used your mouse for each action. It becomes insulting after a while if you see you used your mouse 20 times for the same action, knowing it has shown you the corresponding keyboard shortcut each time.
For more details you can find the Intellij plugin here, and the Eclipse plugin here.
Simple Security for HTTP Based RESTful Services (Part 2)
In part one of this series, we examined one potential solution that turned out to be not so good. In this post lets try to find a solution using the same design, but a better implementation.
To recap, we decided to use the simplest solution which is to add a security hash to each service call. The first approach we tried was adding the security hash to the XML payload of each service call. The conclusion was that approach was not very elegant, and actually quite ugly.
Let us now discuss a more elegant solution. Keeping the same parameters in place, namely, we want to pass the hash along with each service request, where can we place it where it will not cause the implementation to be ugly? Why don’t we try by add the Hash as a field in the Http header?
The request would look like:
PUT http://blah.com/services/someEntity/226 HTTP/1.1 Accept: text/xml Content-Type: text/xml User-Agent: Jakarta Commons-HttpClient/3.1 Host: somehost:port Hash: 53b383c67a03d23a38b6f52f4a732553 Content-Length: 380 <someEntity> <fieldOne> fieldOne </fieldOne> <fieldTwo> fieldTwo </fieldTwo> </someEntity>
As you can see, the hash has been added to the Http header (line 6). To verify the hash, we need to do create a Servlet Filter that verifies the Hash.
A very simple filter would look like:
public class VerifyHashFilter implements Filter {
public void doFilter(ServletRequest request,
ServletResponse response,FilterChain chain)
throws IOException, ServletException {
if(((HttpServletRequest)request).getHeader("HASH").equals("12345"))
chain.doFilter(request,response)
else
((HttpServletResponse)response).setStatus(401);
}
}
Then our service code implementation would change to:
@Path("/services")
public class SomeEntityServiceImpl {
@PUT
@Path("/someEntity/{id}")
@Consumes("text/xml")
public void updateSomeEntity(SomeEntity entity,
@PathParam("id") int id) {
dao.saveOrupdate(entity)
}
}
To test our service, we can use curl:
$ curl -i -H 'HASH:12345' http://localhost:9095/rest-test HTTP/1.1 200 OK Content-Type: application/xml Content-Length: 71 Server: Jetty(6.1.14) <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <someEntity> <fieldOne>fieldOne</fieldOne> <fieldTwo>fieldTwo</fieldTwo> </someEntity>
And the negative test:
$ curl -i -H 'HASH:54321' http://localhost:9095/rest-test HTTP/1.1 401 Unauthorized Content-Length: 0 Server: Jetty(6.1.14)
As you can see, the implementation code is much cleaner and reusable now. The service code can be called from anywhere within the application without having to worry about a security hash. It is safe to assume that if the code makes it as far as the service, it passed through the security filter thus making the request authorized. Having that assumption as part of the design allows you to write much more generic and reusable code.
Please keep in mind this concept is nothing new, as this solution is an over simplification of how the Spring Security module works. The value in this solution is it doesn’t have dependencies on any external frameworks. When designing this solution, that was one of the determining factors.
Next time you need to implement a quick authorization mechanism for your REST service, make sure you keep the Http header along with a Servlet filter in mind.
