Showing posts with label Java vs. Ruby on Rails. Show all posts
Showing posts with label Java vs. Ruby on Rails. Show all posts

Wednesday, May 18, 2011

Benefits of Programming in Ruby on Rails


There are several programming languages that to-be programmers (or current programmers) can choose from. For first-time programmers, choosing a programming language can be difficult. There are many programming languages that are dying out, just aren’t popular, or are just generally hard to learn. It would be a shame for any first-time programmer to purchase books to learn a language to find that it is too difficult. It would also be a shame to learn a programming language that has no application at work. Ruby is a great programming language because it offers a great feature called Ruby on Rails. Rails is a web framework that can be used by programmers to speed up development.
The programming language, Ruby, was created in the mid 1990’s in Japan, by Yukihiro “Matz” Matsumoto. Ruby is based on Perl, Smalltalk, Eiffel, Ada, and Lisp and was written to create a programming language that, according to Matsumoto, “was more powerful than Perl, and more object-oriented than Python.”
One of the goals of Ruby is to allow the simple and fast creation of web applications. The language itself satisfies this goal. Because of this, there is much less tedious work with this language than many other programming languages. Ruby is also free of charge. It is also free to copy, use, modify, and distribute. Since Ruby can be modified, programmers can make necessary changes and can code without feeling restricted. Another feature of Ruby is its mark-and-sweep garbage collection which allows programmers the ability to code without having to worry about the need to maintain reference counts in extension libraries. Also, if an operating system allows for it, Ruby can dynamically load extension libraries. Ruby currently ranks as the 9th most popular programming language in the world. There are many online guides where Ruby programmers to-be can learn how to program in Ruby.
Ruby on Rails, often simply called Rails, is an open source web application framework that was designed for Ruby by David Heinemeier Hansson and was released in July 2004. Ruby on Rails makes use of an object relational mapping layer known as the ActiveRecord. Because of this, programmers do not have to specify database column names in class definitions. Rails will retrieve this information on its own from the database based on the class name. Rails also has a testing framework built in which allows programmers to write test cases which helps them create more reliable, robust code.

Monday, April 25, 2011

PHP vs Java vs Ruby


This week, a lot of focus is on the other open frameworks that have risen during the same era, and their comparative value in a post open source Java world. One such take is from well-known Sun insider, Tim Bray, who spoke at last week's International PHP Conference in Germany.

Bray, who is Director of Web Technologies at Sun Microsystems, co-creator of theXML 1.0 and XML Namespace standards, co-founder of Open-Text, and contributor to the Atom Publishing standard (whew!) spoke in a presentation entitled “How to combine PHP technology with Java based on Enterprise Systems” .
In the slide below, Bray outlines the basic advantages of each of these three platforms (or rather the two languages and one framework if you are scoring at home). In perhaps in a nod to his new employer, Sun, Bray totally omits any mention of .NET or smaller products like Adobe's Flex/ColdFusion platform.
His idea, if you are able to take it on the surface only, is to rate your priorities of: 1) Scalability, 2) Dev Speed, 3) Dev Tools, and 4) Maintainability. In this highly generalized approach, you could theoretically pick your web application building language/framework based on only these priorities.
Tim weighs-in heavy on the maintainability side, and we'd tend to agree with him. To quote:
“Good apps, once built, tend to be in production for an astonishingly long time. Which means that they have to be maintained for an astonishingly long time. Which means that maintainability is important. There are a lot of things that go into maintainability, but I suggest that the biggies are object-orientation, MVCarchitecture, code readability, and code size.”
On the maintainability side Tim places Ruby on Rails out front. Quoting him again, Tim describes why RoR is in the lead here.
“Mostly because there's less code. The fact that Ruby forces MVC on you helps too, also the fact that the templating and [Object Relational Mapping (ORM)] and testing and application code are all so tightly integrated helps. Bear in mind that we still don't know how well Rails is going to work outside of the CRUD-centered greenfield app space where it shines.”
Tim's metrics don't really exist on a quantitative level nor are they based on any published statistics — just a very informed intellect and a privileged position. Obviously, additional parameters such as total cost of ownership and native security (PHP, we are looking at you) should also play a big role the decision making process.
As you can probably guess, in response to this presentation, the proponents of Java,PHP and Ruby are lighting the Internet aflame in defense of their platform of choice and at the same time nay-saying their fellow players. While very entertaining and sometimes educational to follow, not much is going to be gained from this bickering.
Bray concludes the presentation with the Rodney King-esque statement “One way or another we all have to integrate.”
The reality is that there are a great number of ways to hone-in on the language or framework choice for a web application. Many factors have to be considered and weighed against each other. The beauty of what we have today is that there ARE a great many choices out there, much more-so than even a few years ago.
The fact that open source options are being stacked up against the likes of Java and .NET, and have a similar levels of support is a blessing. Today, with the open-sourcing of Java, we have a new entry onto the field. Rather than exclude one or another, this arrival is going to make the open source web world, warmer, more sophisticated, and for better or worse, a little sunnier.

