Thursday, September 28, 2006

Why Add Syntax When You Have Ruby?

A question came up this morning on the JRuby Users mailing list about a feature Jython and Groovy support: constructors that initialize bean attributes. The example given used a JLabel:

JLabel(text, bounds = bounds, foreground = color)

Which ends up being roughly equivalent to:

x = JLabel(text)
x.bound = bounds
x.foreground = color

Groovy has a similar syntax I won't illustrate here. So why doesn't Ruby support this, or perhaps why doesn't JRuby automatically support this syntax for Java types?

To answer, let's take a look at what it would take to add this to current Ruby with only existing features.

The equivalent syntax in Ruby or JRuby might look like:

SomeClass.new(text, :bounds => bounds, :foreground => foreground)

...or possibly using a block as in:

SomeClass.new(text) { @bounds = bounds, @foreground = foreground }

However there's no existing accomodation in the semantics of Ruby for these syntax to work out of the box. It would not be hard to write a short bit of code to allow constructing objects in this fashion, of course (using the block approach as an example):

class Class
def construct(*baseargs, &initializer)
x = self.new(*baseargs)
x.instance_eval(&initializer) if initializer
x
end
end

...which would allow the block example above to work fine (with "construct" in place of "new"). For proxied Java objects, which don't actually have ruby instance vars (@whatever above) it would have to be a slightly different call:

JLabel.construct(text) { self.bounds = bounds, self.foreground =
foreground }

This works fine, but it's perhaps a little less beautiful. What about this impl instead?

class Class
def construct(*baseargs)
x = self.new(*baseargs)
yield.each_pair { |k,v| x.send("#{k}=", *v) } if block_given?
x
end
end

Which would allow a variation:

JLabel.construct(text) {{ :bounds => bounds, :foreground =>
foreground }}

(the double {{}} is intentional; the block returns a hash of initializers)

The bottom line is that this kind of syntactic sugar in other languages can easily be added to Ruby through various techniques, and so features like field-initializing constructors don't need to be part of the core language or any of the implementations.

Does anyone still wonder why I love this language?

Monday, September 25, 2006

Interface Implementation Syntax and Open Classes

Tom and I got together and brainstormed the interface implementation issue today. We think we've come up with a reasonably solid solution.

First some background.

As most of you will know, the current way to implement a Java interface with Ruby code is to extend it:

include_class "java.awt.event.ActionListener"

class MyListener < ActionListener
...
end

This works fine for many cases, and it's great for a simple single-interface implementation. However it breaks down if you want to extend either a Java or Ruby class at the same time or if you want to implement multiple interfaces.

A few weeks back, we on the JRuby dev list kicked around the idea of using mixin
inheritance to do interface implementation:

class MyListener
implement ActionListener
end

This has the advantage of allowing you to also extend a class and implement multiple interfaces, but there's a problem here. By the time we encounter MyListener, the class is already created and there's no opportunity to make such drastic changes as modifying the list of implemented interfaces.

In the case above, MyListener is already created as a pure Ruby class by the time we encounter the implement line...we can't then change it into a Ruby/Java proxy class. Even if we had a way to mark it ahead of time as a Java proxy, that proxy would have to be created already by the time we're in the class body. Ruby's unusual way of instantiating classes is to blame: all classes start out "blank" and the class body is basically eval'ed within that blank instance. With Java types, we do not have such flexibility.

So a new option comes into the debate today. It's not as clean, and it's not as Rubyish, but it should support Java typing and Java interface implementation very well:

include_class "java.util.AbstractList"
include_class "java.util.Map"

MapList = AbstractList.implement(Map)

class MyMapList < MapList
...
end

Or the shortcut version:

class MyMapList < AbstractList.implement(Map)

We will probably also continue to allow the single-inheritance shortcuts as well, since they're nice and clean:

class MyListener < ActionListener
end

...which is roughly synonymous with:

include_class("java.lang.Object") { |p, n| "J" + n }

class MyListener < JObject.implement(ActionListener)
end

The logic behind this approach (very similar to that being taken by RubyCLR and IronPython) is that a concrete class plus multiple interfaces as a whole represents a very rigid, specific type in the Java world. We do not have the flexibility to juggle the internals of those types after they're created, so having a very clear-cut way of specifying that combination of concrete + interfaces allows us to satisfy Java's typing requirements. We can then extend that with Ruby code, implement whatever we want, alter behavior, reopen classes, and so on. We're essentially creating a rigid top-level Java type with a "back door" for implementing its behavior with Ruby code under the covers.

We'll certainly want to try to coordinate with other projects addressing this same issue (Ruby.NET, RubyCLR, IronRuby, IronPython, Jython?), since we don't want multiple incompatible syntaxes for this stuff. You out there guys?

Saturday, September 23, 2006

RailsConf Europe 2006: JRuby Slides and Demo Posted

I have posted my slides and demo on headius.com at the following URLs. The demo has some very basic instructions for getting it to work, but I don't plan to support this code in any way. It was fairly hacked together in the days before the conference, so you're on your own getting it working. Whether you can run it or not, however, it's fairly illustrative in how it accesses EJBs, javax.persistence entities, and JMX resources. A taste of things to come.

JRuby On Rails - RailsConf Europe 2006 (Keynote, original) Update: Fixed the URL
JRuby On Rails - RailsConf Europe 2006 (PDF)
JRuby On Rails - RailsConf Europe 2006 (OpenDoc Presentation)
JRuby On Rails - RailsConf Europe 2006 (PowerPoint)

JRuby on Rails Demo (.tar.bz2)

Sunday, September 17, 2006

Conference Updates

Ok, so this post is as much for me as for you (so I have a post to refer back to) but some of you may be interested to know what conferences I'll be at. Things have gotten a bit busier since the Sun announcement.

BarCamp Milwaukee
- September 30 - October 1, Milwaukee WI

I may make the trip down to Milwaukee for their upcoming BarCamp. Hopefully others from the cities will be willing to make the trip with me (and drive :), or I probably won't go.

RubyConf 2006 - October 20-22, Denver CO

Not presenting, but I'll be there and will probably try to organize a lightning session or something.

Gateway JUG - November 7, St Louis MO

The Gateway JUG has offered to fly me in for a JRuby-fest at their November 7 meeting. It ought to be a good sharing of ideas and meeting of the minds. Try visiting the Gateway JUG website if you might be interested in showing up for the meeting.

TC Code Camp - November 11, Bloomington MN

I'll be presenting JRuby and JRuby-related topics to coders at Microsoft's Bloomington campus.

JavaPolis 2006 - December 11-15, Antwerp, Belgium

Tom and I are officially on the schedule to present JRuby (on Rails, perhaps) at JavaPolis 2006. We'll follow that up with our Great Belgian Beer Tour, sampling brews in the Belgian backcountry. What could be better than that?

A Taste of Celebrity...and Pizza

I'm still decompressing a bit after a great conference and 14 hours of transit from London to San Jose, but blogs are starting to trickle in about RailsConf. Here's a particularly notable entry.

I'm still not entirely sure why he wanted a picture of me with his (girl)friend. Maybe it's a German thing?

