00:19:00 video length
Bio Dr Ben Alex is a Principal Software Engineer with SpringSource, and has been working professionally in software since 1995. Ben founded the Spring Security project in 2003 and led its development into a popular, open-source security framework. More recently Ben founded and serves as lead of the Spring Roo and Spring Shell projects.
SpringOne 2GX is an annual event; it includes a technical exploration of the Spring ecosystem along with the latest developments in the Groovy/Grails space. As a participant, you will have the opportunity to attend two great events at one venue. Whether you're a Spring enthusiast, Tomcat user, Groovy/Grails fan, or just interested in open source development, you'll find valuable content in sessions presented here.
Spring Roo is a new product that we've created at SpringSource to make it easier to build Java based applications. The way it works is it provides a console text based user interface where people can interact with it. The interface also sits in the background and keeps an eye on what the user is doing in their preferred IDE or text editor and makes changes to files as necessary. It essentially automates all of the common tasks that you have when you are building Java applications, so the user doesn't have to do that themselves. So, it's really about productivity and it's productivity for Java developers.
It's similar to tools like Grails, in that both Grails and Roo focus on productivity, so there is a lot of productivity focus at SpringSource. The whole Spring theme, the whole time through the history of Spring, has been power and simplicity and Grails and Roo both continue that theme. The reason why we have both tools is because Grails provides a solution for the Groovy programmers. Many people prefer to work in a dynamic language environment and for that we have first class support for Groovy - we've done a lot of work on improving Groovy tooling and things like STS, SpringSource Tool Suite, and we have Roo for the Java programmers, so people who prefer a static typed language system can head off and use Roo and they'll find they get similar productivity benefits as if they were using something like Grails in Groovy.
They work differently - Roo works entirely at development time, so that means Roo will create files for you or maintain files for you in a very elegant way, sits in the background, does it automatically, very hands off by default. You can use Roo in a directory and it won't change any of your project files unless you ask it to. Grails, on the other hand, because it uses dynamic language, it operates more at Runtime. So it's a little bit like the Spring Framework, where it provides some improvements and some features for you, as part of your Runtime, whereas Roo just operates at development time alone.
The Roo Shell provides an environment in which we can host a series of add-ons. The real power of Roo comes from the add-on infrastructure. Of course, there is some core infrastructure, such as file monitoring and meta data management and type introspection and those IDE like services that are necessary to build sophisticated add-ons, but the majority of the focus of the Shell is to host add-ons in a convenient way. That's the first part of the Shell.
The second part of the Shell is to provide a user interface that developers can actually interact with, so we focused extensively on usability in the Roo Shell. As we were talking about earlier, there is a difference between an expressible user interface, a learnable user interface and a concise user interface. So we've tried to balance those design requirements of text based user interfaces to give something that's extremely usable.
In Roo, you can do things like press the tab key at any time and it will complete the command for you. You can type "Hint" and press "Enter" and it will tell you what the next step is. It will automatically figure out things like what is the command likely to be affecting in that, if I don't bother specifying which file I want to edit, it will automatically assume the file I want to edit is the last file I worked with. It takes all of these assumptions, which makes it a very natural experience to develop with. When people see demos of it or try it out themselves, they quickly say "I really love the Roo Shell because it makes it so easy to build the application."
Yes. There are some considerations that you'd need to deal with if you wanted to use it on the existing code base, but in principle you can. You can change into a directory that holds your current Java based project, you can type "Roo" and press "Enter" and Roo will do absolutely nothing to your project, it will just sit there, running in the background and waiting for you to ask it to do something. If your project has adopted a typical Maven style directory layout, Roo will automatically be able to read the Java source code and understand what that means, then you'll be able to start applying the Roo specific annotations within your source code.
When Roo sees one or more annotations in your source code, it will then automatically respond to those and create the necessary files or maintain the necessary files. You can also type Roo commands at the Shell prompt and the Shell prompt will makes changes to your files, as necessary. It's very similar to an IDE - if you don't run it, nothing happens, your project continues to work. If you forget to load Roo up while you are editing your files, that's no problem, you just reload Roo when you're ready and Roo will discover what's happened since it was last loaded.
Roo is a combination between an active and a passive code generator. We've all used passive code generators when we've been using tools like Eclipse, that is when we right-click and then we generate getters and setters and we tick all the boxes and we click "OK" and then miraculously we get getters and setters. If you think about when you do that, though, often you'll find you run into this problem when if you say delete a field, the corresponding accessor or mutator will now be in error. The same thing if you generate a toString() method. If you add a new field, the toString() method won't be modified to include the new field and so on.
The problem with passive code generation is that it doesn't maintain the code, you are expected to do that yourself and most of us probably just go and delete the method and then regenerate it, which is just effort that you shouldn't have to go through the trouble of doing. An active generator, on the other hand, works automatically. It uses some sort of control data to figure out what it should do every time it's run. Roo is a hybrid generator and the reason it is hybrid is because we nominate for certain types of files it will be a passive generator and for other types of files it will be an active generator. So we take the best of both worlds. If you consider a Java file, we will never touch a Java file except in direct response to a user request.
If you use the Roo Shell, and you say "Please edit this Java file", Roo will edit that Java file at that moment in time. It will never touch the Java file again. On the other hand, there are certain other types of files, like JSPX files or AspectJ inter-type declarations - Roo will automatically maintain those. The AspectJ inter-type declarations are how Roo approaches its code generation. Unlike most code generators where there'll be a directory where it generates lots of code, Roo will generate AspectJ ITDs.
ITDs are like introductions or mix-ins and the way they work is you define members in the ITDs and they are automatically compiled into the final class file. As a result, you might have 4 pieces of source code - one a Java file and 3 AJ ITD files, members are in all of the 4 files. By the time the compiler has finished, all of the members from all of the 4 files are in the .class file. This is how we achieve separation of concern with Roo and this model is terrific, because it lets us do version upgrades automatically. It saves us having to do anything fragile, like having a look inside the .Java file, figuring out what Roo is looking after, figuring out what you are looking after, carefully merging changes.
Take the toString() method - if you are going to provide an active generator for a toString() method, you'd have to differentiate between "Did the user deliberately delete that field from the toString() - because they didn't want it in the toString() - or did the code generator just not remember there was a toString() field and therefore I have to edit the method to add the toString() field?" With the technique we've used in Roo, we know that we generated the entire toString() method, because it's in a separate file, so we know that we control that method.
One of the nice things about Roo is you can at any time step back and take control of whatever you like. The way you take control is you just move the method into your Java file. If you don't like the way Roo is doing a toString() and you'd like to customize the toString(), there are various ways you can use Roo and tell it exactly what you'd like the toString() to be, but the easiest way simply is to copy the toString() method that Roo's created, put it in your .Java file, Roo will automatically stop making a toString() method for you and remove the toString() related AspectJ ITD. It's a very natural development cycle - you just do whatever you like and Roo sits in the background and takes care of the things you don't want to bother doing yourself.
6. Roo's use of inter-type declarations reminds me of approaches that are used in dynamically typed languages with the mix-ins where you can basically apply it to an object - I guess - at Runtime. How does this compare? Given that Java is a statically typed language, how does this work?
It's interesting the way we've approached the inter-type declarations and used them as a code generation output artifact. I'd say it's different from a dynamic language in that this all happens at compile time. One of the most critical things about Roo is that you have no lock-in to Roo, you can remove Roo at any time from your application. I did some demonstrations at SpringOne and I created a Roo project and then we removed Roo and the way you can remove Roo is use a feature within Eclipse known as push in refactoring and what this does is it moves the contents of all your AJ ITD files into the corresponding .Java files.
By doing this, a user can get rid of Roo in about 4 key strokes and there's no evidence that they ever used Roo in their project - you have this lock-in avoidance. I'd say it's a little bit different from a dynamically typed language, because everything happens at compile time. That also gives us some performance advantages, so we don't have any memory consumption at Runtime, by the Roo system or the fact that you used Roo, you don't have any memory performance or storage costs by the fact that you've used Roo - everything's very efficiently managed. Another consideration is that, as we improve Roo and we bring out new versions of Roo, we make various optimizations to the way that we generate the code.
If you take the toString(), for example, when we brought out Roo originally, we didn't properly handle things like primitive fields, so we weren't toStringing those things properly. We fixed the bug and then automatically because the new version came out, it was able to fix all the AspectJ ITDs, which did toString()s. You get these sorts of improvements that we make at SpringSource to the actual Roo system and you get this for free automatically the next time you upgrade Roo and use the new version of Roo. It will automatically fix all of the generated code to reflect the best practice, latest most efficient way that we can approach a particular code generation task.
The Spring ecosystem has improved considerably over the many years that I've been involved in Spring and Spring has existed. Spring was founded in 2001 - 2002 - 2003, depending on whether you look at the book with Open Source Project or some derivative thereof. In that time, the approach to Java has changed a lot if you are building Enterprise applications. We've gone from essentially providing an alternative to entity beans and session beans to essentially solving the whole stack of problems of how you build an Enterprise app. Along the way, different design patterns have emerged and we've continued to improve them.
The work at SpringSource has also lead us to design review thousands of applications with so many clients across the world it makes your eyes spin and we've seen lots of things that people do well, some things that people could improve. We've been able to encapsulate all of that knowledge into our productivity tools. If you use any of our productivity tools and they include things like SpringSource Tools Suite or Grails or Roo, you get the benefit of that acquired learning and knowledge. Another benefit of using Roo is that you get the latest version of all of the Spring portfolio projects.
A subtle benefit that's not immediately apparent of using Roo is that you end up with team wide and organization wide consistent projects. If you think about a team where you've got multiple people, if they are all trying to follow some sort of architectural design patterns and they are doing it by hand, there is going to be some level of variance from one individual programmer to the next with their different coding styles and preferences. One of the benefits of using something like Roo is that we automatically generate large parts of your application, which can be generated. You still have to write business logic; this doesn't replace programming - make no mistake about it!
Certainly, for the parts that are the tedium that we've all come to expect, with getters and setters and toString()s and creating a first pass of your JSP files and editing your Maven POM and setting up your JPA properly and putting the required no argument constructor in there and providing a version field and all the rest of the stuff that we take for granted and we just do every day, just out of sheer habit, Roo takes care of all those things for you and in doing so not only gives you the best practices for tackling those problems, but it also does it in an extremely consistent way, because a system does it as opposed to an individual does it. As I mentioned earlier, as we improve Roo and we bring out new versions of Roo, those best practices will slowly emerge and be improved and the implementation techniques we use will be improved and people who use Roo will get that all for free.
Absolutely. It's very easy to build add-ons for Roo. We have a comprehensive add-on architecture, so users of Roo can install add-ons that are written by themselves or written by other people. We are very careful to differentiate between what is in the Roo distribution, which is essentially comprised of what we call core add-ons and the core infrastructure. Everything else is a third party add-on. You can install third party add-ons very easily.
To create a third party add-on is also very easy. It takes just one command in Roo - the command is "project -templateRooaddon". Once you press "Enter", you end up with a Roo add-on and then you just have to customize it to do whatever it is that you want it to do. After that, you can then use the perform assembly command and after the perform assembly command is finished, you've got a zip file, which is therefore compatible with being installed into other people's Roo installations. So it's extremely easy to write an add-on. I'm going to be demonstrating at SpringOne how to write an add-on on stage in about 40 minutes. It takes no time at all.
Spring Shell represents the part of Roo that provides the text based user interface. What we've done is we built Spring Roo initially and it was a prototype and we included some Shell behaviors in there to demonstrate the usability objectives and also to provide a hosted process management system. The process management system deals with concurrency and file system management and add-on execution, etc. What we've done is had a look at the parts of the Spring Shell which would be generalized and usable by other people, and that's going to be put into a separate project, so that other people who are building Java based systems can take advantage of the Roo Shell and the usability benefits that the Roo Shell provides they can use on their own.
People sometimes ask me "Would you not just use something like Bash? Or, my favorite, the Fish Shell?" The answer to that is that not everybody has a Linux or an Apple Computer, some people are on Windows. The thing is sometimes you want to embed a shell in the JVM, so, if you consider things like our server products, TC server and DM server, they both would find having a shell quite useful because that way they can make it, for example, accessible over SSH or telnet or something like that. You can connect into the running JVM and you can control your Tomcat TC server, DM server type instance, you can get the commands. System administrators love shells, they can press Tab, they can do sophisticated things.
The work that I've been doing recently is on LALR grammars and making the Shell even more robust than what we have in Roo at the moment. I've got a lot of work that I've still got left to do in that regard, but I'm very excited about what we're going to be able to do with the Spring Shell and where it's going to take us. It should be out next year, we're probably mid way through. End of first quarter, partially into second quarter of 2010.
Spring Security provides a few key functional areas. The first is authentication, so you can either use the authentication modules which Spring Security offers or you can use your existing authentication system and have Spring Security recognize it and treat it as authoritative. Then, there is authorization. The authorization is typically in 2 key areas: one is web security, so you can intercept HTTP requests and you can decide, based on this URL path specification can you do a post to it or can you do a delete to it and so on.
There is also a method authorization. With method authorization we decide whether you can invoke a particular method. We tackle method authorization using 2 technologies - either Spring AOP, which is a proxy based approach, or with AspectJ, which can use the compile time weaving or load time weaving approaches. We have full support for the major AOP approaches used in Enterprise Java, if you want to do method authorization.
Moving on from method authorization, we have Access Control Lists. So you are able to specify different files or different entities within your system have different permission structures from other entities in your system. With just typical authorization, you are saying, "This user or this role or this script is allowed to do this operation". On the other hand, with ACL Security you are saying, "This user is allowed to do this operation to this particular instance". The ACL subsystem provides things like inheritance, so you can have a hierarchy, a little bit like a file system, so you can assign permissions at one level and they filter down to lower levels.
It also has a whole range of other features, which help you build applications in the security space, so for example, it does session concurrency support to make sure that a certain person's not logged in more than once and those sorts of things. It's got a very extensive list. Back in 2003, when I started Acegi Security, it had about 20 types. It started out very small and these days it's close to 400 types, so it's got a considerable number of capability areas.
If you look at the history of Spring Security, what used to be Acegi Security, version 1.0 of Acegi Security was basically focused on getting an application secured and it provided most of the core original features back in the Acegi Security days. It was very difficult to use though as it took couple of hundred lines to do a simple configuration. With Spring Security 2.0, when we brought that out, we focused on usability and some refactoring work, so we just made it considerably easier to use and your 150 - 200 lines of XML reduced to only about 10 - 12 for a small basic application.
With Spring Security 3.0, we've made further improvements to usability, we've also primarily focused on supporting the latest versions of Spring. If you have a look at Spring Framework version 3.0, it has support for something called Spring Expression Languages or SPEL, as we call it. Acegi Security or Spring Security - I should say Spring Security 3.0 - supports SPEL. You are able to use expressions within all of your authorization logic, so you are able to say, "If this person has this role or this role or it's before this time of the day, and it's from this IP address, then they are authorized to go in".
You can write considerably more sophisticated expressions declaratively rather than having to, in the old Acegi or Spring Security 2.0 days, write something like an access decision voter. It avoids having to write a class to provide more sophisticated authorization expression logic. You can just do it declaratively now. It also has much better annotations, so you can do things like express filtering rules with the ACL support, you can remove elements from collections and that type of thing. These can also be expressed via expressions, so it's much easier to use and build more complex applications.