Ruby for the Java world


Ever since the invention of the computer, software development has been trending towards higher-level languages. From assembly language, to C, to C++, to Java, each step up has met with the same criticisms from the old guard: it's slow; it's buggy; developers don't want to lose control. But gradually, as hardware has sped up, and new research and development has improved compilers, interpreters, and virtual machines, developers have inevitably migrated to the higher level, enhancing their productivity by freeing themselves from lower-level concerns
Java now holds the lead in many areas of software development, but dynamic languages threaten to bypass it in this inexorable climb. Languages such as Python, Perl, Rexx, Groovy, TCL, and Ruby have been doing yeoman service in specialized domains such as file processing, test automation, software builds, glue code, and Web GUIs for years—hence, their historic name "scripting languages." But in the last few years, they have been making headway in the heavy-duty jobs once reserved mostly for C++, Java, and other compiled languages.
In the last year, the Ruby on Rails (RoR) Web framework has given Ruby a big boost. RoR builds definitions for all tiers of a typical Web application—GUI, business logic, and persistence—from simple Ruby code, thereby minimizing redundancy, boilerplate code, source-code generation, and configuration. RoR's ease of use showcases the Ruby language; and Ruby, a full-fledged software language, has much more to offer than RoR.
As a long-time Java developer, I am likely to stick with Java for some time to come. But I keep my eye on other languages that can play a role in my Java-based systems, and Ruby has recently emerged as a particularly good candidate. With the help of the JRuby interpreter, Ruby works well with Java, configuring, integrating, and reusing Java software (more on that below). And simply learning Ruby has improved my Java code. Ruby lets me easily accomplish techniques such as functional programming and metaprogramming, which in Java I can only do with difficulty. Learning these techniques in Ruby has helped me better appreciate when and how to use them in Java development.
With this article, I hope to share with you some of my excitement about what Ruby can do for my Java-based systems. I compare the strengths and weaknesses of both Java and Ruby, and present the pros and cons of the JRuby interpreter. I also show where to best draw the dividing line between Java and Ruby to benefit from each. I illustrate these points with code samples and present a messaging example that shows how to integrate Java systems with Ruby, putting to good use the flexibility, expressiveness, and power of a dynamic metaprogrammable language.

Ruby vs. Java

This article explains Ruby from the Java developer's viewpoint, focusing on a comparison between the two languages. Like Java, Ruby is a full-featured object-oriented language. But there are many significant differences. Ruby is dynamically typed and runs in a source-code interpreter, and it conveniently supports metaprogramming as well as the procedural and functional paradigms. I won't go into details of Ruby syntax, since that subject has been covered extensively elsewhere.

Dynamic typing