I promise I'll get around to blogging more tomorrow. Time to de-lag and get some sleep before I'm pummeled with questions from Sun language and VM experts on Monday.

Friday, September 15, 2006

JRuby Get-Together Tonight in London

Yes, today is the day! We will be getting JRubyists together at the Fitzroy near the RailsConf conference center.

Here's a gmap to the Fitzroy. Show up around 6:30-7:00PM and I'll be there!

Friday, September 08, 2006

Pat Eyler: Gathering Reactions to the Sun Move

Pat Eyler has a good wrap up of some reactions around the Net to the recent Sun move.

More FAQs about JRuby and Sun

There's been a lot of buzz about Tom and my new jobs at Sun, and understandably so. The response so far has been overwhelmingly positive, and we're grateful for that. It's all very exciting.

There have been a few questions to come up again and again on blog postings and mailing lists, however, that I figured I could answer. Some are fear, some are uncertainty, and some are doubt, but almost all have good answers. I understand some folks have concerns and want to address those as best I can.

Note, my responses may not be Sun policy, but they're my policy. And I don't bend so easily.

1. Does the Sun move mean Groovy, Jython, BeanShell, and friends are being cut out of the picture? Has Sun chosen a winner in the dynamic languages realm?

Absolutely not, on both counts. I got involved in JRuby for one reason: Ruby was underrepresented in the Java world, and happened to be a very attractive language to me. Jython was fairly well-established and performed quite nicely. Groovy was gaining some traction and seeing an upswing in developer interest. JavaScript was scheduled to be included in Java 6. What about Ruby? JRuby didn't run most Ruby apps, had known major incompatibilities with C Ruby, and performance was very poor. Something had to be done.

I like to solve difficult problems, and JRuby certainly has presented some difficult problems. How do you take an existing interpreter that mostly works and--without breaking it--completely refactor and rewrite its internals to maximize performance and compatibility? Answer: very carefully. JRuby has come a long way this past year, and now we have leave to round things out on an accelerated schedule.

So what then? Naturally there's the tools angle (which I'll address in a moment), but will a JRuby 1.0 release mean the end for JRuby and continuing development of dynlangs on the JVM? Of course not! JRuby will continue to be a learning experience for all involved...inside and outside of Sun. Once we've solved JRuby's issues, why not find a way to raise all ships? Support for invokedynamic, open classes, and closures at the VM level? Hooks for code generation, alternative typing systems, and deeper threading, IO, and memory integration? Seamless cross-app connectivity for dynlangs + Java EE with all the tasty agility we've come to love?

This is only the beginning, my friends!

2. Sun has stated that Charles and Thomas have a mandate to think about/work on developer tools; does this mean Eclipse-based solutions are off the support list?

I want to make this perfectly clear...we will not discriminate between any users of JRuby. JRuby is a community project, first and foremost, and part of cultivating and growing that community is a rigid adherence to non-discriminatory support policies. We would be cutting off our right hand (or in my case, left hand) if we started picking and choosing who "deserves" support and help from the JRuby team. Nobody would benefit and everyone would suffer from such a move.

Of course, as Sun employees, we've got a major interest in ensuring NetBeans provides a world-class IDE for Ruby projects on the Java platform. But we were JRuby developers first, and we know that although we want people to migrate to NetBeans, we'll engender no community love by giving existing, mature Ruby IDE solutions the boot. Remember folks, competition is good. It would just be entirely unfair to deny NetBeans users the distinct joy of Ruby and Rails development. We're going to spread the love.

3. Will Charles and Thomas have to move to California?

Not at all. Tom and I will continue working from the Minneapolis area under Sun's remote-employee programs. You'll certainly see me and sometimes Tom at your favorite Ruby or Java conferences, but we'll continue to make home in flyover country. Moo.

4. Was this move in response to the IronPython 1.0 release this week?

Come on folks, you know how fast HR moves. You honestly think they could officially hire us in less than a month? This move has been in the making for several weeks..and man has it been hard to keep secret. I'm glad the truth is finally out and we can take a deep breath...before really getting down to business. (And really, for a move of this magnitude to only take "several weeks" is impressive by any measure...)

I wish the IronPython guys success...and Jim Hugunin is obviously in a similar position, doing what he loves. Hopefully our differing sponsorship won't get in the way of cross-pollenation and idea sharing. It would be a real shame if being hired to innovate by innovative companies actually hurt the innovation that got us here in the first place.

--

I'll plan to keep up with major questions as they come up. I really want this to be full disclosure, folks, as much as humanly possible. JRuby isn't my project or Tom's project--it's yours. You deserve to be in the loop (zero-day media blitz secrets notwithstanding, of course ;)

Thursday, September 07, 2006

JRuby Steps Into the Sun

It's going to be a big news day for JRuby :)

The two core JRuby developers, myself and Thomas Enebo, will become employees at Sun Microsystems this month. Our charge? You guessed it...we're being hired to work on JRuby full-time.

Perhaps some of you may have seen this one coming. For others, it may be a pleasant surprise.

The primary goal is to give JRuby the attention it really needs. The potential for Ruby on the JVM has not escaped notice at Sun, and so we'll be focusing on making JRuby as complete, performant, and solid as possible. We'll then proceed on to help build out broader tool support for Ruby, answering calls by many in the industry for a "better" or "smarter" Ruby development experience. I'm also making it a personal priority to continue growing the JRuby community, foster greater cooperation between the Java and Ruby worlds, and work toward a "whole-platform" Ruby-on-JVM strategy for Sun.

And yes, JRuby will remain as open source as it is today. It just might start moving a bit faster (as if it weren't moving fast already!)

You can imagine how excited I am about this opportunity, and how pleased I am to know that Sun takes Ruby so seriously. Not only will I get to work on the project I've poured my heart into this past year, but I'll be able to do it while helping one of my favorite companies turn a technological corner. Naturally I've been talking with a myriad of folks at Sun over the past several weeks, so believe me when I say these guys really get it. The tide has turned and dynamic languages are on everyone's agenda. It's going to be quite a ride.

Thanks very much to Tim Bray, who has proven a fearless advocate for Ruby and dynamic languages at Sun. Thanks also to Gilad Bracha, Neal Gafter, James Gosling, Peter von der Ahé, and others fighting to improve Java and make the Java platform a dynlang-friendly place. Thanks also to my Sun interviewers for their excellent, thoughtful questions and ideas about the future of JRuby and dynlangs on the JVM. I'm looking forward to working with you all.

And finally, thanks to all you who use, contribute to, and blog about JRuby. You're a huge part of this, and I want you all to join us on this great Ruby adventure. Community involvement has gotten JRuby where it is today, and community involvement is vital to making Ruby on the JVM a reality.

Updates: I'll list substantive news items and blog postings as they come in (and I'll let your RSS aggregators deliver the one-liner posts ;)

Tim Bray: JRuby Love - Tim lays out some informative FAQs on the Sun move. He was our biggest Sun advocate, so he should know.

InfoQ: Sun Officially Back Ruby, Brings JRuby In-House - Includes a link to the newly-posted presentation we taped for InfoQ this past spring.

Thomas Enebo: JRuby Shines in Sun - My co-conspirator's almost-as-cleverly-named post about the event.

Bloglines Aggregation of JRuby articles - The blogosphere is very busy today!

