Groovy and Grails: Changing the Landscape of Java Platform, Enterprise Edition (Java EE Platform) Patterns
Why did I sign up for ANOTHER Groovy and Grails talk? That’s a great question. I have no idea. Nothing new was presented here that wasn’t already presented elsewhere.
JRuby on Rails Deployment: What They Didn’t Tell You
This was a pretty comprehensive presentation on what it takes to deploy a Rails application via JRuby. The talk started out with a brief history of how Rails apps have been deployed on the traditional Ruby implementation. CGI/FastCGI was always slow and kind of buggy. The Mongrel Ruby web server is widely used, but large clusters need to be deployed for high traffic sites, due to Rails’ non-multithreading nature. These large clusters have proven to be difficult to manager. There are tools that help with Mongrel cluster management, but it doesn’t change the fact that your cluster size is huge.
Deploying Rails apps on JRuby allows you to take advantage of JVM threading, shrinking the number of real processes you need to have running out there to handle requests. It is possible to configure JRuby on Rails to use a fixed number of JVM runtimes to process requests, so that you can scale it out to fit the needs of your web application.
There are tools available to help with the deployment of a Rails app on a Java application server. Warbler can be used to package the Rails application into a war file that can be easily deployed to the application server. Warbler is pretty easy to setup and use, and only requires you to list the Ruby gems that your application depends on (which can be done in a configuration file).
However, Rails apps on JRuby still require a bit of fiddling to get up and running. You can use JNDI for database connections, but Rails does not close the connections at the end of each request (by design…this is just how rails works). So, workarounds are needed to get the application to behave a little more like a Java app, which usually opens a connection at the beginning of the transaction, and closes the connection at the end. Several configuration modifications are needed to get the Rails app to run optimally in a production Java environment. And, there are several areas where the Rails and the application server don’t mesh too well together.
The author has just released a library, called JRuby Rack, which attempts to bridge the gap between your Rails application and the application server. Among other things, it allows Rails to use JSPs to render the view, makes the Java servlet context available to the Rails app, and passes servlet request attributes from Java to the Rails application.
Programming with Functional Objects in Scala
Martin Odersky, the creator of the Scala language, presented a good overview Scala. Scala is another programming language that runs on the JVM, and boasts full Java interoperability. It was designed to be scalable across all areas of development, which is where it got its name. It can do everything from power the smallest scripts to the largest applications.
Martin considers Scala to be the Java of the future. It can do everything that Java can, and more. Unlike another fully Java interoperable language on the JVM that is getting a lot of attention, Groovy, Scala is fast. Martin says it benchmarks just as fast as Java. It also is much more expressive than Java, letting you write less code. Martin stated that the average Scala project contains 2x (or more) less code than an equivalent Java project. This is due to the syntax of the language, and to the better abstraction that is provided by Scala.
Scala was designed to be extensible. Users can easily add to the language to fit their needs. This is nice, as it keeps the language itself trim. There is no need for the language itself to solve everybody’s issues. You can take it upon yourself to solve your own problems :)
I’m not going to list out all of the features of the language that were identified during the presentation. Check out http://www.scala-lang.org if you are interested. I will however mention some of the features that peeked my interest.
First, Scala supports mixins. You can think of a mixin as a Java interface with a default implementation. You can “mixin” functionality to your class, without clouding the object hierarchy by allowing multiple inheritance. After working with mixins in Ruby, I’ve really started to miss them in Java. It’s nice to see them here.
Second is the concept of actors. Actors add Erlang like concurrency to Scala. Erlang is well known for the way it handles concurrency, using many lightweight processes that interact with each other via simple asynchronous messages. This is great to see in a language with full Java interoperability.
Another thing I like about Scala is the fact that it is an object oriented language AND a functional language. You can code using the paradigm that best suits the problem.
Scala is quickly growing in popularity. Though not as easy to adopt as Groovy, due to the radically different syntax, it is without a doubt a very strong language.
Defective Java Code: Turning WTF Code into a Learning Experience
I was a little disappointed with this talk. I was expecting a lecture on ways to best learn from existing bugs. There was a little bit of that, but the majority of the session simply showcased some not so obvious bugs that the presenter has run into in the past. There was however some good advice that I took away from this session.
First, never assume that a bug is so stupid, or so unique that it doesn’t exist elsewhere in your code or in somebody else’s code. The speaker showed several bugs fitting this description that he was able to find in several different code bases using findbugs. And, these weren’t obscure projects he found these bugs in either. He found several of these bugs in the Java codebase, the Eclipse codebase, and the codebases of several other large, well respected projects.
Make use of every available tool you have to flush out bugs as early in the development cycle as possible. This includes things like the @Override annotation. The speaker demonstrated a bug where a subclass was supposedly overriding the method of a parent class, but used a class in the method signature with the same name as the one in the original method…but from a different package. So, simply looking at the method, it looked like a perfectly valid override. You had to compare the import statements of the parent class and the child class in order to figure out what was happening. Using the @Override annotation would have caught this bug at compile time.
Design Patterns Reconsidered
Design patterns have been getting a lot of negative press lately. This is due to a number of factors:
- They result in people copying/pasting code to implement the patterns without actually knowing what is really going on.
- They are accused of being workarounds for shortcomings in the language.
- They are overused.
Each of these criticisms has its valid points. However, design patterns still play an important role in software development today.
- They form a vocabulary that developers can use to talk about problems, and solutions.
- They help expose real design issues.
- They help compare alternative design choices.
The speaker took us through three design patterns documented in the original Gang of Four Design Patterns book, and how they might be applied differently today.
First up was Singleton. The speaker acknowledged that there is sometimes a valid need to ensure that there is only one instance of a specific object. However, the Singleton design pattern causes the following problems:
- It makes testing difficult by carrying state from one test run to the next. This could affect how the test behaves, and can make test results unpredictable.
- It creates “hidden” dependencies. It is hard to tell, without digging through the code, that an object may have a hidden dependency on a Singleton. This also makes the Singleton hard to mock for testing.
- There is not really just one instance per the JVM. There could be one per classloader.
- Could create memory leaks, since Singletons never fall out of scope.
- Subclassing is difficult, and ugly.
What do we do about this? Simple; don’t use Singletons. Define an interface, and use a dependency injecting framework to handle the creation of the object, and to inject it where it needs to go. This way you can have your one instance of the class, and avoid all of the problems mentioned above.
Next up was the Template Method design pattern, which has the following problems:
- Algorithms in the base class(es) can become very complex, and hard to follow.
- This design pattern usually leads to an explosion of base classes.
- Inheritance cuts of many of your design options for the sub classes.
- No way to combine functionality in sibling sub classes. You may have a FastCar, and a CheapCar, which are both subclasses of Car…but there’s no easy way to have a FastCheapCar without an additional subclass.
- It is hard, without exhaustingly comprehensive documentation, to document the intent of your framework to your user.
How do we address these issues? Use composition over inheritance. Move the logic that would exist in the sub classes into a series of command objects, which you can then inject into the framework. Inheritance is a very strong form of coupling, and should be avoid unless it makes absolute sense.
Lastly, the speaker took a look at the Visitor design pattern, which has the following issues:
- You can easily expand the list of visiting methods, but you can’t easily expand the data structure you visit.
- It is difficult to return a value while visiting.
- It is difficult to throw an exception while visiting.
The speaker offered the following suggestions for the Visitor pattern:
- Put the data structure navigation code in its own visitor, which would take the logic visitor along for the ride, applying it to each node it visits.
- Hold onto return values and exceptions in the navigation visitor.
- Closuers, when they are available in Java, may be able to improve upon this pattern further.
The speaker finished with a list of general design principles:
- Code to interfaces, not implementations, and use dependency injection to reduce coupling.
- Favor composition over inheritance.
- Don’t rely on object identity.
- Separate parts of the design that change at different rates.
- When in Java, take advantage of the strong, static typing system. It is one thing Java does very well. So, use it to your advantage.
Developing Service-Oriented Architecture Applications with OSGi
This was a Q/A session with some OSGi experts. The experts discussed how they have used OSGi on past projects, what they liked about, and what they felt it could do better.
What is OSGI?
- OSGi is a framework that manages the services in a service oriented architecture.
- It has the ability to add services at runtime, and makes it very easy to do so.
- It provides total control over what services you expose, and what services you consume.
- Service “bundles” have a life cycle that is independent of the JVM, meaning you can start and stop services without starting and stopping the JVM.
- OSGi bundles make the dependencies of a service very clear, making sure there are no “surprises”.
- It allows you to deploy separate components of a SOA independent of one another. So, if a service has a bug, you can simply upgrade that service without touching the rest.
- There is no need to restart the application server to deploy a new version of a service.
- Service bundles are platform independent. Your service can run in a web container, a cell phone, a zerox machine…pretty much anything that supports OSGi.
I’ve been hearing a lot of buzz about OSGi the past few weeks leading up to JavaOne, which is why I attend this talk. I have to say, I like what I heard. I think that Orbitz may be able to benefit from such a framework, as the majority of our architecture is service oriented. This could possibly help in the deployment of some of our services. I will definitely be reading some more on this topic, and thinking about how we might be able to use this powerful new technology.
Testing in Groovy
The last session I attended for the day was one on testing using Groovy. Groovy provides many features that make it an ideal language to use to write tests for your Java code:
- Groovy is much more expressive than Java, and has the ability to dramatically reduce the amount of test code you have to write.
- Groovy is fully interoperable with Java, giving you access to all of your Java code that you want to test.
- You can re-use existing Java test frameworks.
- Groovy’s metaprogramming capabilities make mocking objects and stubbing methods a breeze.
- Groovy has several features that can be used for testing, including a GroovyTestCase class, and built in mocking and stubbing capabilities.
I was pretty convinced going into JavaOne that I wanted to start writing tests in Groovy. Everything I have seen here at JavaOne regarding Groovy has re-enforced this decision.