Java has static typing. You declare the type of each variable, and then, during compilation, you get an error message if you use a variable of the wrong type. Ruby, on the other hand, has dynamic typing: You don't declare types for variables or functions, and no type-check occurs until runtime, when you get an error if you call a method that doesn't exist. Even then, Ruby doesn't care about an object's class, just whether it has a method of the name used in the method call. For this reason, the dynamic approach has earned the name duck typing: "If it walks like a duck and quacks like a duck, it's a duck."
Listing 1. Duck typing
class ADuck
def quack()
puts "quack A";
end
en d
class BDuck
def quack()
puts "quack B";
end
en d
# quack_it doesn't care about the type of the argument duck, as long
# as it has a method called quack. Classes A and B have no
ck end
# inheritance relationship. def quack_it(duck) duck.qu
a
a = ADuck.new
b = BDuck.new
ack_it(b)
quack_it(a) q
u


Java also lets you achieve dynamic typing, using reflection, but this clumsy and verbose workaround produces confusing exceptions like NoSuchMethodError and InvocationTargetException; in practice, these exceptions tend to pop up in reflective Java code far more often than the equivalents in Ruby.
Even in nonreflective Java code, you often lose static type information. For example, execute() methods in the Command design pattern must return Object rather than a specific type in pre-Java 5 code, resulting in ClassCastExceptions. Likewise, when signatures change between compile-time and runtime, runtime Errors ensue. In practice, whether in Java or Ruby, such errors rarely cause severe field bugs. A strong unit test suite—which you need anyway!—generally catches them in time.
Ruby's dynamic typing means you don't repeat yourself: How often in Java have you had to suffer through verbose code along the lines of XMLPersistence xmlPersistence = (XMLPersistence)persistenceManager.getPersistence();? Ruby eliminates the need for the type declaration and casting (as well as parentheses and semicolon): a typical Ruby equivalent would be xmlPersistence = persistence_manager.persistence.
Ruby's dynamic typing does not mean weak typing—Ruby always requires you to pass objects of the correct type. Java, in fact, enforces types more weakly than Ruby. For example, Java evaluates "4" + 2 as "42", coercing the integer to a string, while Ruby throws a TypeError, telling you it "can't convert Fixnum into String." Likewise, Java, sacrificing correctness for speed, can silently overflow an integer operation, producing weirdness such as Integer.MAX_VALUE + 1, which equalsInteger.MIN_VALUE, while Ruby simply expands integers as needed.
Despite Ruby's advantages, Java's static typing does give it one ability that leaves it as the preferred choice for large-scale projects: Java tools understand code at development-time. IDEs can trace dependencies between classes, find usages of methods and classes, auto-complete identifiers, and help you refactor code. Though parallel Ruby tools exist with limited functionality, they lack type information and so cannot perform all these tasks.

Interpreted language

Ruby runs in an interpreter, so you can test code without a distracting wait from the compiler; you can even run Ruby interactively, executing each line as you type it. Besides the fast feedback, interpreted languages have a rarely noted advantage in dealing with field bugs. With compiled languages, to analyze the code causing a field bug, the field engineer must determine the deployed application's exact build version and then look up the code in the source-code configuration management system. In real life, often this is simply impossible. With interpreted languages, on the other hand, the source code is immediately available for analysis and even, when necessary, for emergency on-the-spot fixes.

Interpreted languages have an unfortunate reputation for slowness. Compare the history of Java, a "semi-compiled" language: In the early years, the JVM always interpreted the bytecode at runtime, which contributed to Java's reputation for slowness. Yet Java developers quickly learned that most applications spend most of their time waiting on the user or network I/O and the remaining bottlenecks are best optimized in higher-level algorithms, rather than in raw low-level tweaks. Over the years, Java rapidly gained speed; for example, just-in-time compilers with optimization based on dynamic analysis sometimes allow Java to outdo C++, which is limited to optimization based on static compile-time analysis.
Already, for most applications, Ruby is no slower than other languages. In the near future, Ruby will get a further boost as Ruby's native interpreter moves to a bytecode-based system and the JVM JRuby interpreter gains the ability to compile Ruby to Java bytecode. Eventually, any performance lag will gradually become negligible for most functionality.

Functional programming