InternetNews.com: JRuby Developers Join the Sun Fold - Andy Patrizio talks to Tim Bray and I about what this means for JRuby and for Sun.

InfoWorld: Sun picks up a gem in JRuby - Mostly a blog wrap-up, but a few good links and quotes.

Wednesday, September 06, 2006

ActiveRecord-JDBC 0.2.1 Released!

I told you it would only be a couple days!

ActiveRecord 0.2 has been released. (It's actually 0.2.1 because of a minor Gem glitch)

Ola wraps it up in the link above, but for the record it supports normal AR operations and basic migrations for the following databases:

  • MySQL
  • PostgreSQL
  • Oracle
  • HSQLDB
  • Microsoft SQL Server (except for change_column_default)
  • DB2 (except change_column, change_column_default, rename_column, remove_column,
    add_index, remove_index and rename_table)
  • Derby (except change_column, change_column_default, remove_column, rename_column)
  • FireBird (except change_column_default and rename_column)
Whew! And we really only started getting migrations and additional databases into the mix a week or two ago. Things go very fast when you have JDBC to handle all the heavy lifting!

I'm going to demo the AWDwR2 Depot app running on top of MySQL at Rails, and probably demonstrate one of the other databases Rails doesn't normally support as well (Derby perhaps? or SQL Server if I can get Parallels up before presenting?)

Usage

Ola has a Derby walkthrough with some unusual typos [Update: my mistake, he symlinked stuff like "gem" to "jem" to avoid collisions with MRI], but here's my walkthrough for MySQL in ultra-condensed form:
  1. Install JRuby from trunk or my branch
  2. Build it (not necessary once we get another release out)
    ant clean jar
  3. Set up env vars for JRuby
    export JRUBY_HOME=[jruby dir]
    export PATH=[jruby dir]/bin:$PATH
  4. Install Rails
    gem install rails -y --no-rdoc --no-ri
  5. Install ActiveRecord-JDBC
    gem install activerecord-jdbc --no-rdoc --no-ri
  6. Generate a Rails App
    rails ~/testapp
  7. Go to the app
    cd ~/testapp
  8. Modify database.yml
    development:
    adapter: jdbc
    driver: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost/testapp_development
    username: ...
    password: ...
  9. Modify environment.rb:
    require File.join(File.dirname(__FILE__), 'boot')
    require 'active_record/connection_adapters/jdbc_adapter'
  10. Add driver to CLASSPATH
    export CLASSPATH=$CLASSPATH:mysql.jar
  11. Create a testapp_development database, grants for testapp user, and widgets table in MySQL (use migrations if you like)
  12. Scaffold Widgets CRUD
    jruby script/generate scaffold widget
  13. Start up the server
    jruby script/server
And that's about it. You've got a scaffolded widget page running in JRuby over JDBC to MySQL.

Pretty neat, eh?

Troubleshooting
  • ActiveRecord-JDBC does not install: I had some trouble myself; I think something's up with either RubyForge or with our released gem. You can always download ActiveRecord-JDBC and install it locally, of course.
  • scaffold fails with an error about "nonexistent jdbc adapter": Ensure you've added the require line to environment.rb (hopefully this will be unnecessary in the future)
  • scaffold and script/server terminate without running: Make sure you've successfully installed the ActiveRecord-JDBC gem. The additional require in environment.rb causes Rails scripts to die silently if there are any errors.
  • scaffold fails with the error "cannot convert NilClass into String": Make sure you've correctly specified the driver and url lines in database.yml
What's Next

We're going to continue adding database support, especially if you folks can contribute migrations impls for your database of choice. It's fun and easy!

We've also got a patch under discussion to allow adding JDBC database jars to [RAILS_ROOT]/lib and have the driver pick them up automatically. This could obviously be extended to Rails at large for service client jars, persistence framework jars, and so on. No more CLASSPATH manipulation!

We're hoping to get the Rails guys to include "jdbc" in the list of supported adapters out-of-the-box, so that environment.rb require is not necessary.

We're also going to see if there's a way to abstract out all the DDL code in core Rails, so we can all benefit from the same code.

Monday, September 04, 2006

More ActiveRecord Information

Supporting More Databases

A number of folks have asked about support for database X. We want to support all possible databases, of course, and JDBC gives us a huge head start on that. Many databases will only need a bit of tweaking to support all the basic CRUD operations. The additional work...small though it may be...is implementing the schema-manipulating methods of ActiveRecord. Here's a complete list...if you can provide examples for each operation, it would speed our supporting them:

  • add_column
  • add_index
  • change_column
  • change_column_default
  • columns
  • create_table
  • drop_table
  • initialize_schema_information
  • native_database_types
  • remove_column
  • remove_index
  • rename_column
  • rename_table
  • structure_dump
  • table_alias_for
  • table_alias_length
Check available docs for ActiveRecord or look at the existing adapters in ActiveRecord in SVN for examples on each.

Avoiding Modifying active_record.rb

There's now a thread going on the Rails core mailing list and a bug to address the issue of adding adapters to Rails. Hopefully one of two things will come out of this:
  • "jdbc" will be added to the list of adapters available in core Rails
  • a mechanism will be added (or fixed) to allow adding to the list of adapters from outside the core source
The former would be ideal, since no additional, special config changes would be needed for jdbc versus MySQL, for example. The latter would be an "ok" compromise, but would require modifying all apps to add "jdbc" to the adapter list. I'll report back when something comes of it.

Java Regex Broken for Alternation over Large Strings

This is a serious bummer.

I've been working through some of Rails's test cases this evening. Since I've got Depot running reasonably well now and I know I can easily wire together a simple Rails app that calls Hibernate or EJBs, I figured I'd try to get a better handle on the true state of Rails support.

As I'm running test cases--the majority of which appear to be passing, btw--I came across a couple goofy regex issues. The first is one we'd seen before, where dot refuses to match \r. In this case, adding DOT_ALL to the Pattern's flags seems to resolve it. I think we just hadn't noticed that flag before, so many other similar bugs might be resolved the same way. Not an easy issue to narrow down, but I found it and moved on.

So then I started seeing SystemStackErrors popping up within the CGI library. When I see stack overflows in JRuby, I usually figure it's one of two things:

  1. Something's wrong with JRuby that's breaking a termination condition in Ruby code, so a recursion is never ending
  2. JRuby itself is missing a termination and recursing endlessly
Pretty simple issues to track down...find where the recursion is happening, and figure out why it's not terminating. Except in this case, the recursion wasn't in either Ruby or JRuby code. It was in Java's regex library.

Blowing The Stack

O Java, how I love Thee. Every library I could want, all in one place. You care for me so well. It pains me to find your faults.

So it appears that the Java regex library's compiled patterns execute recursively. This alone wouldn't be particularly unusual, especially if the recursion was limited by the complexity of the regex itself. However in this case it seems the recursion is a factor of the string to match, rather than of the expression complexity. With a large enough input string, I can get Java's regex to blow the stack every time.
regex = /\A((?:.|\n)*?)?([\r\n]{1,2}|--)/n
long_string = ""
76.times { long_string += "xxxxxxxxxxxxxxxxxx" }

long_string.sub(r) {""}

This bit of Ruby code will cause java.util.regex.Pattern to blow the stack during matching. I'm sure this regex could be reduced to a simpler case, but I don't really need to go through the exercise of doing so; others have reported the same issue:
So the issue stands, unfortunately. I'm not sure I'd characterize it as an RFE...I'm no regex expert, but I would hope my regex engine wouldn't overflow based on large input, especially if that input was completely bogus as in my example above. I don't think that's unreasonable, especially considering that Ruby's regex engine appears to handle this case (and considerably larger cases) just fine. Correct me if I'm expecting too much.

So what's the damage? Well, since we currently use java.util.regex exclusively, and since Ruby libraries and apps very frequently use regex to match against very large strings, we'll have to migrate to a different regex library. Until that happens, however, Rails under JRuby will not support large multipart posts, at a minimum. There may be other places this has an effect, but multipart posting was the area I investigated.

So for now...I guess it's just busted. We'll begin evaluating alternative regex libraries posthaste. Any help from you folks would be appreciated...just take that regex or one from the bugs and try to match against extremely large input.

Rewrite the Regex?

Some may say that the regex should be rewritten to avoid the use of alternation. Perhaps so, perhaps there's a better way. However Ruby handles it fine, so requesting that the Rails folks or any other Ruby devs start tailoring their regex so they will work under JRuby is quite out of the question. If we can't run the same regex against the same input, we need a different regex library...that's all there is to it.

Besides, the bugs posted have additional regex that are even simpler. It just seems to be a limitation of the Java regex library that certain regex will blow the stack on large input.

For the record, here's the relevant bit of the stack. I get pages and pages of this, under both Java 5 and Java 6 beta 2...both 64-bit under Linux:
...
at java.util.regex.Pattern$Branch.match(Pattern.java:3998)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4052)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4241)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4111)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:3962)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3314)
at java.util.regex.Pattern$Branch.match(Pattern.java:3998)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4052)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4241)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4111)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:3962)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3314)
at java.util.regex.Pattern$Branch.match(Pattern.java:3998)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4052)
...

