Exploring Roo's Architecture |
|

Last month we discovered how easy it is to build a fully-fledged enterprise application in just a few minutes using Spring Roo – our new productivity tool for Java developers. While many Java developers have already started evaluating Roo to help save time on their projects, I've received a lot of questions from people curious about how Roo actually works. In this blog entry I will explore Roo's architecture in depth, including its goals, alternatives prototyped, design rationale and implementation details. By the end you'll have a good understanding of what makes Roo tick and why its approach works well for Java projects.
New Roo and STS Releases
Before I get into the detail of Roo's architecture, I should briefly mention we have today released Spring Roo 1.0.0.M2. Featuring dozens of bug fixes and minor enhancements, this new release also includes:
- A very nice unit test mocking capability (written by Rod Johnson)
- Java and SQL reserved word detection (so no longer will you accidentally call a field something like "from")
- The ability to specify the particular Java version you'd like to use (of particular importance to Apple users)
- Extra Spring Web Flow configuration (so you now have a proper flow to play with)
- Automatic exposure of dynamic finders to the web tier
- Improved support for Windows users and those with non-English default locales
We've also released SpringSource Tool Suite (STS) 2.1.0.M2 since my last blog entry. The Roo support in STS continues to improve, and you can now even configure STS to point to a separately-downloaded Roo installation. This is great news for the increasing number of people writing their own Roo add-ons or simply wanting to use the latest Roo releases with STS. Other nice Roo features in STS include CTRL + R "Roo command" dispatch, an inbuilt Roo shell, extra Roo commands to execute integration tests or deployments (including to a cloud environment!) and more. I thoroughly recommend downloading STS 2.1.0.M2 if you haven't already done so.
Roo Core versus Roo Add-Ons
At its heart, Roo offers a core set of services that permit "add-os" to be used. These core services include a shell, file system manager, file system monitor, file undo capability, classpath abstraction, Abstract Syntax Tree (AST) parsing and binding, project build system interface, metadata model, process management, bootstrap and utility services. While we'll indirectly explore some of these core services later on, the vast majority of functionality that end users are interested in come from add-ons. Without any add-ons, Roo is just an elaborate console.
When you download Roo, we ship the core services plus a series of common add-ons. All of the add-ons can be identified via the "addon" keyword appearing in their JAR name. Every add-on that ships with Roo is optional and end users are free to enhance existing add-ons or create new ones. Indeed we very much welcome the community to develop and share add-ons they find useful.
Given there is a design separation between Roo's core services and the add-ons a user may wish to use, the focus of our energy for Roo 1.0.0 is on ensuring mainstream web applications can be easily and productively developed. In subsequent versions of Roo we will ship an increasingly richer array of add-ons that help users build other classes of application.
One area I've been asked frequently about is Roo's use of Maven. As noted in my last blog entry, the projects that Roo 1.0.0 creates use Maven. Because this Maven usage is implemented via an add-on, it is easy to add support for other project build systems as well. Indeed we've had many requests for Ant/Ivy support, and there is already a feature request in Jira (ROO-91) for this.
On a similar note, Roo also currently ships JPA and JSP add-ons. Both of these are pragmatic choices we made to support typical web application development in Roo 1.0.0. There is no technical reason at all preventing the development of JDBC, JDO, JSF, Velocity and FreeMarker add-ons, and we hope to see such add-ons over time.
Because this blog entry is focused on Roo's architecture, I'll conclude discussion of individual add-ons at this point. You can read my last blog entry if you'd like to learn more about how the current Roo 1.0.0 add-ons can be used to build applications. For now, let's dig a little deeper into how Roo actually works.
Roo's Design Goals
Whenever reviewing any technology, it is important to consider the design goals and objectives that influenced its architectural choices. I explored some of these goals in my original Roo blog entry, but let's revisit the topic here in a little more detail.
Most importantly, we wanted Roo to be a productivity solution for Java developers. There are many developers who prefer to (or need to) work in Java, and Java remains the most widely used programming language on the planet. Providing a first-class productivity tool to this very large group of developers represents Roo's most fundamental goal.
Second, we wanted to ensure we eliminated barriers to adopting Roo. There is no point having a great productivity tool if people aren't comfortable (or simply aren't allowed) to use it. Specifically, that meant having no lock-in (ie easy removal of Roo), no runtime portion (and potential approval hurdles in many organizations), no unnatural development techniques, no IDE dependencies, no licensing costs, no strange dependencies to make it work, no steep learning curve, and no compromises to speed, performance or flexibility.
Third, we wanted to deliver a solution that built on the many strengths of Java. These include extremely good runtime performance, availability of standards (like JPA, Bean Validation, REST, Servlet API etc), fantastic IDE support (like debuggers, code assist, refactoring etc), established technologies, type safety, and a massive pool of existing developer knowledge, skills and experience (not only in Java itself but also the de facto Java building blocks like Spring, JSP, Hibernate etc).
Alternatives to Roo's Architecture
With the above requirements in mind, in 2008 I prototyped a number of different techniques including JSR 269 (the Pluggable Annotation Processing API in Java 6), build-time source code generation, IDE plugins, bytecode generation at development time, bytecode generation at runtime and advanced reflective approaches such as extensions to Spring Framework AOP. I didn't prototype other JVM languages because the principal motivation underpinning Roo was a tool to enable Java programming.
In one way or another each approach I prototyped had issues that ruled it out. Every approach needed a special runtime, special IDE plugin or suboptimal build step (or a combination thereof). Most also permanently locked the user into the approach, with removal unduly difficult and therefore creating a barrier to adoption that would stop many Java developers from enjoying the productivity gains on offer. Many approaches also relied on reflective techniques at runtime that would be slow and confusing to debug, and most offered little to no IDE integration. I also particularly preferred providing a lightweight, command-line tool, as I strongly believed this would deliver better a usability experience than a GUI. These are the reasons why we didn't use the approaches listed above.
Roo Architecture Summary
After considerable prototyping we arrived at the Roo architecture, the key elements of which are:
- A tab-completing, context-aware, hint-providing command line shell that can be loaded and exited by the user at any time and supports concurrent use with text editors and IDEs
- Use of @Roo* annotations which have source-level retention only (not runtime retention)
- AspectJ inter-type declarations (ITDs, also known as "introductions" or "mixins") for automatically maintained Java members (we'll discuss ITDs in depth below)
- A metadata model to facilitate easy development of custom Roo add-ons (we'll also discuss the metadata model below)
- Full round-trip capabilities, courtesy of the metadata model and various core services mentioned above
This architecture didn't need a special build system, runtime component, IDE plugin or alike. It also met all of the design requirements mentioned earlier.
Roo's Secret Sauce
The "new idea" that made this possible was to automatically use ITDs as a code generation artifact. Using ITDs in this manner delivers considerable practical benefits, because it allows Roo to generate code that is in a separate compilation unit (ie physical file) from the code that the developer writes. Despite being in a separate file, the ITDs are combined into the same compiled .class file at compilation time. Because the resultant class is essentially the same as if the developer had written all the code themselves, all the benefits of traditional Java programming (like IDEs, debugger support, code assist, type introspection, type safety etc) work just as you'd expect. Also, because the compiled class is just a class file, everything works perfectly at runtime. Specifically, you don't have to worry about issues like reflection performance, memory usage, confusing and difficult to debug operation, extra libraries that may need approval and upgrading etc.
What's also exciting about using ITDs for code generation is the separation of concerns it delivers. Separation of concerns benefits the application developer, as they can safely ignore the ITD files created by Roo (because the developer knows Roo will manage them). But the separation of concerns is also excellent for Roo add-ons as well. The development of add-ons is much easier as the add-on developer knows they control the entire ITD compilation unit contents. A more subtle benefit is the automatic upgrade support this delivers. We've seen many examples during Roo's development where we've improved an add-on and then users who subsequently load Roo receive an automatically upgraded ITD. Similarly users can remove add-ons from their environment and the relevant ITDs will automatically be removed by Roo. This is an extremely pragmatic and useful technique that we've found invaluable.
The final major benefit of ITDs is lock-in avoidance. As we'll see later, ITDs are essentially normal Java source files. They just sit on your disk with all of the other source code, meaning developers can elect to never load Roo again and their project will still work. Those wanting a more complete removal can use features like Eclipse AJDT's "push in refactoring". What this does is automatically move all source code from ITDs to the correct Java source file. This means if you don't want to use Roo anymore, just "push in refactor" your project and you have a perfectly normal Java project – just as if you'd written it all by hand yourself. This is fantastic news:
- People just wanting to kick-start a project can do so with incredible ease and then remove Roo (as an aside they can also resume using Roo again at any time and it will work fine)
- People wanting to use Roo for long term productivity gains can do so with complete confidence, knowing they can very easily remove it at any future time with just a couple of mouse clicks
Roo uses ITDs as provided by AspectJ. SpringSource are big supporters and users of AspectJ, and here are just some of the reasons we feel it's a good fit for Roo-based projects:
- AspectJ is an active project with a large community
- AspectJ is mature, reliable and robust, having origins back in 2001 at PARC
- AspectJ is widely supported by mainstream technologies like Maven, Ant and IDEs
- Using AspectJ delivers existing IDE support without us needing to write extra plugins
- Our research showed around half of all Spring users were already using AspectJ anyway
- AspectJ is not used at runtime (the AspectJ runtime JAR is needed, but this has been a Spring Framework dependency since Spring 2.0 and as such would already be approved by organizations using Spring 2.0 and above)
- AspectJ operates at build time and therefore ensures Java's performance and perm gen space is not compromised
- Roo's ITD usage pattern is automatic, transparent and does not require users to have any AspectJ (or ITD) knowledge, skills or experience
- Using AspectJ permits more advanced programming patterns to be employed such as domain driven design (DDD) and enforcement aspects, should developers wish to employ them
- SpringSource employs the current leads of AspectJ (Andy Clement) and AJDT (Andrew Eisenberg), plus highly regarded AspectJ experts (like Ramnivas Laddard and Adrian Colyer), so we knew we had considerable in-house skills to ensure AspectJ would work very well with Roo
- Many other production-proven technologies from SpringSource are also built on or support AspectJ, including Spring Framework, Spring Security, SpringSource Application Management Suite, SpringSource dm Server, SpringSource tc Server and more
Roo Usage in More Detail
Let's explore Roo's ITD usage and metadata model by creating a new project. Assuming you've installed Roo 1.0.0.M2, let's create a new directory for our project and start Roo:
$ mkdir architecture $ cd architecture $ roo
Once you receive the welcome screen, enter the following commands:
roo> project --topLevelPackage com.hello roo> persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY roo> entity --name World roo> field string name
Graphically your screen will look something like this:

Let's now open up a text editor and take a look inside the World.java file:
package com.hello;
import javax.persistence.Entity;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.tostring.RooToString;
import org.springframework.roo.addon.entity.RooEntity;
@Entity
@RooJavaBean
@RooToString
@RooEntity
public class World {
private String name;
}
As shown, there are several @Roo* annotations. These annotations are included in Roo add-ons and instruct Roo to create an ITD if required. The @RooEntity annotation is indicating that you'd like Roo to automatically provide typical JPA methods and fields (including an identifier and version property). The @RooJavaBean is requesting getters and setters to be created for each field. The @RooToString is requesting a toString() method to be created.
All ITDs created by Roo adopt a specific naming convention. The convention is SimpleTypeName + "_Roo_" + AddOnSpecificKeyword + ".aj". Roo automatically ensures all files matching this format are properly managed by a relevant add-on. If there is no add-on installed for a particular keyword, Roo will delete the orphaned ITD file. This ensures you can change your add-on configuration at any time and not have to manually deal with cleaning up.
Let's have a look inside the World_Roo_ToString.aj ITD:
package com.hello;
privileged aspect World_Roo_ToString {
public String World.toString() {
StringBuilder sb = new StringBuilder();
sb.append("id: ").append(getId()).append(", ");
sb.append("version: ").append(getVersion()).append(", ");
sb.append("name: ").append(getName());
return sb.toString();
}
}
As you can see, an ITD looks just like a normal Java source file. There is only one difference: in the method signature there is a "World." prefix before the "toString()" method name. This is directing AspectJ to introduce the toString() method into the World.class file during compilation. As you can see, ITDs are incredibly simple even if you've never encountered them before. In particular, there are no pointcuts required.
Let's edit the World.java file and add another field to it:
private String comment;
If you've left Roo running, as soon as you save World.java you will notice that it instantly modifies the World_Roo_JavaBean.aj and World_Roo_ToString.aj files. This is because Roo monitors the file system for any changes you make outside of the Roo shell, such as through your preferred IDE. You could have also used Roo's "add field string" command if you preferred.
If you didn't have Roo running, the next time that you load it an automatic startup-time scan will be performed. This includes automatically upgrading any existing ITDs if the relevant add-on has been upgraded (or even deleting the ITD if the add-on no longer exists). The point is all of this happens automatically and naturally, without you needing to worry about following special rules and constraints about when Roo must run or how you must change files etc.
Customizing What Roo Generates
All @Roo* annotations allow you to control the member name being used, and also provide the member yourself. Let's edit the World.java file and change the @RooToString annotation to:
@RooToString(toStringMethod="rooIsFun")
If you now have a look in the World_Roo_ToString.aj file, you'll see the method name has automatically changed:
package com.hello;
privileged aspect World_Roo_ToString {
public String World.rooIsFun() {
StringBuilder sb = new StringBuilder();
sb.append("id: ").append(getId()).append(", ");
sb.append("version: ").append(getVersion()).append(", ");
sb.append("comment: ").append(getComment()).append(", ");
sb.append("name: ").append(getName());
return sb.toString();
}
}
Let's say you don't like Roo's toString() method (which is now rooIsFun(), remember!). You have two ways of removing it. You can either delete or comment out the @RooToString annotation in the World.java file, or you can simply provide your own rooIsFun() method directly in World.java. Feel free to try both techniques. In both cases you'll see Roo automatically deletes the World_Roo_ToString.aj file, as it can see you don't need Roo to provide the method for you anymore. This reflects Roo's approach: you are always in total control and there aren't any surprises.
Metadata Model
While you certainly don't need to understand Roo's internals to simply use Roo, curious readers might be wondering how the World_Roo_ToString.aj file even knew there were getId(), getVersion(), getComment() and getName() methods available. This is particularly interesting given these methods aren't even in the World.java file. Let's explore this a little more.
In the Roo shell, enter the following command:
roo> metadata for type --type com.hello.World
The resultant screen should look similar to:

What this is summarizing is Roo's internal representation of the World.java type. This is built from an AST parse and bind of the World.java file. You may have noticed there are downstream dependencies listed. These represent other metadata items that wish to be notified should the World.java metadata ever change. Add-ons will generally listen for changes to other metadata items and then modify ITDs (or XML files or JSPs etc) accordingly.
You can watch the metadata event notifications take place by typing "metadata trace 1" and then changing the World.java file. The notification messages will appear similar to the following:

Before concluding this introduction to Roo's metadata model, I will note that Roo does not require metadata to be retained in memory. This ensures very large projects can still use Roo without running out of memory. Roo automatically tracks cache statistics and also the runtime profile of individual add-ons. Those systems with sufficient memory will enjoy an automatic LRU cache. If you're curious about the LRU cache statistics, these are available via the "metadata status" command (note the cache hit ratio is pleasingly high):
roo> metadata status 2: org.springframework.roo.addon.configurable.ConfigurableMetadata 5: org.springframework.roo.addon.javabean.JavaBeanMetadata 8: org.springframework.roo.addon.finder.FinderMetadata 35: org.springframework.roo.addon.plural.PluralMetadata 53: org.springframework.roo.addon.beaninfo.BeanInfoMetadata 64: org.springframework.roo.addon.entity.EntityMetadata 124: org.springframework.roo.addon.tostring.ToStringMetadata 862: org.springframework.roo.process.manager.internal.DefaultFileManager [DefaultMetadataService@6030f9 providers = 14, validGets = 369, cachePuts = 17, cacheHits = 352, cacheMisses = 17, cacheEvictions = 0, cacheCurrentSize = 6, cacheMaximumSize = 1000]
Conclusion
I hope that you have found this discussion of how Roo works interesting. We've seen that Roo uses ITDs to achieve sustainable productivity gains for Java developers. We've looked at the benefits of Roo's ITD approach and seen how it actually works in depth, including how they are customized, how they operate at a metadata level and how their lifecycle is transparently and automatically linked to add-on upgrades. We've also discussed how ITDs deliver mature and proven separation of concerns while concurrently avoiding lock-in, runtime implications and other subtle issues that are important in large, real-world projects. Finally, we reviewed Roo's metadata system and explored some of its event notifications, type introspection and scalability features.
We look forward to supporting the community in becoming involved in Roo and developing new add-ons. We invite you to try out Roo and we very much welcome your feedback, bug reports, feature ideas and comments. I hope that you enjoy using Roo.
Similar Posts
- Introducing the Flex Addon for Spring Roo
- A Big Hop Forward: Spring Roo 1.1.0 Is Released!
- AOP Configuration Choices in Spring 2.0
- Spring Roo 1.1.0.M3 Released
- POJO Aspects in Spring 2.0: A Simple Example





Greg says:
Added on June 18th, 2009 at 11:48 amBen,
Great article!
Do the aspects generated by Roo work with load-time weaving? I currently have an app utilizing that feature, mixing together @AspectJ along with some Spring AOP, and wondered if Roo would fit into that.
Ben Alex (blog author) says:
Added on June 18th, 2009 at 12:20 pm@Greg, Roo uses compile-time weaving of the ITDs. As such you shouldn't have any problem combining it with load-time weaving (although you'd probably find better performance if you let AspectJ do its work at compile time, given AJC will be running to process the Roo ITDs anyway).
Gabriel Pop says:
Added on June 18th, 2009 at 2:12 pmPerfect timing, I was preparing to give a ROO presentation in my office tomorrow and then this post came up. Thanks ! Since springOne wanted to find out about the internals of Roo.
Matthew Adams says:
Added on June 18th, 2009 at 3:07 pmHi Ben,
It would be great to see how to write the code-generating portions of Roo plug-ins. Is there a tutorial or reference guide material on using the metadata model?
-matthew
Keith Donald says:
Added on June 18th, 2009 at 3:18 pmGreat article Ben! I found the tour through the architecture enlightening…. I definitely gained a better understanding around the motivation for using ITDs.
Looking forward to a follow up article on writing Roo add-ons!
Keith
Don says:
Added on June 18th, 2009 at 8:11 pmHi,
In the last post about Roo I left a comment asking how Roo measures up against Grails. From what I can tell, the two look very similar from the user's perspective, though Grails uses Groovy meta-programming for it's magic whereas Roo uses AOP. Can you explain why it makes sense for Spring to have Roo and Grails in it's portfolio?
Thanks,
Don
Jozsef says:
Added on June 19th, 2009 at 12:17 amHello,
Same "problem" like Don's.
What should I choose ? Grails or Roo ? Because I have to choose, and these two thing look almost the samo for me.
Thanks !
Raúl Arabaolaza says:
Added on June 19th, 2009 at 1:45 amHi,
Great article, now i understand perfectly why you choose AOP and can tell my manager that i don´t have any risk of vendor lock in, i can get all roo´s magic features even if i discard roo by using push to refactor.
Only one litle "but", push to refactor seems to be a AJDT feature, not a roo feature, is not a big problem because STS is free, but i wonder… That functionality could be included into roo itself? By doing that you will eliminate the only, and minimal, Roo´s locking to an IDE.
regards, Raúl
Ben Alex (blog author) says:
Added on June 19th, 2009 at 1:57 am@Raúl, we could theoretically add a "remove roo" command to Roo itself, although I think I'd spend more time thinking up alternate command terms instead of actually coding it ("goodbye my little friend", "bloat my java code -yesReally"
etc). I haven't spent any time on it because I knew Andrew was working on push in refactoring and it was a quick outcome for Roo users. I also felt it would give people *even more* confidence in using Roo because they know the removal feature is not even part of Roo, but part of the mature, well-maintained and widely-used AJDT Eclipse plugin. For a user to get caught by lock-in, they'd need to dislike Roo *and* for AJDT to somehow no longer offer an advertised feature. It seems unlikely a user would suffer *both* problems at the same time. I mean even if they did, you've seen ITDs are simple enough a user could move the members across to the Java source files by hand. And simply stopping using Roo in the meantime will still leave the ITDs on disk and therefore everything will still compile and work.
I should also note that AJDT is part of normal Eclipse – you don't need to use STS. I acknowledge you need to load Eclipse or STS to use AJDT, but given both Eclipse and STS are 100% free I don't think it's a major problem. Even a non-Eclipse user could quickly "mvn eclipse:eclipse" their Roo project, load Eclipse, perform the push in refactoring, then quit Eclipse and never reload it again.
Raúl Arabaolaza says:
Added on June 19th, 2009 at 4:27 am@Ben, I see your point, I think is very reasonable. Thanks for the quick answer
.
Dave McLure says:
Added on June 19th, 2009 at 12:44 pmOK, this is going to seem like a really trivial request, but you might want to consider adding a "net stop beep" to the roo.bat startup file on Windows XP.
The constant tabbing around in roo was causing my Windows XP command prompt window to beep (extremely loudly I might add) – and this sound is beyond the control of the usual windoze volume controls.
Not only was the sound extremely unnerving to me, but believe it or not, it was quickly becoming a show stopper for me with roo at work here (I think my cube neighbors were nearly ready to lynch me).
Luckily, I discovered that you can disable this stupid beeping noise by simply typing in the command "net stop beep" prior to launching roo. I have since added this command to my roo.bat and life is wonderful again! (at least until I forget to add it to the next roo milestone drop).
Ben Alex (blog author) says:
Added on June 19th, 2009 at 3:30 pm@Dave, I've completed your request to stop Roo beeping under Microsoft Windows (logged in Jira as ROO-110). Thanks for the suggestion.
Grzegorz Borkowski says:
Added on June 22nd, 2009 at 4:26 amThere is only one problem with Roo approach I see. In my team, we use Maven and everybody uses his preferred IDE: one can use Eclipse, other uses Netbeans etc. In Maven-based project it's not a problem to allow people to use their preferred IDE, as all metadata are kept in POM, not in IDE-specific files. I also often switch IDEs: I use Eclipse until it starts to crashes and I think "I hate Eclipse" so i switch to Netbeans until it crashes and I think "I hate Netbeans" so I go back to Eclipse etc. (Especially WTP and how it works and how it uses my Tomcat installation makes me mad and often forces to use Netbeans).
But now I if start to use Roo, all Netbeans users will be lost, because code completion will not work and all the calls to the methods from ITD files won't be recognized by IDEs background compiler and will be red-underlined as errors. On the positive side, I see project compiles and runs properly even under Netbeans, because AspectJ compilation is defined in POM. But luck of code completion because of lacking recognition of methods from ITD is a real problem. So it's not true that Roo has no IDE dependencies: in fact you must use Eclipse to take full advantage of Roo (you can do push-in-refactorings of all ITD code to make it visible under Netbeans, but then again you are not taking full advantage of Roo, as this is not a normal way it should be used, I believe)
Greg says:
Added on June 22nd, 2009 at 8:38 am@Grzegorz:
You have a point. But this point must extend to a significant piece of AspectJ itself, and not just Roo. Basically NetBeans doesn't appear to support the full suite of features from AspectJ.
Eclipse handles it, ant handles it, and maven does too. So…how is it Roo's fault that NetBeans doesn't support this? And what about IntelliJ? AspectJ isn't exactly new. What is holding NetBeans back from supporting it?
Grzegorz Borkowski says:
Added on June 22nd, 2009 at 8:46 amWell, perhaps you're right, but the point still holds. Roo depends heavily on IDE support for AspectJ constructs (ITD) to make it fully functional. This means that from practical point of view, Roo is of little value for Netbeans or IntelliJ users…
Joost den Boer says:
Added on June 22nd, 2009 at 8:54 amBen,
Great article. Thanks.
Just like Matthew I would like to know more about writing addons.
I especially would like to know which core services/component are available to be used by addons. The Command object are not that difficult, but the Operations classes I don't get. I have looked at the source of a couple of them but they all seems to do something else. I don't get how Roo is able to construct those complex Operations classes. They all seem to use different constructor arguments.
Could you please enlighten us a bit more so we can really get started with making addons?
Greg says:
Added on June 22nd, 2009 at 9:07 am@Grzegorz:
Sorry, but "depends heavily" would imply to me that Roo only runs inside Eclipse. There are some plugins that are built that way. The fact that Ben built Roo to run from a command-line shows a huge investment in design consideration.
"Roo is of little value for Netbeans or IntelliJ users." We should be beating up on NetBeans and IntelliJ for not taking the AspectJ revolution seriously. It would seem better couched, "NetBeans and IntelliJ are of little value for AspectJ users." NetBeans developers, are you listening?
Grzegorz Borkowski says:
Added on June 22nd, 2009 at 9:34 am@Greg:
You are perfectly right, NetBeans and IntelliJ are of little value for AspectJ users. Or more precisely: for users that take advantage of AspectJ specific features, which are not standard Java. But honestly, I've took part in many Java projects and never seen project using these features. When AspectJ was used, it was used in "@Aspect style", that is based on pure standard java annotations, so no special IDE support was needed – and I guess this is the usage that Ben described: "Our research showed around half of all Spring users were already using AspectJ anyway". I don't believe half of Spring users actually use non-Java-standard, AspectJ-specific constructs.
Also, I'm not in charge of Netbeans nor IntelliJ to force them to handle ITDs properly. It would be nice if they did, and it would promote AOP for sure. On the other hand, I can only guess that if they didn't implement aspectj syntax support yet, then simply there was no significant demand for it.
Rod Johnson (blog author) says:
Added on June 22nd, 2009 at 1:55 pm@Joost
In the 1.0 GA timeframe the team will better document add-on authoring, so less detective work will be needed
To solve the immediate mystery: Operations classes are parameterized by constructor injection. Roo itself uses a Spring application context.
Rgds
Rod
Ben Alex (blog author) says:
Added on June 24th, 2009 at 3:35 am@Grzegorz, as others have observed, it isn't Roo's fault certain IDEs don't provide complete support for AspectJ ITDs ("complete support" usually meaning code assist for ITD-introduced members). Such IDEs occupy a smaller marketshare than Elipse-based IDEs (which *do* offer complete ITD support) and generally already have an AspectJ plugin that simply needs enhancement to more fully support ITDs. Even if the developers of an IDE's AspectJ plugin don't use Roo, making this enhancement improves their plugin for all AspectJ users in that IDE – not only Roo users. This is a much more satisfactory position than expecting the community to build a Roo-specific IDE plugin in every IDE.
I'd also make the point that what is the alternative?
* If we implemented Roo as an IDE plugin it most certainly would have been an Eclipse IDE plugin. As such users of other IDEs would have been virtually abandoned, unless they're willing to write their own plugin from scratch and solely to support Roo. This is a much less realistic proposition than encouraging existing AspectJ plugin developers to simply make an enhancement to ensure their ITD support is first-class.
* There are similar productivity tools to Roo, but these generally don't provide code assist in every IDE. If it was so easy to do, you'd think someone would have figured out how to do it by now. Those other tools usually also require you to remember the commands and remember the method names you're supposed to use. You have to run the application to see if your memory worked and you typed everything in correctly. You also usually need to learn a different programming language and lose IDE features like debugger integration. At least Roo's approach delivers quality IDE support to most users (based on IDE market share) right away and doesn't require them to learn anything other than Java. With Roo you instantly see completions, you receive instant feedback if there's an error, and it won't compile if you're trying to do something wrong. More importantly, you can go back to plain Java source in a few clicks and permanently banish both ITDs and Roo from your project. That's on top of a friendly command line shell that also includes tab completion, hinting and contextual awareness – irrespective of which IDE you happen to use. Most RAD tools don't give you this level of command line usability nor instant visual feedback if something is wrong. That's not to mention their runtime approach (extra dependencies, slower operating speed, memory consumption, the need to regularly upgrade the runtime, versioning compatibility issues, approval requirements, lock-in and so on).
I believe the ITD approach strikes the right balance between usability, performance, lock in avoidance and realistic IDE support.
Grzegorz Borkowski says:
Added on June 24th, 2009 at 4:38 amBen, if I knew better alternative, I would have already written it and made money on it
Seriously speaking, I'm aware of only one alternative at this moment: Groovy&Grails. This touches another question which was raised several times here, but never answered: what is SpringSource position against Roo vs. G&G? As people already said, both seem very similar, both are supposed to be "productivity solution for Java", and both are in hands of SpringSource.
Personally, I see some pros and cons of both of them. Roo doesn't require learning of new language nor framework, so learning period is short, and it has no runtime cost. On the other hand it introduces some other constructs, like ITDs, that can look alien to most Java developers. And as I said it's rather unlikely to have support fo such constructs in other IDEs (but perhaps I'm wrong about it, I'm just guessing here).
G&G on the other hand requires you to learn new language (Groovy) and new framework (Grails). It has runtime cost (Groovy will be slower than pure Java, but in practice this can be of no importance; also this can be more difficult to debug, potentially less stable etc). IDE support for Groovy is much worse than for Java too. On the positive side, programming in Groovy will make you probably much more productive than in Java, still being on the Java ground. And because G&G is getting popular very fast, it's much more probable to have full support for it soon in other IDEs than for AspectJ.
That's my comparison, but still I believe Spring community is waiting for some "official" comment on "Roo vs G&G" from SpringSource
Hendy Irawan says:
Added on June 24th, 2009 at 4:02 pmRegarding the ITD dilemma, is it practical for Roo to provide a choice between having compile-time aspects (like what it's doing now) and run-time aspects.
Runtime ITD with @Aspect's is usable by non-Eclipse IDEs and even though it may incur performance hit, the developer should be *in control* of the choice. As you have said this is one of the goals of Roo. Putting the developer in control, like: "I want to use AOP, but not at compile-time, pointcuts is fine with me."
Please follow-up this excellent article with Roo add-on development tutorial!
Tobias says:
Added on June 25th, 2009 at 3:42 pmI would be really nice if the author gave us a comparison beetween: Roo, Grails and Skyway (http://www.skywayperspectives.org, which has SpringSource as a partner).
cblin says:
Added on June 29th, 2009 at 4:28 am[quote]Please follow-up this excellent article with Roo add-on development tutorial!
[/quote]
1 please
Will a forge be available for the community addons ?
What I am interested in is the generation of a frontend in extjs (i.e a GridPanel with a binded form to edit the records).
Hendy Irawan says:
Added on June 30th, 2009 at 6:23 am@Tobias
Thanks for the info about Skyway. It seems really interesting.
I guess it's somehow a competitor to SpringSource's own STS ?
Paul Bernet says:
Added on July 13th, 2009 at 9:34 amI tried the "push in refactoring" which is mentioned above
- but run into problems. Here is what I did:
1)
Executed clinic.roo sample in Roo M2.
2)
Generated Eclipse-Project and imported it to STS 2.1.0 RC1
3)
AJDT Plug-In is in Version: 2.0.1.e35x-20090704-2000
4)
When I right click the clinic project I do not see the Sub-Menu Entry Refactor | Push In…
as suggested in http://contraptionsforprogramming.blogspot.com/2009/05/push-in-refactoring-for-ajdt.html
Do I need to activate AJDT somehow ?
Regards.
Paul
Andrew Eisenberg says:
Added on July 13th, 2009 at 6:00 pm@Paul:
No, you shouldn't need to activate anything. But it does seem like something funky is going on. Do you notice any relevant error messages in the error log? There could be something preventing AJDT from loading. A quick test to see if AJDT is properly loaded is to look for AJDT gutter markers in the ROO ITD files.
Please raise a bug for this on Bugzilla and paste any relevant error logs or stack traces into your report:
http://bugs.eclipse.org
Paul Bernet says:
Added on July 14th, 2009 at 6:57 am@Andrew:
When I changed into the "Aspect Visualisation" perspective I was able to select the menu entry
However, when I selected the entry for the first time I got the error below in the eclipse log.
After a Clean/Build of the project I was able to proceed with the procedure as in:
http://contraptionsforprogramming.blogspot.com/2009/05/push-in-refactoring-for-ajdt.html
The resulting classes look like this – I've taken Pet as a sample:
@org.springframework.beans.factory.annotation.Configurable
@Entity
@RooJavaBean
@RooToString
@RooEntity(finders = { "findPetsByNameAndWeight", "findPetsByOwner", "findPetsBySendRemindersAndWeightLessThan" })
public class Pet {
Is this the correct result of the procedure ? I'm wondering that there are still Roo Annoations.
Regards.
Paul
Javed Mandary says:
Added on July 15th, 2009 at 4:42 amStrangely the download link for spring-roo doesnt seem to be working:
http://www.springsource.com/products/spring-community-download
Are there any other direct links that can be used?
Andrew Eisenberg says:
Added on July 15th, 2009 at 9:38 am@Paul,
"However, when I selected the entry for the first time I got the error below in the eclipse log."
I didn't see an error log. Did I miss it?
The refactoring will leave the @Roo* annotations on the target type. Push in refactoring does not change the semantics of your program, only the structure.
Yehuda says:
Added on July 15th, 2009 at 12:40 pmworking on a hobby project enabling ROO with JSR-113. will share when i have something stable.
Paul Bernet says:
Added on July 16th, 2009 at 2:15 am@Andrew
The Ex got lost along the way.
java.lang.IllegalArgumentException: Argument not valid
at org.eclipse.swt.SWT.error(SWT.java:3865)
…
at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
The same ex periodically occurs in the eclipse error log with two different "Message headers":
1) Problems occurred when invoking code from plug-in: "org.eclipse.jface".
2) Unhandled event loop exception
For the remaining @Roo* Annotations: I assue that I can write a script which deletes all @Roo* Annotations and import statements.
Regards.
Paul
Andrew Eisenberg says:
Added on July 16th, 2009 at 11:02 amPaul,
Can you please raise a bug for this on bugzilla? And include the full stack trace. I will look at it. Thanks.
http://bugs.eclipse.org
Keith Thomas says:
Added on July 16th, 2009 at 11:37 pmAs far as I can tell SpringSource are entirely silent on the whole Grails vs Roo topic. Any thoughts why this should be?
Paul Bernet says:
Added on July 17th, 2009 at 4:05 am@Andrew:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=283814