Ruby supports multiple programming paradigms with equal ease. In addition to its pure object-oriented style (even integers and the like are objects), it also supports a procedural style suited to one-off scripts: you can write code outside any class or function, as well as functions outside any class. (Ruby silently adds these functions to the Object class, maintaining the object-orientation behind the scenes.)
Most interestingly, for Java programmers looking for new and useful perspectives, Ruby supports the functional paradigm. You can use most functional programming constructs in Java, with some support from libraries such as Jakarta Commons Collections, but the syntax is clumsier. (See "Functional Programming in the Java Language" by Abhijit Belapurkar and Jakarta Commons Collections in Resources.) Ruby, though not a purely functional language, treats functions and anonymous blocks of code as full citizens of the language, which can be passed around and manipulated like any ordinary objects.
In Java, you often iterate over a collection's Iterator, running the logic on each element. But the iteration is just an implementation detail: in general, you are just trying to apply the same logic to each element of a collection. In Ruby, you pass a code block to a method that does just that, iterating behind the scenes. For example, [1, 2, 3, 4, 5].each{|n| print n*n, " "} prints the string 1 4 9 16 25; an iterator takes each element of the list and passes it into the code block as the variable n.
Functional programming is useful in wrapping code blocks with instructions to be executed before and after the block. For example, in Java, you can use the Command design pattern to ensure the opening and closing of a file, database transaction, or other resource. This burdens the code with the useless overhead of an anonymous inner class and callback method; in addition, there is the distracting rule that variables passed into the anonymous Command class must be declaredfinal. And to ensure that logic always executes at the end of a code block, the whole thing must be wrapped withtry{...}finally{...}.
In Ruby, you can wrap any function or code block, with no need for anonymous classes or method definitions. In Listing 2, the file opens, then closes after the write() method. No code is needed beyond the transaction() method and the code block.
Listing 2. Wrap a code block
File.open("out.txt", "a") {|f|
f.write("Hello")
}


Metaprogrammable language

You generally define your Java classes as source code, but you can also manipulate class definitions at runtime. This requires advanced techniques such as bytecode enhancement during class-loading. Hibernate, for example, inserts data-access logic directly into the business objects' bytecode, saving the application programmer from coding the extra data-access layer. But class manipulation, called metaprogramming, is practical only for infrastructure programmers: application programmers cannot usefully introduce these tricky and fragile techniques.
Even at development time, Java limits the developers' ability to change classes. To add an isBlank() method that tells you if a String is all white space, you'd have to add a StringUtils class with the static method (as Apache Commons does); logically, the new method belongs in String.
In Ruby, on the other hand, you can simply extend the built-in String class with a blank? method. In fact, because in Ruby everything is an object, you could even augment the Fixnum class, the equivalent of Java's primitive int, as shown in Listing 3.
Listing 3. Add method to built-in classes String and Fixnum
class String
# Returns true if string is all white space.
# The question mark indicates a Boolean return value.
def blank?() !(self = /\S/) end
en d
class Fixnum
# Returns 0 or 1 which in Ruby are treated as false and true respectively.
def odd?() return self % 2 end
en d
puts " ".blank? # true
# The next line evaluates if-then similarly to Java's ternary operator ?:
puts (if 23.odd? then "23 odd" else "23 even" end)


JRuby: Ruby in a Java world