What a downer.

Sunday, September 03, 2006

Using the ActiveRecord-JDBC Adapter

Ola Bini, Nick Sieger, and others have been making great progress on the ActiveRecord-JDBC adapter lately. I figure it's a good time for a brief update on progress, and a short walkthrough on how to use it.

Where We Are, Where We're Going

There has been one official release of the ActiveRecord-JDBC adapter, a 0.1 that has basic SQL support for MySQL. It's available as a gem called "ActiveRecord-JDBC" (case-insensitive). It provides normal MySQL support for most major ActiveRecord operations today, and it's mostly the same code we used for our JavaOne demo.

Although the JDBC libraries give us plenty of information on database typing and precision, they provide practically nothing for generating DDL. Because of this, a large part of current ActiveRecord capabilities have to be written outside of the JDBC-aware code. DDL differs between databases, so like the core Rails project, we're forced to implement the various schema-related methods of ActiveRecord differently for different database vendors.

Currently, we're just reproducing the same code available in core Rails, with a little manipulation to work with ActiveRecord-JDBC, but we're hoping to work with the Rails team to abstract out the non-driver-specific portions of the core ActiveRecord adapters so the JDBC version can leverage the same code. I'm also hoping we'll be able to get the "jdbc" adapter name added to core Rails in the active_record.rb file where such adapters are listed. This will allow JRuby users to install Rails and the JDBC adapter and immediately start using them, without additional steps.

We are planning a second release of the JDBC adapter very shortly. It should have reasonably solid migrations/DDL support for MySQL, Oracle, and Firebird, as well as some level of support for HSQLDB, Derby, and others. It's moving along quickly now that it's been spun off into its own jruby-extras project. You can go there or to the jruby-extras SVN repository to grab the bleeding-edge source from SVN.

Getting up and running with ActiveRecord-JDBC

