Tuesday, November 11, 2008

Rails "Plugin not found" error may be a red herring.

I've been writing a number of plugins lately, and I kept getting this error when I would install it from RubyForge:

Plugin not found: ["http://blah.rubyforge.org/svn/trunk/vendor/plugins/blah"]

I knew the plugin was there, and in fact I could see that the plugin files were being placed in the vendor/plugins directory. So why was this message showing up?

After a number of hours (yes, hours, it's depressing) it turned out that I had an error in my plugin's install.rb file. Apparently any exception raised in a plugin's install.rb file gets caught and the erroneous "Plugin not found:" message is shown.

So, if you see this error and are confused, start adding traces to your install.rb file and you are likely to find something is broken.

Wednesday, November 05, 2008

Thwarted by ActionController::MethodNotAllowed

Are you running a rails app locally seeing this:



ActionController::MethodNotAllowed
Only get and post requests are allowed.
RAILS_ROOT: /Users/me/my_rails_project
ActionController::MethodNotAllowed (Only get and post requests are allowed.)



There are of course actual valid reasons this might be happening to you if you're doing something tricky, but if all you're trying to do is browse to a page (which is get request) and it's blowing up with this there may be a simple fix.

Stop script/server and start it again. Then refresh the page.

I've found that sometimes when I edit routes.rb and add a route, particularly if it's a resource, thinks get wonky and I get this error. Restarting script/server ended up fixing my problem when google yielded nothing for me.

This blog is now called "Ryan Owens is a Nerd (roian)"!

Greetings! It's been a while. I'm going to change things up a bit here. The original format of this blog was more of a personal journal, but it seems more useful (and easier) to just post tidbits as I am inspired to do so. So I'm going to do that now. And I'm renaming it since I couldn't get the associated url on blogger/blogspot.

So my advice is, even if you're hosting externally, go ahead and get the blogger url for your blog when you start up a new one.

Thursday, April 20, 2006

Welcome to Words 4 Nerds!

Greetings! My intent with this blog is to chronicle my views (and how they have changed/are changing) of Java, Ruby, Actionscript, Hibernate, Tapestry, Ruby on Rails and whatever else I know a little bit about.

Just to confuse everyone, this blog will start about 18 months ago when I went to the 2004 Ruby Conference. Before, during and for a week or two after the conference I wrote some notes to myself about what I thought about Java versus Ruby. I wasn't blogging then, which seems like a shame now, but it's never too late to start, right?

My intent is to post my those entries one by one, with their original (past) dates, moving on to fill in a few blanks over the past 18 month and finally begin creating some new posts along the same lines. Hopefuly when it's all done I'll have a site that shows my frame of mind as a 100% Java guy then, to a 100% Ruby guy (in the future).

Should be interesting, for me if nothing else.

Thursday, October 07, 2004

Java 2 Ruby: The Prequel

Today I decided to chronicle my switch to Ruby and attempt document any revelations along the way. Hopefully this can be helpful in the future to others who would like to switch. First I will summarize all my thoughts leading to this point as I can recall them.

Background:

  • I have been coding in Java since 1996 when there was only 1 Java book available.

  • I consider myself a user interface designer/programmer.

  • I have done a lot of webapp work over the past 5 years: JSP/Struts etc.

  • I found long ago that designing a good UI was hard, but implementing it was much harder.



Personal Goals:

  • Make great User Interfaces.

  • Empower Domain Experts (who are not programmers).

  • Side Quest: I'd love to be able to build a note taking app for myself in 5 minutes. I think it's possible.



Requirement MetaData


Early on I found that the kind of information I wanted to use in my interfaces was not typically available in the backend others were developing. The short example is TextFields. I would usually have a method "String getName()" that I needed to create a UI for, so I knew I needed a textfield. I could assume that the label on the screen would say 'Name'. However I did not know, nor could I assume, the max/min length of the text field since that was dictated by the database. There may also be some EJB or other code somewhere else that limits the size further, especially if there was a requirements change at some point. Continue this to things like 'first name', 'last name', 'middle initial' and so forth, and you have a lot of guesswork about info that is usually only in some Word requirements doc somewhere, or more likely spread over 2 years worth of emails and meeting minutes. Of course there should be an up to date requirements doc, but this was quite often not the case. So I eventually became a 'backend programmer' in order to give my UI the information it needed to be better.

Summary: I need more "MetaData" than most backend programmers are used to giving me, and I don't want to spend all my time hunting down these requirements since the backend folks have already done this work once.

Domain Experts and the "MetaDatabase"


As a UI guy I generally deal with Domain experts. People who really know their data, but don't know about Databases and certainly not code (Java or otherwise). All of my data comes from these Domain Experts: the domain model, the UI 'screens', the validation logic. Everything. Same as a requirements doc.

My solution to this over the years was to create a "MetaDatabase" which contained all of this domain data. This is a central location where I store all the data I have about the system I'm building: Objects, attributes, associations, sql types, java types, field lengths, etc. The idea is to put everything the Domain Expert tells me into this Meta database, and generate as much code as possible (preferably all) it. At the very least all of my requirements data is in one place. The idea is not new. It is practically stolen from the Pragmatic Programmers book (see footnote). You could also think of this as a requirements machine. To that end I did a lot of work with various persistence layers, some homegrown, and finally landed on Hibernate. More on that later.

Summary: I created a Meta database full of requirements data with the goal of generating all of my backend code and supplying my UI with the data it needed to be better.


Model Driven Design


I find Model Driven Design quite interesting. The golden idea being that businesses could have define all business objects, rules, user interfaces, etc for an entire system in a language neutral formal (UML). Then vendors would build MDD Servers or somesuch that would run these applications. Freeing businesses from technology lock-in. In say 5 years when your server is yesterdays news, you just take your business app data and drop it into the newest leading edge MDD server and your app works. This MDD server could be written in anything, so whether it's Java, Ruby, ADA, Fortran, no one cares. I think this is interesting, and it coincides with the meta database idea. It's pretty much the same idea.

What the MDD guys offer is UML. Using Poseidon for UML I have been able to train domain experts to "model" their own systems using UML Class Diagrams. This works on a number of levels:

  • It relieves me from the requirements gathering duties to a large extent.

  • the domain experts learn a (relatively) simple tool and in the process learn a few basic coding ideas (like structure).

  • they can see their system and play with it immediately.


From these UML diagrams I can generate their Persistence layer. That's a lot of work I don't have to do once the generation tools are written.

Summary: I can train domain experts to use UML to design their system, and effectively build their own persistence layer.

Technologies


I currently use Hibernate and Struts for my webapps, and Maven (based on ANT) as my build system.

Hibernate


I love Hibernate. Before Hibernate I used Torque, which is similar but not as configurable. Hibernate (as many rubyists have pointed out) can be extremely complex to configure, but I have a giant book "Hibernate in Action" to help me out. The general belief is that its complexity is "necessary" given the complexity of the problem. With Hibernate I can create a set of configuration files (XML), and from that generate my entire persistence layer.

Hibernate XML → generates → Java classes, Sql Scripts.

The trick is this: Since all of my domain objects are defined in UML (XMI) I can also generate my Hibernate XML files. So...

Domain Expert → Visual UML Tool → XMI → Meta Database → Hibernate XML → Java Classes and Sql Scripts.

I now have my entire persistence layer generated from the Domain Expert's Visual tool. SO, Hibernate's complexity is largely irrelevant if I use code generation.
The only thing that actually deals with Hibernate are tools I wrote once.

Hand coding:
I still have to hand code specialized queries, computed fields on Domain Objects, and other things like that.
This seems like a necessary step now, since that logic has to be written anyway.


Struts:


Practically everyone I talk to now hates Struts. Too many config files, Form classes etc. Lots of duplication. I understand where you're coming from on this, however code generation solves a lot of my duplication woes so it doesn't bother me currently. I happen to like having a config file that lets me wire my web actions to various web classes. Granted, I do have a set of Struts utilities that I've developed over the last 3 years or so so perhaps I've masked the problems. Again, the point is that I can generate practically everything I need from my meta database so the complexity is handled for me.

Hand coding:
I still have to hand code the business logic that the Struts actions perform.

Not Implemented Yet:
I actually am not currently generating the Struts code either. It's a TODO item now.

Maven:


I freaking love Maven. Ant is cool, but Maven is freaking sweet. In maven I define all my project info in a config file. My project name, cvs repo, dependencies and all that are in the config. This plays nicely into my central meta database idea. Maven also manages a central repository of versioned jars for you, which is a huge win since jar version management is a royal pain. More importantly, Maven generates tons of incredibly useful documentation for you for free. I'll enumerate the stuff later, but the 'project comprehension tool' aspect of Maven is where it's at.

Also, maven plugins allow me to build very flexible reusable tools for my projects. If I have an XML file from Poseidon in my project (and a few config properties) I can generate my persistence layer with one command: maven metadb:i.
That command generates my Java model classes, creates a Cloudscape database and configures hibernate for me, all in 1 step. Very sweet.

So Maven is really the glue for all of my various tools. More than that, it is what I use to massage any differences in the tools I use. The plugins I write define how tools fit into my overall architecture. From that perspective, I use Maven to build tool adapters for my framework. When I create a new project, I don't use Hibernate directly, I use maven plugins.

*So my development is in terms of my framework's plugins, not the tools I use.

Hand coding:
I still have to hand code any specific build tasks that don't exist as plugins. I also have to occasionally duplicate tool settings when different tools need similar settings. (properties)

Caveat:
Maven itself does have a reasonably steep learning curve. I think it is mostly because it assumes a certain project structure and each of the many plugins have their own goals and properties. Writing plugins is a tad ridiculous. You really have to know what's going on and it's no trivial task. Integrating Cloudscape and Hibernate as a Maven plugin to work on any arbitrary project with sufficient customizability was a royal pain. Debugging plugins sucks because they have to be built and deployed, no quick debugging. It takes a while.

Standing on the shoulders...


One big plus of all of this is that other people wrote the tools. The configuration files are very rich. Some say that's too complex, but I was able to learn a ton from the hibernate, struts and maven configs. These configs showed me all the meta data that these kinds of tools needed to operate, much like any API would. My task was simplified because I could look at their configs and map it or add to my Meta database. Over time my understanding of the metadata I needed to define my projects was augmented by many other projects as well.

So with one central meta database I can generate all of the configs to wire together the various tools. I love the flexibility. I have all the info I need, and I didn't have to write Hibernate, Struts or Maven.

I currently think this mapping will always be necessary so long as tools are developed by different people with different goals. I think this is what tools like Spring and Copland are supposed to address with AOP, but I have not tried them yet.

Caveat:
I think the biggest problem currently is that my system is fairly complex. I think it's elegant, and it does a lot of work for me, but you have to know when to regenerate your persistence layer, and rebuild your database, etc. I have simplified this greatly with maven plugins that do everything for you. Running the cloudscape database is pretty sweet too since it means people can get started without having to configure a database, which is a big win since my goal is to Empower Domain Experts (who aren't programmers).