As a Java programmer, you won't want to use Ruby in production until you can get it to interact with existing Java applications and libraries, which hold within them a tremendous variety of essential functionality. JRuby, an open source Ruby interpreter for the JVM, simplifies Ruby-Java integration. You can call Java libraries from Ruby, script Java applications with an embedded interpreter, or even use Ruby libraries from Java. Exactly the same Ruby code runs in JRuby and the standard Ruby interpreter, except where Ruby code calls into native (C-coded) or Java libraries.
The JVM is often contrasted with .Net's multilanguage Common Language Runtime as supporting only a single language. But in fact, the JVM executes not only Java, but also Python, JavaScript, Groovy, Scheme, and many other languages, which means that where necessary, Ruby code can interact with these languages as well
As of mid-July 2006, JRuby remains in prerelease mode (version 0.9). But it's catching up rapidly: a team of volunteers has released five versions since January 2005. JRuby's maturity is continually evaluated with a test suite that calibrates it against the standard interpreter, and it now passes more than 90 percent of the tests plus provides basic support for Ruby on Rails.
To try JRuby, be sure that Java SE 5 is installed and that JAVA_HOME is set. (Java Runtime Environment 1.4 was supported in JRuby 0.8.3 and below; it will be supported from the next patch release after 0.9.) Download the compressed file from the project's page and uncompress it. Set the JRUBY_HOME environment variable to the JRuby base directory. You can experiment interactively with jirb in the bin directory. For most purposes, you'll use the jruby interpreter—create a file and pass its name as a parameter to the jruby batch/shell script in directory bin.
In addition to running ordinary Ruby code, you can also use JRuby to construct Java objects, call Java methods, and inherit from Java classes. A Ruby class can even implement Java interfaces—necessary for statically calling Ruby methods from Java.
To initialize the libraries used for accessing Java from Ruby, start with require "java". Then specify the Java classes to use with the include_class method, for example, include_class "javax.jms.Session". You can include an entire Java package into a Ruby module with include_package. Like Java's wildcard package-import statement, it's advisable to avoid the namespace pollution of include_package; in JRuby, there is the additional penalty of a performance hit as the interpreter searches all packages for the desired class. Stick to include_class where possible.
The names of many Java standard classes overlap with the names of Ruby classes. To resolve collisions, pass a code block into the include_class function, returning a new name for the Java class, and JRuby will use this as an alias (see Listing 4).
Listing 4. Include a Java class with clashing name
require "java"
# The next line exposes Java's String as JString
include_class("java.lang.String") { |pkg, name| "J" + name }
s = JString.new("f")


Alternatively, you can create a Ruby module that includes the Java class definitions, but in a separate namespace. For example:
Listing 5. Java module importing multiple Java classes
require "java"
module JavaLang
include_package "java.lang"
end
s = JavaLang::String.new("a")


What's JRuby good for?

Dynamic languages like Ruby are most commonly used for specialized areas such as gluing other systems together; JRuby takes on this role in the Java world. For example, JRuby can pull data from one system, transform it and insert it into another. When the requirements change, modifying a JRuby script is as easy as changing a configuration file, thereby avoiding the complex compile-and-deploy cycle of Java integration code.
In addition to calling Java from Ruby, you can call Ruby from Java, making your application scriptable. With JRuby's minimal syntactic overhead, you can create an easy-to-use domain-specific language for users to work with For example, a gaming engine's scripting system can present Ruby classes describing characters, vehicles, and other game entities.
Moreover, with Ruby's dynamism, users can change definitions of scriptable classes. The Ruby objects allow direct method access to state and behavior. With Java, on the other hand, you typically pass around a Map with user-configurable keys, lacking the full functionality of objects.
A Ruby script is like a souped-up configuration file. Configuration for Java applications typically comes in an XML or properties file, but these are limited only to parameters decided on at development time. With a Ruby script fed to your scripting system either from a text file or from an embedded editor, the user can freely customize behavior wherever you choose to place a scripting hook. In this way, Ruby combines configuration with behavior, providing the functionality of Java plug-in APIs, but without a Java IDE or a compiler, and sparing the additional steps of building and deploying jar files.
For example, a user-provided script can hook into an application's management events to filter for certain suspicious conditions, then send a notification to a system administrator and log into a special security-issues database, or a start-up script can purge old files and reinitialize custom datastores. Likewise, many rich clients allow users to change the position of menus and toolbars—with a JRuby hook, a user's new menu items trigger any behavior the user wants.
For convenience in scripting Java applications, the Bean Scripting Framework (BSF) provides a standard interface between the JVM and multiple dynamic languages, including Ruby, Python, BeanShell, Groovy, and JavaScript; Java Specification Request (JSR) 223, the successor of BSF, will be a standard part of Java 6. The Java code can send variables into the JRuby namespace; JRuby can manipulate these Java objects directly or return a value back to Java. With the BSF and JSR 223, the syntax for interoperation between Java and any scripting language is the same. Listing 6 shows a basic example of BSF use with Ruby, and the full code is in the online samples under the directory bsf_example. Note that BSF does not include JRuby support out of the package; but simple instructions for adding it are available in the JRuby documentation.