Despite the design complexities and our DDL woes, getting an ActiveRecord-based app up and running on JDBC is now very simple. This walkthrough proceeds from a stock JRuby install, and is based on current JRuby trunk (though it may work ok with 0.9.0 as well...we'll have a new release out soon).

  1. Ensure JRuby is set up and working correctly via the normal setup procedures
  2. gem install rails -y --no-rdoc --no-ri (ri and rdoc generation are still too slow under JRuby)
  3. gem install ActiveRecord-JDBC --no-rdoc --no-ri (this is the 0.1 version for now, but hopefully we'll have 0.2 out this week)
  4. Edit lib/ruby/gems/1.8/gems/activerecord.../lib/active_record.rb, adding jdbc to the list of RAILS_CONNECTION_ADAPTERS toward the bottom of the file:
    RAILS_CONNECTION_ADAPTERS = %w( jdbc mysql postgresql sqlite firebird sqlserver db2 oracle sybase openbase )
  5. Modify database.yml for your settings. For example, using MySQL:
    development:
    adapter: jdbc
    url: jdbc:mysql://localhost/testapp
    driver: com.mysql.jdbc.Driver
    username: testapp
    password: testapp
  6. As always, ensure the appropriate JDBC jar files are in your CLASSPATH
That's pretty much all there is to it. We'll get that second release out in a day or two so that migrations work and additional databases are supported, but these instructions won't change. I'll post here when that release is out.

How Well Does It Work?

It seems to work very well so far. As part of my JRuby on Rails presentation at RailsConf, I'll be demonstrating the new Depot application from Agile Web Development with Rails 2nd Ed. The entire app seems to work very well under JRuby, and I only had to make one additional manual change in the database because JRuby doesn't yet work well with edge rails (on which the book's examples are currently based). It's quick and responsive, and will only improve as we continue on.

Also keep in mind that the DDL issue only limits the JDBC adapter's usefulness for migrations or schema-manipulation purposes. Without DDL generation, it will still work with many, many databases without major modifications, since JDBC really shines here. Hopefully a future version of JDBC will provide DDL metadata or tools for manipulating database schemas. Until then, we'll continue to work with the Rails folks to find a good solution for DDL under the ActiveRecord-JDBC adapter.

Saturday, September 02, 2006

From Eclipse to NetBeans: Part 3

I got a lot of good tips from NetBeans developers and users about how to resolve some of the issues I ran into. A number of them, as I mostly expected, were related to my running a beta that's still under development. Others are resolved via modules and add-ins (that in many cases should perhaps be included as standard). And still other cases are resolved or scheduled to be resolved in NetBeans 6. So to be fair, I decided to continue my NetBeans adventure by diving to the bleeding edge of NetBeans: building directly from source and running JDK 1.6 Beta 2.

I won't go into the details, but getting NetBeans to build was an extremely simple matter (thanks to Tor Norbye from Sun). Set CVSROOT, checkout -P standard, cd nbbuild, ant. It's really that simple. I did need to up the maximum memory needed for ant, but that was a minor issue. After the build, I found "ant tryme" that starts up NetBeans, and I was off and running.

This article will be a short wrap-up of issues from Part 1, revisited based on tips, tricks, and NetBeans 6 current and planned features. Hopefully it will demonstrate to potential switchers that NetBeans has really turned a corner. I'll revisit Part 2 in the next article.

I used to be among the NetBeans detractors...and for good reason; NetBeans had a rocky start. But I'm rapidly growing fond of it, especially using NetBeans 6.

Salvation

I'll take the items from Part 1 point-by-point. There's some useful links inline as well, so feel free to skim this list for issues of particular interest to you.

  1. Antialiasing - RESOLVED! When running under JDK 1.6, all text elements are immediately antialiased according to the host platform's settings. No additional configuration changes are needed.
  2. SVN by default - RESOLVED, I think. My basic pull of NetBeans 6 from CVS included SVN support immediately. I believe it's intended to be in the full release by default as well.
  3. Workspaces - OPEN. My main use for workspaces is to keep different sets of projects in different places, and to a lesser extent to have different configurations for those sets. No obvious support for this in NetBeans 6 yet.
  4. Separate repository view - OPEN. Eclipse's repository view is a godsend when you're hunting around for projects, tags, and branches, or if you want to do any remote repository management. I still miss it, and there's no out-of-the-box support in NB 6 for a repository view.
  5. Standard SVN layout support - OPEN. I would like NetBeans to understand what "trunk", "tags", and "branches" dirs in SVN are used for.
  6. Delete project not deleting files - OPEN. I tried to delete a working copy locally and the files remained on disk.
  7. Wizarditis - OPEN. The best example of this is perhaps the SCM wizard, where at least seven clicks are required for me to check out my JRuby branch. If I had a repository view, it might take three or four.
  8. Show non-project files in project view - OPEN, but not a big deal. I've gotten accustomed to just using the Files view when I need access to non-Java source. I still think it's necessary to show other files in the project view, but it hasn't gotten in my way as much as I thought it might.
  9. Settings dialog search - OPEN, but improving. I remember once being told that if people need to use a site map or search for your site, you're doing something wrong. NetBeans should actually be applauded for presenting common settings in a novice dialog and a full complement of expert settings a button-press away. In NB6, they appear to be moving some of the important advanced settings to the main dialog as well. It's a balancing act, but I think a lot of people will appreciate the easy dialog.
  10. Browser selection - Doubly RESOLVED. With JDK 1.6, NB6 uses your platform's browser by default, and the setting has been moved to the basic settings dialog.
  11. NetBeans is a goofy name - UNRESOLVABLE. There's too much branding and history behind the NetBeans name to change it, or so I'm told. Oh well, at least it's not limiting in any way, and it does have a nice mouthfeel to it unlike "Visual Studio 2005".
  12. Eclipse keybindings - OPEN, but workable. The default Eclipse keybindings are missing some important ones, but you can go map them yourself easily enough. Unfortunately there's no equivalent to Ctrl-Shift-R, which is like a "super open" for any file in the workspace. I also haven't found an outline view shortcut like Ctrl-O, which hurts a bit.
  13. Sorted members view - OPEN. However I can deal with the default sorting for now.
  14. Show packages as a hierarchy - OPEN, but I've been using the Files view almost exclusively which already uses a hierarchy.
  15. Anti-aliased UI - RESOLVED! Under JDK 1.6, UI elements are also antialiased! It looks great!
  16. Collapsing comments - RESOLVED, but one bug. It turns out that only the large license block at the top of our JRuby source files refuses to collapse. Everything else, including JavaDocs and multi-line comments, collapses ok. Probably a bug in how NB determines what comments to collapse.
  17. Improved coloration - RESOLVED SOON. Better coloration and other editor improvements are planned for NB6.
  18. Memory usage - OPEN, but improved. NetBeans 6 is a little better, but still typically takes over 200MB and sometimes over 300MB of memory. Eclipse usually stays under 200MB for me. However I don't have any modules disabled, and NB6 comes with UI design, Java EE, DB support, XML support, Web design support and a ton of other stuff out-of-the-box. That balances things out a lot.
  19. FIXME support - RESOLVED via external module. The NetBeans Tasklist looks quite a bit more sophisticated than Eclipse's support.
  20. Clear search results - OPEN, but workable. Search for nothing and the results clear. However I conversed with Roman Strobl, NetBeans Evangelist, and he agreed that was a little cumbersome.
  21. Right-click editor menu with SCM operations - RESOLVED. You can't get those options right-clicking in the editor, but you can right-click the editor tab for the same effect. Hooray!
  22. Odd behavior of SVN menus in file view - RESOLVED. This and several other SVN issues I ran into appear to have been fixed in recent 5.5 and 6.0 development builds. Subversion support seems to be tighter in NB6, or so it seems.
  23. Slow start-up - OPEN, but fading fast. It's not a large perceptible difference between Eclipse and NetBeans now, and NetBeans is loading a lot more stuff. It's very nearly RESOLVED.
Hopefully it's apparent that NetBeans is arriving fast. If I were to make predictions, I'd say that NetBeans 5.5 will be a really powerful and useful release, especially considering suport for Java SE 5 and Java EE 5 out-of-the-box. I believe the bugs I've encountered will be wrapped up, and 5.5 will be a compelling alternative to "Eclipse-plus-ten-thousand-plugins", which functionality it easily matches.

I would also predict that NB6 may finally be the big release that surpasses Eclipse for day-one usability and functionality. There's just so much packed into the base product, I don't think Eclipse itself is even a fair comparison. WSAD may be the only real competitor at that point, and I'd prefer not to run that monster (and I also prefer not to use WebSphere.)

One area I think NetBeans needs to improve is in making development releases easily available. I have to dig down through multiple pages, dropdowns and license-acceptance forms to get at the 5.5 and 6.0 dev releases, which have so far been very stable and very nice. To save some time, here's a link to the NetBeans Download form. "Daily" builds are obvious enough, but I believe "Q-Build" builds are probably "QA" builds, perhaps equivalent to Eclipse's "integration builds" or "milestones". Q-Builds might be a good place to get started for you Pro users out there.

Thursday, August 31, 2006

Performance: Block Variables Breakdown

In response to my previous blog, Chris Nokleberg noted that if we're using String#equals a lot, interning will have an additional benefit...namely because String#equals short-circuits if both String objects are ==. I had forgotten about that benefit, so I thought I'd poke around for places it might have an effect.

In digging a little, I was reminded that DynamicVariableSet, which holds block-local variables, does a linear search for retrievals and mutations. Compare that to method-local variables in Scope, for which all clients must pass an index to get or set a value. I'm not sure if there's a reason why DynVars must be retrieved by name and Scope vars can be directly indexed...it's probably historical from the C code or a limitation of the current parser. In any case, a linear search could theoretically represent a performance issue accessing or modifying block-local variables. So I thought I'd run some numbers to see how frequently we have to search past the 0 value in the DynVarSet. Here's the breakdown while gem installing rake:

Count of block var retrieves from indicies 0 through 6:
516436
226049
42687
1170
656
122
1

So a total of 787121 block variable lookups, with percentages below:

index 0: 65.6%
index 1: 28.7%
index 2: 5.4%
...with the remainder filling out the last 0.3% of accesses

What can we learn from this? Well DynVarSet currently allocates initial space for up to 8 variables, based on someone's long-past examination of code that showed a maximum of 6 was a good estimate. The numbers above show that, for RubyGems + RDoc at least, a maximum of 3 would cover 99.7% of all cases without requiring expansion of the array, and that with a subsequent expansion to 6 slots we would cover all but 0.0000127% of cases. So using 6 as a maximum and always allocating 8 slots is perhaps a bit generous. More profiling on more code is warranted here, but it might be safe to drop the initial size to 3 and leave in the doubling when expanding.

It also shows us that we pay the cost of two String#equals calls for 28.7% of lookups, and pay for three in 5.4% of lookups, with higher counts statistically insignificant. So although it might seem like we're unlikely to suffer much of a performance hit because most block var lookups are at index 0, our cost to lookup or modify block variables is doubled in over a quarter of cases and tripled in a twentieth of cases. If we normalize all lookups to the same cost (X * 99.7 versus X * 139.2), that translates to a 28% performance boost for block variable lookup cost. Note that I'm not measuring block variable modifications here either, which would conceivably see a similar boost.

And of course what it doesn't show (but which we know to be true) is that if we were able to eliminate both the linear search and the call to String#equals, we'd save a very large percentage of block var lookup time, since we'd reduce it to a simple array indexing. I think it's worth exploring how we could do that--especially since we already do it for Scope in all the same places.

Isn't optimizing legacy code fun?

Performance: Inlining Strings

A while ago, we decided to inline all appropriate symbolic strings as they entered the AST. This appeared to help performance a measurable amount, presumably for two reasons:

  1. The AST would take up less space in the long term
  2. Since Strings cache their hashcodes, having each identical string in the AST be the same object would reduce the number of hash calculations.
And the numbers seem to bear it out. Here's a local rake install:

Without interning AST strings:
real 1m19.894s
user 1m18.649s
sys 0m0.920s

With interning AST strings:
real 1m15.021s
user 1m13.785s
sys 0m0.948s

So it's very measurable...in this case 4-5 seconds out of 80 seconds, or about a 6% gain with interning.

However this week I realized the fallacy of the second point above. In order to intern each incoming string, Java must hash them. This causes all strings entering the AST to be hashed once anyway in order to get the interned version. In fact, it could reduce performance, since we're now forced to hash strings we might never encounter during execution.

I can't confirm that this is 100% true, but it's a reasonable theory. String.intern() is native code, but logic dictates that the fastest way to intern strings would be to use an internal hash/symbol table. So I proceeded this evening to try removing interning to see how it affected performance. I hoped to get a small gain during execution due to a large gain during parsing. The numbers above show that I lose a measurable amount overall by interning. However, I do see substantial parse performance gains:

With interning AST strings (Time.now - t method of measuring 100 parses):
11.101

Without interning AST strings:
9.404

About 1.7 seconds out of 11, or a whopping 15% gain in parse speed without interning. AARGH.

At this point I'm leaning toward removing interning and swallowing the 6% performance hit temporarily until we can figure out where it's coming from. Logically, interning everything should only add overhead, or so my brain tells me. Where's the flaw in my logic?

My London Schedule

So here's the times and places. I want to get together JRubyists to just chat a bit at some point, and it seems like Thursday or Friday would work best. The only concrete suggestion so far is the Fitzroy Tavern on the 15th, around 6:30PM-7:00PM (thanks Damian). This works for me, and it's after the conference. Here's a goofy Google Map to Fitzroy from the conference center.

I'm also planning to attend the "Pizza on Rails" event on the 13th, so folks can find me there.

I'll keep this entry updated as things come in, so it can be used for reference.

13 September, 6:00AM: Arrival in London (Heathrow)

Other than getting checked into the hotel, I have that whole day free. I don't plan to cram for my presentation or anything, since it's not until Friday (and I don't really work that way). To avoid the lag I'll probably sleep as much as I can on the plane. Getting out and about once I get there ought to get the circadians whipped into shape.

13 September, 6:00PM: Pizza on Rails

Pizza on Rails is around 6PM, with pizza at 7PM.

14 September, 9:00AM: RailsConf Day One

The "Welcome" is at 9, and it goes straight through until 8:30PM with a lunch break from 12:30PM to 2:00PM and a dinner break from 5:50PM to 7:30PM. I'll probably try to grab meals with folks from the conf.

15 September, 9:30AM: RailsConf Day Two

Lunch break is the same as Day One, and the conf is scheduled to go through until 6PM, with "Closing Remarks" coming after that. Probably be out by 6:30, and the Fitzroy is pretty close. Maybe someone not going to the conf can get there early to scope it out.

15 September, 3:00PM: JRuby on Rails

I'm in the last set of speakers, before the final plenary session with James Duncan Davidson and Dave Thomas. I'm up against cleaning up rails, adding unicode to rails, and project management for rails. I wish I could attend the unicode session, but I'll try to grab Dominic offline.

15 September, 6:30PM: JRuby Meetup

So far I think we'll just be at Fitzroy Tavern, as mentioned at the top of this post. All are welcome...I don't fly out until 1:25PM the next day, so I can stick around for a while.

16 September 10:00AM: Departure

Given the recent TERROR scare, I'm going to be extra careful and head to the airport nice and early. I'm not particularly worried about TERROR, but I am over-cautious about giving security enough time to scour my person for soda pop and lip balm.

Thus ends my first trip to London. It's too bad it will be so short, but I have business to attend to stateside immediately after the conference. Hopefully I'll stop back in when I'm in the EU for JavaPolis.

I hope to see plenty of JRubyists in London!

Wednesday, August 30, 2006

IronPython Demo for John Udell

Tim Bray tossed me a link to an IronPython screencast given by Jim Hugunin for Jon Udell.

On the surface, it does look fairly impressive. However I'm not impressed for the reasons some folks might be. So here's the notes I took while watching this demonstration...take them for what they're worth.

IronPython with Avalon demo

Here Jim demonstrates instantiating and manipulating a small Avalon UI in an interactive python session. This is essentially the same as the demonstration I gave at JavaOne using IRB to script Swing components (and no, I'm not claiming to be the first to do such a demo). It shows that Avalon produces very impressive and beautiful UIs, and the XAML under the covers is pretty big and ugly. It also shows that IronPython has some nice integrations with .NET code. Beyond that, I wasn't any more impressed than I was when I got the IRB stuff working. It's cool, to be sure, but it's not new.

Notes:

  • Tab completion is nice, but in an interactive shell it isn't very exciting. IRB already does this in Ruby (not in JRuby unless you have a ReadLine library wired in), and completion against running code is easy.
  • Importing a whole namespace from .NET is really, really nice. We would love to be able to efficiently support the same, but there's currently no capability in Java to get all classes or subpackages in a package. That's the reason why you have to include each class you want. You can include a whole package with JRuby, but for each package you include we have to brute-force search them for all Java classes from then on. O(n) to locate a class, where n = number of packages imported. It sucks. Including the classes directly has no unreasonable overhead, though.
  • It looks like IronPython has a few nice wrappers around the delegate-based events in .NET. That's the b.Click += some_handler...some_handler is python code that becomes a delegate instance; the += adds it to the Click event. Nice and simple. Everyone feels differently about events+delegates versus listener interfaces, however, and in Java we've got the latter. We'll need a different way to make things nice and simple.
  • Most of the UI interaction stuff we can already do with JRuby, though it's not wrappered quite as much; you're basically just calling Swing methods directly. We could add a lot here by making something smart that handles common UI use cases for you. This demo somewhat reminds me of the Groovy demo at JavaOne 2006, where the presenter used OLE automation to work with an Excel document. It was a great OLE demo. It was a pretty good Excel automation demo. However it was only a mildly entertaining Groovy demo because it just called OLE methods like any other language could. The Avalon stuff in this demo is similar.
  • Almost all the functionality shown, including XAML manipulation, etc, is .NET code, not IronPython code. Ignore anything about XAML and Avalon to see what's really interesting...the various little ways IronPython makes .NET components available to python. Again, an impressive Avalon or XAML or .NET demo...but only a pretty nice IronPython demo. But pretty nice is pretty good. IronPython looks pretty nice so far.
Visual Studio demo

VS 2005+ is very nice, but I think most folks already knew that. However the python support looks much better than I expected, on par with what RDT has built for Ruby in Eclipse, though maybe a bit more polished.

Notes:
  • It was a bit of a dodge that he didn't admit how Jython compares performance-wise to IronPython. Of course, Jython has been around longer, and I'd wager that it's faster. I've made it perfectly clear that Ruby is still faster than JRuby, because I don't think distracting folks from JRuby's performance issues will make them any less of a concern. It's too slow. We'll fix it.
  • I've given a lot of thought to where we'd need to hook into JRuby to be able to online debug code, and it won't be terribly difficult to do. We also might be able to simply get Ruby's normal debugging hooks working with a little effort, and just use those remotely. Either way integration into the IDE is just icing on the cake.
  • I completely disagree with the long-standing idea that programs should be implemented in Python or Ruby (or some other dynlang) and then migrated toward C# or Java (or some other static lang). I application code should *stay* Python or Ruby, because much of the value of those languages is in the long-term maintenance of the code you write. The minute you port that code to C# or Java (or C) you've lost that benefit. You've set it in stone, as far as I'm concerned. Is any application code ever to a point where you want to set it in stone? Wouldn't we rather just code in dynlang all the time?
  • I didn't see any code completion or refactoring of python in Visual Studio, unfortunately. There was a little C# completion only, which is well-known and deserving of praise. That's a big area Ruby IDEs could jump ahead. The editing capabilities for python are also only touched on briefly, since he presents a pre-written python script and then writes and calls some C# code.
  • The online debugging in Visual Studio looks really nice...I want that for Ruby. The JRuby compiler I've been working on will include .rb filenames and line numbers in the eventual stack trace from the compiled code, so eventually you'll be able to step through Ruby code using my compiler...even after it's compiled to Java class files:
    at MyCompiledScript.fib_java (samples/test_fib_compiler.rb:2)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

PowerShell

I read a bit about the PowerShell stuff the other day and I don't really have much to say here. It's basically a set of .NET objects that are interactively available to dynamic .NET languages for interacting with the system...a nice set of OO components to provide what UNIX command-line utilities do on UNIX, in a sense. It's neat and all, but it's not relevant to IronPython except that you can script those components in python.

Other notes

Using import clr in IronPython is a clever way to add in .NET decoration of python types; we could probably add that, so that Ruby strings automatically have Java String methods.

Conclusion

My opinions are sour grapes, perhaps...but I could do almost all of the non-IDE stuff in a screencast of my own. The IDE stuff will come soon. It's still a very nice demo, and kudos to Jim for what IronPython has become. I'm impressed.

I think it's safe to say that we're behind IronPython on having a fast, well-integrated implementation (a detriment of the legacy code from the original port) but way ahead on completeness and compatibility with C Ruby (a benefit of the legacy code from the original port). The IDE stuff is not yet as nice for us, even counting the Eclipse-based RDT. NetBeans and Eclipse are in many ways not as nice as Visual Studio, so there's some additional catchup to do there.

I'd like to know how folks out there feel about our approach to JRuby, working to make it a drop-in replacement for C Ruby so it can take advantage of all the libraries and applications out there. As far as I know, neither Jython nor IronPython can actually run most of the major Python applications, and certainly nothing as complicated as Rails. Our choice has made some things harder, but I think the value of making Ruby work on the JVM would be greatly diluted if you couldn't run real Ruby apps.

FWIW, I've had a long-standing task to do a nice screencast like this for JRuby using Swing and other libraries, and I dir a very similar UI demo for JavaOne. Hopefully soon I'll have time to do a longer, fancier one.

Tuesday, August 29, 2006

From Eclipse to NetBeans: Part 2

I had planned to post a "Part 1.5" that summarized all the emailed and commented help I got for my first post, but I've been too busy working on JRuby on Rails to try most of those suggestions out. Several folks offered a whole bundle of useful tips that will address many of the "bad" points in Part 1. I will revisit those as I have time, and hopefully use them to compile a "NetBeans for Eclipse Users Walkthrough. For now, however, I continue to muddle through with NetBeans as-is.

NetBeans continues to surprise me in both good and bad ways. Some features seem to be very nice and very well thought out, while others...well I wonder if anyone's actually using them, because they're very cumbersome. Most of the UI seems to be solid and clean under Java 6, but there are some occasional jarring glitches and (in my opinion) poorly-designed interfaces. Sometimes NetBeans seems to know exactly what I want to do...sometimes it seems to make what I want to do as hard as possible. It's still been worlds better than earlier versions, but I'd have expected a level of polish I'm just not seeing yet. Is it because I'm running a beta IDE on a beta JVM? Perhaps. Perhaps not.

However I'm going to be a trooper about this and do what I can to fight through issues. I think NetBeans really has a lot of promise if these things can be ironed out, and truth be told, most stuff works fine. However the stuff that doesn't work...REALLY doesn't work.

And again, please don't consider this an attack on the NetBeans product or team. NetBeans is very impressive...but there's room for a lot of good improvement. I hope this hard look at NetBeans vs Eclipse will help make progress to that end.

The Bad:

  1. "Extract Method" should have an option to replace all instances of identical code with calls to the new method. I use that feature in Eclipse *very* frequently.
  2. No "Inline Method" refactoring? I really need that one. Here's a typical use case for me:
    • N methods all have the same code, for whatever reason..perhaps I've refactored and simplified them each down to the same chunk of code.
    • Extract Method to create a new method that does that duplicate block, and replace all instances of duplicate code so all the old methods call the new one.
    • Inline all the old methods so all callers now call the single new method. The old methods are eliminated.
    In this way, I manage to make all callers calling duplicative methods call a single new method without ever manually modifying a single line of code. I have many such refactoring tricks I have learned over the years, many of which depend on being able to inline methods and extract methods globally. JRuby would not be where it is today without those refactorings.
  3. The "Find Usages" dialog has a grand total of two or three checkboxes (depending on visibility), one of which I will probably rarely use (find in comments) and the other which should probably just be on by default (find overrides). I would much prefer to just go straight to the search results, rather than always have to hit "Next" on this dialog.
  4. There's no way to look at the project view and know whether I have errors in my project or not, even after running a build. In Eclipse, if I save a class with errors, the entire project and all directories leading to that class get marked with a big red X. In NetBeans I can see if the current file has errors, which is good...but being able to see errors anywhere in the project is a must when I'm making refactoring changes that can affect more than one file. I need to know at a glance if I've broken something else. For larger projects, re-running the build can be prohibitively slow.
  5. My Projects and Files views only show the little "versioning cylinder" icon next to SOME of the items in my project. Even more confounding, in the Projects view, only SOME packages show up as versioned. I haven't figured out a pattern to it.
  6. I should be able to change the delay between typing code and having NetBeans re-parse it and display error squiggles. By my estimate, it takes about three seconds for it to realize I've typed bad code, by which time I've almost certainly moved on to the next line or a different file completely. Yes, it checks when I save, but checking as I type *very slowly* is not really useful. EDIT: I did find this setting...it's at 2000ms by default. I've set it to 1000ms, so we'll see if it's disruptive. Is it set so long because it causes a lot of overhead?
  7. There are surprisingly few "non-advanced" settings and a baffling array of "advanced" settings. Almost everything I need to do is in the "advanced" section. Perhaps I could just turn on an "always advanced" view and save myself that button-press?
  8. Why can I right-click items in the Advanced Settings tree, to bring up the exact same properties listing I see on the right-hand pane? Prefer one way to do things...the right-click properties dialog should go.
  9. I can't find how to change the default L&F. Maybe it's in the Advanced Settings somewhere, but I couldn't locate it. Metal is an OK L&F, but it's jarring when the rest of my system looks completely different. It also seems too "bright" to me, for some reason...I prefer softer earth tones.
  10. Code completion brings up two popups: one for the list of methods, and one for documentation on the selected method. One displays itself above the line I'm typing and one displays below the line. This effectively hides all contextual code around the line I'm typing, which is frustrating. The documentation window is also enormous, and usually mostly empty.
  11. There doesn't appear to be a way to revert changes when the changes are new files. Modified files get reverted, but not files or directories that are new. Oddly enough, they DO show up as changes when choosing "Show Changes".
  12. I selected all new items in the "Show Changes" pane and hit the delete key...BEEP, nothing happens. I right clicked and selected Delete...and it appeared to proceed with the delete operation. The Delete key should map to a logical Delete operation whenever possible.
  13. After deleting, the view continued to show new files that were no longer visible in the Files view, and refreshing did not help.
  14. After manually cleaning out the new files, my NetBeans project appeared to be totally hosed, returning a goofy error about a parameter field not being normalized (filed as bug 83665). I had to completely wipe out my working copy and re-get it...
  15. ...only to find that once I had deleted my project, NetBeans totally forgot my SVN URL and I had to retype it. Thankfully it remembered my credentials, but why didn't my old URL show up in the list of possible URLs anymore?
  16. Then it again asked me where I wanted to check things out, defaulting to my home dir. Can't I just set a single work location and be done with it?
At this point I figured I should call it a night.

The Good:
  1. NetBeans shuts down WAY faster than Eclipse. That's a huge benefit. I don't know what the hell Eclipse is doing that takes as much as 15 seconds to shut down, even if it was sitting idle.
  2. NetBeans ships with way more capabilities than stock Eclipse. I found the Module Manager today to turn some stuff off and was absolutely stunned to see how much stuff comes in the base install. However there's a bad side to this too: NetBeans could be perceived as having a slower startup time because of all these modules, even though most folks will never use most of them. Maybe have a few coarse-grained use cases people can choose to enable AFTER installing and starting up the first time. At any rate, I'm impressed with what ships out-of-the-box.
  3. I can confirm that antialiasing appears to work for the whole IDE under Java 6, as reported by one commenter. Very nice!
  4. I like being able to turn on line numbers for all editors in one place. However, others may want to be more picky.
  5. NetBeans seems to be much more deterministic than Eclipse. For example, when Eclipse is under heavy load, occasionally mouse clicks and keypresses will disappear into the ether. When Eclipse gets laggy I frequently have to double-check that the code or shortcut I just typed was actually received. This sometimes leads to me typing only half of a line of text or typing a search query into my editor. NetBeans so far does not seem to "lose" UI events like Eclipse does.
  6. I see that right-clicking editor tabs DOES allow me access to Subversion. I just don't have it in the main pane's context menu. That's totally acceptable, so mark another item off the bad list from Part 1.
Subversion...Wherefore Art Thou

The subversion issues have been severe enough I figured I should rant a bit before closing this article out. As far as I can tell, SVN support is simply broken in 5.5b2, to the point that I'm now afraid to perform many operations out of fear that they'll nuke my working copy in some heinous way. In this case, I had no local changes to lose (or to struggle to save), but I could picture some painful corruption like the "parameter field" error coming right in the middle of some multi-file refactoring. I pray that doesn't happen.

Painful to live in fear, isn't it?

Jack-of-all-Trades...but...

NetBeans seems to have a vast range of capabilities, rivaling multiple major Eclipse-related projects all rolled into one. However there's a lot to be said for polishing the core pieces to death before launching into a new set of features. Subversion should just work. The UI should just work, without glitches. Professional-grade refactorings should work like you expect them to (and Eclipse's complement of refactorings is actually overshadowed by some other IDEs, so NB is well behind the curve here). Under no circumstances should a working copy be so badly damaged by an operation that it must be flushed out and re-gotten. And so on...

These key features need to work perfectly, all the time, before anyone will consider launching into more advanced features like Java EE support or Database Browsing. If I can't even do basic SCM operations on my project, why would I ever invest time in anything more than simple Java code editing?

That said, I think NetBeans could really shine like a star with some polishing...polishing that may be coming in NB6, I really don't know. Most of these issues are obvious or minor, and many of them are in newer features that have perhaps not been tested as well as one would like. Hopefully the excellent improvements in NetBeans over the past year will draw more users...and more testers...to the project.

Monday, August 28, 2006

RailConf Europe 2006 - I Will Be There!

It's official! Travel arrangements are currently being made for me to attend and present at RailsConf Europe 2006 in London!

I had not expected to make it, so this comes as a bit of a surprise. I guess I need to put together some sort of presentation now, don't I? Oh, and make sure I'm happy enough with JRuby's Rails support to be comfortable...

I'll take comments on this off-the-top-of-my-head agenda:

  • Who Am I
  • What is JRuby (dime tour, nothing too deep)
  • Why Rails on JRuby (probably a few slides on JDBC, alt persistence layers, EJB integration, legacy code integration, why JRuby is better in some ways than Ruby)
  • Why not Java-based web framework X
  • Demos
  • What doesn't work
  • What's next, future plans, how can you help
  • Q/A
I'm also hoping the JRubyist Mongrelites are able to get things working before then. I'll probably try to help them, wrap up enough bugs so that most walkthroughs in AWDwR work nicely, and create the presentation over the next two weeks.

I hope to see you in London!

P.S. If anyone wants to give me any pointers on travel from the US to the UK, please do. I'll be travelling alone and I've never been across the pond. Thankfully, I already have my passport, but other than that I'll be flying blind. If any Brits feel like taking me under their wing once I arrive (or just grabbing a pint or two), that would also be much appreciated. I plan to arrive during the evening of the 13th, flying back the morning of the 16th.