Minor Thoughts:
tools are coupled to a philosophy. The tool builder had something in mind. It may or may not coincide with your philosophy.

Main Thoughts: (attempting to be language neutral)

  • A centralized Meta database allows me to store business system meta data separate from implementation complexities.

  • Learning all the rules you have to conform to for any tool is hard. Trying to conform to the rules many tools can be error prone and extremely difficult.

  • Using existing tools is crucial so I can focus on my application/tool.

  • Wiring together tools with custom adapters allows me to define my framework's semantics instead of trying to merge multiple tool's philosophies.

  • A single way of thinking is easier to teach a newcomer.

  • No one needs to know what tools the framework uses. (I believe this is just plain old OO design)



Questions I need to Answer:
Understanding the concepts to begin with is a learning curve. Mapping terminology to the concepts is a learning curve. Is learning a new set of rules harder than adapting any moderate number of ideas to work together?

Things Missing:

  • I currently can only generate a persistence layer from the metadatabase.

  • I have not yet integrated Struts into my toolset with generation and plugins.

  • I cannot capture business rules in metadata, they must be coded in Java in either Domain Object classes or Struts Actions.

  • I still don't have the rich UI metadata that started me down this road years ago.



And that wraps up my current state of mind, before everything gets torn asunder at RubyConf 2004. Should be interesting.



Footnotes:


The Pragmatic Programmer
This book changed a lot of things for me. The book crystalized ideas I already had, and many I didn't. Most notably I think, it let me know I was not crazy, there was a better way. Nowadays, simply knowing a person liked that book gives me confidence in that person, because that means they want to be a better programmer.