To Ruby From Java


Java is mature. It’s tested. And it’s fast (contrary to what the anti-Java crowd may still claim). It’s also quite verbose. Going from Java to Ruby, expect your code size to shrink down considerably. You can also expect it to take less time to knock together quick prototypes.

Similarities

As with Java, in Ruby,...
  • Memory is managed for you via a garbage collector.
  • Objects are strongly typed.
  • There are public, private, and protected methods.
  • There are embedded doc tools (Ruby’s is called RDoc). The docs generated by rdoc look very similar to those generated by javadoc.

Differences

Unlike Java, in Ruby,...
  • You don’t need to compile your code. You just run it directly.
  • There are several different popular third-party GUI toolkits. Ruby users can try WxRubyFXRubyRuby-GNOME2, or the bundled-in Ruby Tk for example.
  • You use the end keyword after defining things like classes, instead of having to put braces around blocks of code.
  • You have require instead of import.
  • All member variables are private. From the outside, you access everything via methods.
  • Parentheses in method calls are usually optional and often omitted.
  • Everything is an object, including numbers like 2 and 3.14159.
  • There’s no static type checking.
  • Variable names are just labels. They don’t have a type associated with them.
  • There are no type declarations. You just assign to new variable names as-needed and they just “spring up” (i.e. a = [1,2,3]rather than int[] a = {1,2,3};).
  • There’s no casting. Just call the methods. Your unit tests should tell you before you even run the code if you’re going to see an exception.
  • It’s foo = Foo.new( "hi") instead of Foo foo = new Foo( "hi" ).
  • The constructor is always named “initialize” instead of the name of the class.
  • You have “mixin’s” instead of interfaces.
  • YAML tends to be favored over XML.
  • It’s nil instead of null.
  • == and equals() are handled differently in Ruby. Use == when you want to test equivalence in Ruby (equals() is Java). Use equal?()when you want to know if two objects are the same (== in Java).

Monday, March 21, 2011

Ruby On Rails Job Trends


Less is more for Ruby on Rails, inventor says

The goal is to keep Ruby on Rails fast, lightweight and easy to use, characteristics that have helped it become a trendy alternative to Sun Microsystems Inc.'s Java and Microsoft Corp.'s .Net, and led to a raft of companies offering Rails development services for businesses.
"We're going to pull out a fair number of elements, features that aren't a good fit for what people want to do most of the time, and make them plug-ins instead," Heinemeier Hansson said in an interview. "If your application absolutely depends on them you won't be stranded, you'll be able to get the plug-ins easily."
Among the elements to go will be Action Web Service, for creating Web service APIs using SOAP (Simple Object Access Protocol), Hansson said. It's a way of steering developers towards using REST (Representational State Transfer), his preferred method for linking applications in Rails.
"We don't want to turn into Java -- this pack rat that just holds onto any possession. We're not afraid to take out stuff that's not relevant or that we plain don't like," he said.
There will be some additions -- the Rails team has some "pent up stuff" in the repository that it's keen to push out, he said. But the focus of Rails 2.0 is to "consolidate and sharpen" what's already there.
Keeping the framework light and simple comes at a price, however, and many companies are jumping in to offer Ruby on Rails packages that bundle tools and plug-ins to make the framework more suitable for demanding business needs. Many of those products will be on show at RailsConf 2007 in Berlin in two weeks.
Borland Software Corp.'s CodeGear division is expected to release its Ruby on Rails Java IDE at the show, Heinemeier Hansson said. The product is based on the Eclipse platform and has been in beta since May. Sun Microsystems Inc. will likely give an update on JRuby, an implementation of Ruby for Java environments.
The vendor support helps quell jitters among corporate users that Ruby on Rails is not backed by a large company. If the prominent support of Oracle Corp. and IBM Corp. helped get Linux in the door at big enterprises, the support from Sun and IBM for Rails could do the same.
Java and .Net have become "bloatware" as vendors add features for every possible business need, causing companies to look at alternatives, according to Cyndi Mitchell, managing director for ThoughtWorks Studios, which offers software and services for Rails development.
The rise of Rails is as much a matter of timing as anything, she said. "This bloatware stuff has just ground to a halt and the alpha geeks are veering away from anything they don't need to get their work done. At the same time the IT business cycle is picking up and people are willing to invest again in new things," she said.
Her clients are telecom, media and finance companies looking for a fast turnaround for new applications. Most are deploying in native Ruby environments, but it helps that Sun is supporting JRuby, she said, which lets companies deploy Rails applications on existing Java servers.
Jonathan Siegel, founder of Rails consulting company ELC Technologies, said applications that would take eight to 10 months to develop in .Net can be up and running in four to six months using Ruby on Rails.
Still, at three years old Rails is a young platform and has limitations. One high-profile user, the Twitter social networking site, caused a stink earlier this year by complaining that Rails didn't scale well across multiple databases, and that the underlying Ruby language is slow. The open-source community responded by developing a plug-in to address the scaling issue.
Some also say that both Ruby and Ruby on Rails need a stronger hand to steer them, to prevent multiple implementations leading to compatibility issues. "The major risk for the future and longevity of Ruby, and by association Rails, is whether or not the platform gets splintered," Mitchell said.
Siegel said: "I believe Ruby on Rails will overcome a key milestone when the deployment teams at larger organizations feel at home with the deployment side of a Rails application. In my view that's having a deployment procedure that's as easy to maintain and monitor as for a .Net or a J2EE application."
Heinemeier Hansson is nonchalant about the demands. He developed Rails for his own use and not to make money, he says, and if enterprises want to use his framework it is they who should adjust, not he.
"We're not trying to bend Ruby on Rails to fit the enterprise, we're encouraging enterprises to bend to Ruby on Rails," he said. "Come if you like it, stay away if you don't."

