As you can tell from my blog I am a long time Java developer who likes to flirt with dynamic languages. Not surprisingly my two favorite languages at this point are Groovy and Ruby. Therefore, I enjoy working with the Grails and Rails frameworks. After working with Java for so long I was starting to get tunnel vision around a single language. After all, Java is a general-purpose language that can do anything if you bend it enough.
However, Java is not always the best solution for all situations. Obviously, Web development is one of those glaring areas where Java can work but might not be the best candidate. I began developing web applications with Java using plain old servlets and jsp pages. Like most Java developers I also discovered Struts 1. While some of the components of the framework seemed a little strange, Struts was better than my homegrown attempt. So I developed with Struts for a while but I was not entirely satisfied. Of course there were other issues to tackle outside of the presentation layer including persistence, transaction handling, and other services. So I evaluated JDO, EJB, and Hibernate. I finally settled on Hibernate but there was still a mess between my presentation tier and my persistence layer. Later I found Spring and glued everything together. After evaluating countless presentation frameworks I refined my Java Web stack over time using Stripes, Spring, and Hibernate. This combination took a lot of experimentation but I was able to make Java conform to the web in a relatively lightweight manner. The point is that I had to do a lot of bending here.
When Rails first came on the scene I was fairly closed minded mainly because of my investment in Java. How could this newcomer trump all my hard work or be as robust as Java? Well after taking Rails out for a test drive I quickly realized how over-architected Web development was with Java. It reminded me of so many early math classes where it would take several pages of computation to achieve a result. Then more advanced math classes introduced techniques to achieve the same results in just a few steps. I appreciated the simplicity of solving a problem with less computation and yielding the same results (or better). Doing less work for the same results once I understand the underlying theory works for me.
But with RoR there was a fair bit of voodoo so I became less intrigued by Rails and wanted to know as much as possible about Ruby. Ruby turned out to be a fun language with constructs that are currently not available or easy to achieve with Java (i.e. closures, better mixin techniques, creating your own DSLs with builders, everything is an object, etc). I quickly realized that I could code much more expressively and achieve the same functionality with a lot less lines of code. Testing my code with a dynamic language instead of Java was also enjoyable because it was simpler. I actually wanted to do testing! Exposure to a new language like Ruby actually improved my Java code (and made me resent how noisy Java is). So now I am an aspiring polyglot with an open mind to new languages.
Not long after I looked at Rails I saw that Grails 0.3 was available (I think I first saw it on http://java.net). So the Java camp was attempting to answer Rails with Grails. OK fine, I took a look at Grails and this is when I was first exposed to Groovy. Groovy offered much of the same dynamic capabilities as Ruby and worked well with my existing Java code (mostly). And Grails offered much of the same convention over configuration principles like Rails. Even better I could integrate my Grails application with my existing Java code. It was like winning the World Series of Poker when I hooked up my existing Spring beans and Hibernate annotated domain objects with Grails. Grails automatically recognized my Spring beans and seamlessly added all of the GORM dynamic methods to my domain classes.
However, I still liked the Ruby language slightly better than Groovy because it did not carry the Java baggage along with it. So now I have a language and a framework that are great for new development, but I could not reach out to my existing Java classes or external libraries with Ruby. Then I found JRuby. JRuby allows me to write Ruby code and integrate with my Java code, Spring beans, etc. However, if I was going to use Rails and wanted to follow their paint by numbers framework then I was stuck with ActiveRecord. Also Rails does not have a service layer concept so my Spring beans did not naturally fit in the Rails framework. I quickly found out how to create a Spring bean factory in JRuby so my Rails controllers could access these services.
As much as I like JRuby there are some things that I want. First, I would like to see JRuby continue to strive for near Java performance. I do realize that we are talking about a dynamic language but I believe that this can be achieved. Second, I think that JRuby needs to provide easier integration for popular open source frameworks like Spring and Hibernate. Why shouldn’t JRuby/Rails emulate Grails the same way that Grails “borrowed” from Rails. Maybe the JRuby team could offer these items as gems to supplement the Rails framework. Or maybe this will be a pluggable feature with Rails 3? This is about bridging the gap between the Java and Ruby communities. Finally, I want to see Engine Yard offer commercial support and training for JRuby (which seem inevitable now that Charles Nutter is at EY).
While building Rails applications is fun, deployment can be a pain. I think that the leveraging JRuby/Rails on a Java platform makes a lot of sense here. Ruby contains several gems for integrating your Rails application in a Java environment. First, there is the Warbler gem, which allows you to take your Rails application and package it up in a standard war file format. So now your Rails application can be deployed on any standard Java container. Second, there is a Glassfish gem for deploying your applications without Warbler. The JDBC-ActiveRecord gem allows you to use your JDBC drivers to connect to your database instead of the Rails drivers. By deploying your Rails application on a JVM you get extra benefits like simpler deployment strategies, better threading support, and easier ways to scale. So while you might want Rails for development, the JVM might offer better services for housing your application. Even if you don't have to integrate any Java code you should still consider JRuby for Rails development IMHO.
So, if you choose to use a dynamic language should you use Grails or Rails for Web development? I do not think there is a cut and dry answer to this question. In this case, the lines are a little blurry because the underlying languages seem to be converging in capabilities. However, I will provide my 2 cents on this issue and watch the comments for this entry fill up. Let me start off by saying that I like both frameworks for different reasons.
Let's start with Grails. Grails is great for Java developers that have existing experience with Spring and Hibernate. The migration to Grails will benefit these people the most because they understand how Spring and Hibernate work. Grails is pretty much just a wrapper around these frameworks so when problems arise they will have the same issues that had to be solved before. The benefit is that this is a great way to get started with a dynamic language (like Groovy) and start to understand what all the fuss is about using a familiar set of tools. Plus, as I indicated earlier you could drop in your Spring beans and Hibernate classes and watch them work out of the box. You will need a deep understanding of Spring and Hibernate when things go wrong to troubleshoot problems as they arise. This is where things might break down for developers that do not understand these frameworks.
Now let's talk about Ruby on Rails with JRuby. Working in Rails is just a fun way to develop. Rails was created solely to solve the domain specific problem around web development. And Rails developers seem to introduce easy solutions to mundane problems. There are lots of plugins and gems that can make Rails even more enjoyable. However, there are thousands of Java libraries available that you might want or need to integrate with. As a Rails developer why wouldn't you at least give yourself the option to tap into those libraries?
So how does everybody win? I believe that everyone will benefit if these two communities come together. I have observed the Java and Ruby communities for some time and seen a lot of mud thrown from both sides. At the end of the day you have to ask yourself why these two groups cannot see that they really need each other at some level. Is this more of a cultural gap than a technical one? Java is infused into so many organizations and is not likely to go away any time soon. What better way to get your Rails application deployed in a Java shop than making a case with JRuby? Also, if you want to evangelize and strengthen Rails as a popular development platform why not build on top of one of the largest existing infrastructures? Rails will only survive by gaining acceptance as a viable framework.
As for Java developers that think that Rails is not a good solution for Web development I say they are passing judgment without entertaining the idea. Let's face it, Java is legacy. If you still think that JSF provides rapid development or think WebSphere is a great application server then you probably will not buy into this blog entry. As technologists we need to find and accept better ways to solve problems. Maybe Rails is not the end all solution for Web development. There are many emerging frameworks like Seaside, Django, Lift, Sinatra, Camping and more that believe they have a better mousetrap. This is a sign that people believe that Java is too complicated and over-architected for web development.
Let me summarize by overstating how much Web development has changed. Java developers and Ruby developers need to understand how the JVM can benefit them. Web development using domain specific languages and dynamic languages are hot and over architected Java solutions are not. But there is a middle ground and whether you choose Grails, RoR, or some other framework to simplify your web development you are probably on the right track. Finally, both the Java community and the Ruby community have things to offer each other to secure their survival.
Well off to look at more Scala...
Showing posts with label Ruby on Rails. Show all posts
Showing posts with label Ruby on Rails. Show all posts
Thursday, August 20, 2009
Wednesday, April 30, 2008
Deploying Rails 2.0.2 applications with Tomcat 5.5.x using Warbler
After working with Rails for some time I wanted to determine how to deploy an application on Tomcat. I will discuss how to build a war file that can be used on Tomcat and show pitfalls I experienced along the way. Here are the technologies I am using for this deployment:
I will assume you have Rails installed as a gem in JRuby. To make a standalone war file make sure you run this command to freeze Rails in your project:
$ jruby -S rails:freeze:gems
This will write the standard Rails gem information to your RAILS_ROOT/vendor/rails directory. Here is how you install Warbler from JRuby:
$ jruby -S gem install warbler
After this is configured switch to the root of your Rails project and execute this command:
$ jruby -S warble
This will build an exploded war file in a temporary directory within your project. This path can be changed in the warble.rb file that gets installed. Now create a Warble configuration file by executing this command since we will need it (not sure why this is done after the fact):
$ jruby -S warble config
After generating a configuration file you should consider updating the JRuby jar file that comes with Warble since you will want the latest version packaged with your war file. If you do not do this Warble will always include the original version of the JRuby jar with your war file. Add the jruby-complete-1.1.1.jar file which can be obtained here) to your RAILS_HOME/lib directory. Grab the latest Goldspike jar file and place it in your RAILS_HOME/lib directory. Now add this code to the configuration:
config.java_libs.reject! {
|lib| lib =~ /jruby-complete|goldspike/
}
This allows you to externally package your own versions of JRuby and Goldspike and reject the verions of these jar files that come bundled in the gem directory ($JRUBY_HOME/lib/ruby/gems/1.8/gems/warbler-0.9.5/lib/warbler).
Also, you can delete the exploded directory and the war file by issuing this command:
$ jruby -S warble war:clean
From this point you just move the war file to your Tomcat webapps directory and start the server. This is great when everything works. However, I was lucky enough to run into some issues while making this happen.
The first issue occurred when I started Tomcat with the war file I built with Warble (remember that this is using Goldspike under the covers) and got this error message in the Tomcat logs:
“Could not load Rails. See the logs for more details.”
Yipee! So when I went to look in the Tomcat logs there was no additional information. Great! It turns out that the stack trace output gets swallowed on a Mac. This is fairly easy to fix (but should be patched by the Goldspike team) by modifying the source code for the goldspike-1.6.1.jar file to emit the full stack trace. Grab the latest Goldspike code from here:
svn checkout
svn://rubyforge.org/var/svn/jruby-extras/trunk/rails-integration
You will have to modify src/main/java/org/jruby/webapp/RailsFactory.java like this:
This really is not too big of a deal. You can explain to Warbler what gems need to be packaged with your war file. Here is a snippet from my warble.rb file that shows how I included the missing gems:
# Gems to be packaged in the webapp. Note that Rails
# gems are added to this list if vendor/rails is not
# present, so be sure to include rails if you overwrite
# the value
config.gems = ["activerecord-jdbc-adapter", "jruby-openssl", "activerecord-jdbcmysql-adapter", "jdbc-mysql"]
Alright re-warble and... still no connectivity. Awesome! This time I was missing my MySQL jar file in my war file and the activerecord-jdbcmysql-adapter gem could not communicate with the implementation jar. To fix this copy your MySQL jar file to the RAILS_ROOT/lib directory in your Rails project.
One more re-warbling and more good news:
“Rails Error: No :secret given to the #protect_from_forgery call. Set that or use a session store capable of generating its own keys (Cookie Session Store)”.
This is a known bug with Goldspike and Rails 2.0. So edit your web.xml file and add the following:
I would also suggest increasing the Java memory setting in the JAVA_OPTS of Tomcat to at least -Xmx512m to improve performance. Also keep in mind that Warble is configured to use the production environment for your Rails application so make the appropriate migrations before starting the application. You can make further modification to the Goldspike configuration within the warble.rb file to tweak the pool of Rails runtimes. Once I made these changes it was pretty transparent where I was running my Rails application.
I hope this saves other people time when running into issues. This was kind of a frustrating process since it should be a simple one line deployment. However, I was happy with the end results.
- JRuby 1.1.1
- Rails 2.0.2
- Warbler 0.9.5
- MySQL 5.0.4
I will assume you have Rails installed as a gem in JRuby. To make a standalone war file make sure you run this command to freeze Rails in your project:
$ jruby -S rails:freeze:gems
This will write the standard Rails gem information to your RAILS_ROOT/vendor/rails directory. Here is how you install Warbler from JRuby:
$ jruby -S gem install warbler
After this is configured switch to the root of your Rails project and execute this command:
$ jruby -S warble
This will build an exploded war file in a temporary directory within your project. This path can be changed in the warble.rb file that gets installed. Now create a Warble configuration file by executing this command since we will need it (not sure why this is done after the fact):
$ jruby -S warble config
After generating a configuration file you should consider updating the JRuby jar file that comes with Warble since you will want the latest version packaged with your war file. If you do not do this Warble will always include the original version of the JRuby jar with your war file. Add the jruby-complete-1.1.1.jar file which can be obtained here) to your RAILS_HOME/lib directory. Grab the latest Goldspike jar file and place it in your RAILS_HOME/lib directory. Now add this code to the configuration:
config.java_libs.reject! {
|lib| lib =~ /jruby-complete|goldspike/
}
This allows you to externally package your own versions of JRuby and Goldspike and reject the verions of these jar files that come bundled in the gem directory ($JRUBY_HOME/lib/ruby/gems/1.8/gems/warbler-0.9.5/lib/warbler).
Also, you can delete the exploded directory and the war file by issuing this command:
$ jruby -S warble war:clean
From this point you just move the war file to your Tomcat webapps directory and start the server. This is great when everything works. However, I was lucky enough to run into some issues while making this happen.
The first issue occurred when I started Tomcat with the war file I built with Warble (remember that this is using Goldspike under the covers) and got this error message in the Tomcat logs:
“Could not load Rails. See the logs for more details.”
Yipee! So when I went to look in the Tomcat logs there was no additional information. Great! It turns out that the stack trace output gets swallowed on a Mac. This is fairly easy to fix (but should be patched by the Goldspike team) by modifying the source code for the goldspike-1.6.1.jar file to emit the full stack trace. Grab the latest Goldspike code from here:
svn checkout
svn://rubyforge.org/var/svn/jruby-extras/trunk/rails-integration
You will have to modify src/main/java/org/jruby/webapp/RailsFactory.java like this:
After you rebuild the Goldspike jar add it to your RAILS_ROOT/lib. Now re-warble your war file and put it on your Tomcat server. Now you should be able to find your error. In my case I was not making a connection to my database. I was clearly missing gems in my war file. Great!
} catch (RaiseException e) {
//added this line so the full stack trace is shown
e.printStackTrace();
logRubyException("Failed to load Rails", e);
throw new ServletException(
"Could not load Rails. See the logs for more details.");
}
This really is not too big of a deal. You can explain to Warbler what gems need to be packaged with your war file. Here is a snippet from my warble.rb file that shows how I included the missing gems:
# Gems to be packaged in the webapp. Note that Rails
# gems are added to this list if vendor/rails is not
# present, so be sure to include rails if you overwrite
# the value
config.gems = ["activerecord-jdbc-adapter", "jruby-openssl", "activerecord-jdbcmysql-adapter", "jdbc-mysql"]
Alright re-warble and... still no connectivity. Awesome! This time I was missing my MySQL jar file in my war file and the activerecord-jdbcmysql-adapter gem could not communicate with the implementation jar. To fix this copy your MySQL jar file to the RAILS_ROOT/lib directory in your Rails project.
One more re-warbling and more good news:
“Rails Error: No :secret given to the #protect_from_forgery call. Set that or use a session store capable of generating its own keys (Cookie Session Store)”.
This is a known bug with Goldspike and Rails 2.0. So edit your web.xml file and add the following:
<context-param>OK, please just one more re-warbling and deployment to Tomcat and a successful standalone war file has been created and deployed. *birds singing*
<param-name>jruby.session_store</param-name>
<!-- This value really means let Rails take care
of session store -->
<param-value>db</param-value>
</context-param>
I would also suggest increasing the Java memory setting in the JAVA_OPTS of Tomcat to at least -Xmx512m to improve performance. Also keep in mind that Warble is configured to use the production environment for your Rails application so make the appropriate migrations before starting the application. You can make further modification to the Goldspike configuration within the warble.rb file to tweak the pool of Rails runtimes. Once I made these changes it was pretty transparent where I was running my Rails application.
I hope this saves other people time when running into issues. This was kind of a frustrating process since it should be a simple one line deployment. However, I was happy with the end results.
Saturday, December 15, 2007
NetBeans 6.0 and Rails
I have been looking for a good Rails IDE and think I have found one. I was using TextMate which has lots of great quick templating commands for Rails concepts for migrations, rhtml, and navigating between files and methods. However, I enjoy working with IDEs and tried some Eclipse based versions but felt that they were inadequate. My paying job at the time is mostly Java based and I use IntelliJ which makes my development more productive for that type of development.
I had not looked at NetBeans in some time because most Java developers were using Eclipse and that was fine for me at the time. So when I saw that NetBeans had a Rails related version of their IDE I was willing to give it another look. I can only say that for me this is a very nice IDE that has full functionality around the way I develop with Rails. Here are some of the features I find handy:
A simple IDE layout for components that is similar to IntelliJ. There are no unnecessary perspectives that Eclipse users have.
Support for auto-completion of methods with rdoc helpers.
Debugging capabilites that are simple to use.
Integration with version control repositories like Subversion. Tools to manage your Gems and Plugins from the Tools menu Easy navigation between Rails controllers and views as well as opening files via keystrokes. Decent refactoring built in Generators for creating Rails components. Menus to run Rake and Migration scripts Built in functionality to start a Rails console from your project It works great on my Mac and much more than I expected...
Just to whet your appetite to get you more excited about this IDE here are a couple of screenshots from how I use this IDE:
Here is what it looks like when editing files with code completion and quick docs:

And here is a shot of what debugging looks like in NetBeans:

If you are working on a Mac make sure you look at this link for setting up the fast debugger gem. You will also need to have XCode installed for compilation.
I think you will agree that this is the best IDE for Rails at this time.
I had not looked at NetBeans in some time because most Java developers were using Eclipse and that was fine for me at the time. So when I saw that NetBeans had a Rails related version of their IDE I was willing to give it another look. I can only say that for me this is a very nice IDE that has full functionality around the way I develop with Rails. Here are some of the features I find handy:
Just to whet your appetite to get you more excited about this IDE here are a couple of screenshots from how I use this IDE:
Here is what it looks like when editing files with code completion and quick docs:

And here is a shot of what debugging looks like in NetBeans:

If you are working on a Mac make sure you look at this link for setting up the fast debugger gem. You will also need to have XCode installed for compilation.
I think you will agree that this is the best IDE for Rails at this time.
Subscribe to:
Posts (Atom)