Sunday, March 20, 2011

Java vs. Ruby on Rails - It is a Dead Heat


For web technology entrepreneurs in the process of developing a new online service, there are five important choices that must be made regarding web technology. Some of the following choices have options that are mutually exclusive and others that are inseparable. I put server side language first, since in many cases it narrows down the options for the remaining choices:
  1. Server side language: Java, Ruby on Rails, PHP, Python, ASP.NET or other
  2. Database: MySQL, Oracle, PostgreSQL or other
  3. Web server: Apache, IIS, or other
  4. Hosting environment + hosting serviceWindows or Linux +Rackspace, Amazon EC2, Google App Engine, or other
  5. Developer tools: Eclipse, .NET Visual Studio, or other
The issues and pressures web technology entrepreneurs balance when making the aforementioned choices typically have this priority:
  1. Time to market: how long will it take to program the desired features, configure the hosting environment, and deploy the software. Some ideas need to be implemented quickly to capitalize on a time-sensitive opportunity. In addition, the sooner you receive feedback from your user base the sooner you can adjust your business model.
  2. Costs: on a tight budget, free open source software and cheap shared hosting environments are attractive. On the other hand, the licensing costs of enterprise servers and support may be what you need to scale your system.
  3. Long term scalability and growth: how many users can your technology mix support, will you need to switch hosting environments to support a rapid increase in user activity, and how quickly can new programmers learn and be productive with your technology?
In a nutshell, Java is not good for entrepreneurs because it is too complex and too slow to develop, configure, and deploy your web application. Ruby on Rails will get you off to fast start because it excels at time to market and low costs but leaves you hanging when it comes to scalability. Here is my entrepreneurial web technologies report card:
Time to Market:
  • Unit testing: both Java and Ruby provide comprehensive unit testing frameworks for testing objects.
  • Controller testing: I give the edge to Ruby on Rails because you can test your controllers (including aspects of your view templates) side-by-side with your objects without having to rebuild or recompile the rest of your web application. The Cactus Servlet testing framework and StrutsTestCase are not as easy to use as Ruby on Rails' controller testing framework.
  • Rapid feedback: Since Ruby is a scripting language you do not have to recompile (i.e., Java) your code in order to test your changes.
  • Code conventions: Ruby on Rails epitomizes the use of conventions while Java has lots of competing frameworks (e.g., Spring, Struts, JSF) that each like to invent their own conventions.
  • Developer tools: Eclipse offers outstanding developer tools for both Ruby on Rails and Java. Eclipse has slightly better tools for Java including more comprehensive code completion and code generation.
  • Code library complexities: Ruby requires much less thinking when comes to installing plugins, third party components, upgrades, and other libraries. Java library compatibility can be a circular (tail-chasing) mess, especially regarding XML libraries (i.e., JAXB, Xerces, Crimson). Specifically, it can get complicated trying to figure out the order that XML libraries are being loaded into the Java classpath. For example, I used to struggle to understand which versions of Java, Tomcat, and the web services libaries were compatible with each other. Upgrading one of the three might cause a problem with one of the other two. Ruby gems, albeit not flawless, makes it really easy to add and install new libraries and, what's more, the gem tool will prevent you from installing incompatible libraries.
Cost:
  • Software Licensing: Java and Ruby on Rails are can be configured to use 100% open source software and, thus, be free to use forever. However, it is likely that a successful online service will eventually need proprietary software regardless of your server side language. I give the higher mark to Ruby on Rails because Sun allows its proprietary enterprise partners to lead the way with many of the enterprise level software solutions requiring subscription or licensing fees (e.g., JBoss, BEA/Oracle, WebSphere).
  • Hosting services: In my experience, hosting Ruby on Rails is cheaper than hosting Java web applications but that both come a distant second to PHP hosting.
Scalability and Growth:
  • New developer learning curve: as a result of code conventions and limited code library complexity, Ruby on Rails has a much flatter learning curve for newly hired programmers. Specifically, a new developer can get up to speed with a Ruby on Rails web application really quickly by simply reading this book: Agile Web Development with Rails, 2nd Edition
  • Multi-threading: Java application servers allow you to run multiple web applications in a single process with the single process managing the multi-threading with minimal configuration. However, Ruby on Rails mongrel clustering requires that each web application have its own static number of mongrel threads. This a problem because the server's memory use is very inefficient. Specifically, a static number of mongrel processes for each of your rails applications means that daily or hourly fluctuation in site traffic could max out your one of your mongrel clusters or at the very least put an unbalanced load on one of them.
  • Service up-time: during deployment of an updated web application, some of the Java application servers can "automatically manage client connections so that existing clients continue to use the older application, while new client requests are directed to the newer application". On the other hand, anytime I installed an updated Ruby on Rails application, there would be at least 30 seconds where all of my mongrel clusters (i.e., multiple Rails applications) would be out of service. Obviously, I may not have been doing things the best way possible but the point is that Java makes it easier to maintain service up-time.
  • Clustering: In conjunction with multi-threading and service up-time, Java application servers provide comphrensive clustering capabilities whereas Ruby on Rails requires duct-taping Apache and Mongrel together.
  • Command line scripting: for data backups and other asynchronous processes has proven to be unchallenging for both Java and Ruby.
  • International language support: Java has native support for creating web sites that need to serve multiple languages. On the other hand, I have yet to see any international language support from the Ruby on Rails community. If I was going to do a multi-lingual web site, I would not choose Ruby on Rails.
It is a Dead Heat

The results of my entrepreneurial report card show that both Java and Ruby on Rails score a grade point average of 3.07. The report card GPAs resulting in a tie is merely coincidence and is not a product of report card manipulation.

More importantly, Java and Ruby on Rails can both fail you; albeit in different ways. Ruby on Rails can fail you on scalability and Java can fail you on time to market. On the other hand, Google's App Engine is very intriguing because it guarantees scalability and low costs. Unfortunately, it appears to sacrifice time to market because you have to learn and use Python. Specifically, Google encourages you to use their Python webapp framework. Therefore, expert Python developers using Google's App Engine may be able to score straight As on my entrepreneurial report card. Other than that, there does not appear to be a combination of technologies that can score high marks on all of the aforementioned entrepreneurial issues.