Thursday, December 18, 2008

Simple Maven Archetype

I've been doing more and more with Maven lately. We're currently beginning the effort to migrate some of our stuff to Maven at work. A new feature of the archetype plugin was introduced a bit ago to generate java projects from a menu. This is done using mvn archetype:generate. This provides you with a (hideous) menu of options to begin a new project from a template.

The problem I have with this (besides the menu being hideous) is that Maven still defaults the compiler to use source/target settings for java 1.4. Every project I do that uses Java 1.5 needs to have the compiler config settings tweaked to allow the use of 1.5. It is really annoying, so I created my own simple archetype that I can use and uploaded it to github for easy access. http://github.com/raykrueger/simple-archetype/tree/master

This new archetype generates an empty project with compiler settings for 1.5, includes the dev.java.net maven repository and has dependencies for slf4j and junit.

I may move this archetype project in the future into a collection of archetypes. So I can have a simple java one, a webapp one, and whatever else I come up with. If I do move them, I'll update this blog :)

Sunday, December 07, 2008

Hibernate-memcached 1.1.0 Released!

After a bit of trial and error with the maven release plugin, the latest release of hibernate-memcached is available. This release includes a few new features:
  • Support for the Whalin memcached client
  • New Key strategies: Md5KeyStrategy, Sha1KeyStrategy for reducing the length of keys
  • Better Exception handling during cache failure scenarios

This is the first release after moving the source to github.

I need to do some wiki work to get documentation up for how to enable and configure the Whalin/Danga memcached client. I hope to get to that some time this week.

The new KeyStrategy implementations for Md5 and Sha1 are there to reduce the size of the keys. Raymond He emailed me to point out that the obnoxiously long keys that Hibernate generates take up a lot of memory in memcached. Many records + ~250 char keys = a lot of wasted space. The new Md5 and Sha1 keys strategies simply take the fully qualified key name generated by hibernate-memcached and hash them up to take a lot less space.

The improved exception handling revolves around the addition of a new MemcachedExceptionHandler interface and a default LoggingMemcacheExceptionHandler implementation. Essentially the Spy and Danga memcached clients are wrapped up to eat any exception that comes out of them. There's really no reason for the cache layer to throw exceptions at Hibernate. Errors are logged as Errors, and a null is returned.

Enjoy!

Saturday, November 22, 2008

Rails 2.2 Released!

Rails 2.2 was released this week with some really interesting new features. Most interesting, to me at least, is "Thread safety and a connection pool". Rails applications are generally run using many single threaded instances through something like Mongrel. Now they'll be able to run multi-threaded, a huge leap forward.

What's most interesting, it almost only matters to JRuby users! For more information; have a look at Charles Oliver Nutter's post from a little while back: "Q/A: What Thread-safe Rails Means".

Friday, November 21, 2008

3 Reasons to Switch to Git from Subversion � markmcb

A great little comparison of day-to-day type operations with Git compared to Subversion.

3 Reasons to Switch to Git from Subversion � markmcb

Friday, November 14, 2008

Grails 1.0.4 Released

Grails 1.0.4 was released today. This is the first release from G2One after the SpringSource acquisition. I don't know much about new features yet though. So check the internets :)

SpringSource Team Blog: First Grails Release Under the SpringSource Banner

Sunday, October 19, 2008

O'Reilly Feeds Gone Wild

Anyone else notice that the news feeds coming from various places on the O'Reilly network have gone nuts? For instance the O'Reilly Ruby feed suddenly had like 20 Linux articles published at once. I also have a feed for articles from my friend Tim O'Brien that, right now, shows 42 new articles. Those articles all have the same publish date and are from just about every author in the O'Reilly network. Weird...

Fix it Tim(s)!

Wednesday, October 15, 2008

Yesterday's Post

I posted a rather lengthy article yesterday that got screwed up a bit. I tried to use "Windows Live Writer" to write the article offline. That didn't go well, as I accidentally posted just the title and the word "blah". I removed that immediately, but it sill made it to the feed somehow. When I reposted the final article Live Writer reused the URL and so therefore it never showed up in the feed.

Anyway, if you missed it, check out
"Using JRuby and ActiveRecord Migrations to Manage Database Change".

Thanks :)

Monday, October 13, 2008

Using JRuby and ActiveRecord Migrations to Manage Database Change

Managing change to your application databases is a very common requirement for any development team. The usual approach seems to consist of piling scripts into some "db/changes" folder in your project. This is probably fine for the most part, but when you have multiple databases in multiple environments, managing that across multiple developers can be a problem. If have the usual minimum of three environments (dev, test, prod) you have to remember to apply the right scripts in the right order in each environment. If you are doing iterative development you may be making small database tweaks here and there over a period of a week or two. The difficulty comes in trying to remember what script you applied last and which script you need to apply today.

Following our first instinct of storing sql scripts in source control, let's add another complication into the mix. What if you have to support multiple database engines, say MySQL and Postgres. There will be subtle differences in statements, and database specific properties that need to be set. Managing two sets of scripts becomes a huge pain pretty quickly. Now, as as Java developer, we get to use Hibernate to maintain database portability. Hibernate is a fantastic ORM library, and it comes with tools to generate the DDL needed to create your database from scratch. Unfortunately, it does not include any tools for managing incremental updates to that schema.

The Ruby on Rails folks came up with a solution to the issues above; ActiveRecord Migrations. Migrations are small, incrementally versioned Ruby classes that are designed to bring your database up to date in a controlled fashion. The basic concept is very simple. Store a "version" in the database and maintain a set of Ruby classes that can bring your database up to the latest version. The Ruby classes are numbered using the version they represent and include an "up" and "down" operation. So, let's say we have a current version in the database of "6" and Ruby classes numbered up through "10". When we execute the "migrate" command ActiveRecord will see the current version and see we have scripts that go beyond that and begin to execute their "up" methods in order 7.up, 8.up, 9.up, 10.up. If we wanted to bring our database down to version 8 ActiveRecord would in-turn run the "down" methods. Executing 10.down, 9.down; leaving us at version 8. ActiveRecord Migrations also address our second issue of portability. Your individual migration classes are written in a database agnostic "Domain Specific Language", which allows for the SQL to be generated at runtime for your specific database. Note that you can also execute arbitrary SQL if needed as well.

I intend to show how to do this from the perspective of a Java developer, deploying these changes into a Java deployment environment. This is where JRuby comes in. At my company we already have Java on all of our servers and development machines, but not Ruby (except maybe on dev boxes). Using JRuby allows us to run Ruby on top of the installed JVM without having to worry about installing Ruby. So, let's get crackin' here and do something.


Install JRuby

Download Jruby (1.1.4 as I write this) and extract it somewhere. For me I've dumped it in "~/dev/jruby-1.1.4". Set an environment variable called JRUBY_HOME that points to this location; EX: in .bash_profile: export JRUBY_HOME="~/dev/jruby-1.1.4". Add JRUBY_HOME/bin to your path and you're good to go; EX: in .bash_profile: export PATH=$PATH:$JRUBY_HOME/bin


Install Required Gems

Ruby has a library distribution mechanism called ruby-gems. A gem is a library, every gem has a version and some dependencies. JRuby comes with ruby-gems pre-installed, all you need to do is tell it to install the other libraries you want. We'll need a few of them to get started. Note that I'm going to use mysql via jdbc in this example. You can use the native Ruby drivers for your database of choice, or one of the supported jdbc adapters.

  • jruby -S gem install jruby-openssl (we won't use this, but JRuby will complain when installing gems without it)
  • jruby -S gem install activerecord
  • jruby -S gem install rake
  • jruby -S gem install activerecord-jdbcmysql-adapter

Since we're using the jdbcmysql adapter we'll need to throw the mysql jdbc driver into our JRUBY_HOME/lib directory.


Configure the Project

Let's start by creating a directory structure to work with. Let's create a folder called "activerecord" with a subfolder named "db" and a subfolder inside "db" named "migrate". Executing "mkdir -p activerecord/db/migrate" will do the trick. In our "activerecord" folder create a file named "database.yml". The .yml file extension means this is a yaml file, Yaml stands for "YAML Ain't Markup Language"; cute right? We're not going to get into yaml much, suffice to say our use of it here is like a properties file. We'll stick to name/value pairs. Our "database.yaml" file will have the following contents...

adapter: jdbc
driver: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost/test
username: root
password: whatever
Note that I am assuming mysql running on the localhost with a database called test. Adjust this file accordingly for whatever your database settings are.


Prepare Your Rakefile

Again, in our "activerecord" folder we're going to create a file named "Rakefile.rb". If you are familiar with Ant then you're familiar with the concept of Rake. Rake is the defacto build tool for Ruby and Rails applications. The Rakefile.rb file is equivalent to the Ant build.xml file, except that it's written in Ruby not XML. As a straight up copy and paste operation, your "Rakefile.rb" will have the following contents...

require "active_record"
require "yaml"

task :default => :usage

task :usage do
print "Executing \"rake migrate\" will bring the databse up to date\n"
print "To upgrade/downgrade to a specific version use: \"rake migrate VERSION=X\"\n"
end

task :migrate => :configure do
ActiveRecord::Migrator.migrate("db/migrate", ENV["VERSION"] ? ENV["VERSION"].to_i : nil )
end

task :configure do
ActiveRecord::Base.establish_connection(YAML::load(File.open("database.yml")))
ActiveRecord::Base.logger = Logger.new(File.open('migrate.log', 'a'))
end
If you look at it this file you can see how it is similar to an Ant build.xml file. The "task" blocks (the block is denoted by the do/end) are like "targets" in Ant. Here we've got a task named "migrate" that depends on the "environment" task. The "environment" task sets up our database connection using our Yaml file, and configures a log file to write to. Our migrate task simply tells the ActiveRecord Migrator where the classes are and optionally a specific VERSION to move to. Specifying a version is commonly used for rolling back to some point in the past.


Write Your First Migration

I'll put together the migration classes necessary to build a "user" table, and a "messages" table, with a cross-reference table joining users to messages in a one-to-many relationship. I'll do this in small steps so we can see it as a serious of migration steps. Let's start right off with the User table. In the "db/migrate" folder create a file named "001_create_user_table.rb". The name of this file is important and significant. The first part represents our version, in this case "1". Everything after that is actually ruby standard class file naming. We're defining a class named "CreateUserTable", which therefore means it should be in a file named "create_user_table". Why the swich from camel to case to underscores? I haven't a clue...

class CreateUserTable < ActiveRecord::Migration
def self.up
create_table :user do |t|
t.string :username, :null => false, :limit => 15
t.string :fullname, :null => false, :limit => 30
end
end

def self.down
drop_table :user
end
end
The migration above is a Class that extends ActiveRecord Migration, it defines two instances methods named "up" and "down". The "up" method calls a method (on Migration) called create_table and passes it a block. When create_table executes the block it will pass it a "TableDefnition" instance, which we named "T". We then call the "string" method on the TableDefinition and pass it "symbols" stating the name and a map (the comma-delimited name/value pairs) containing the options for the column. The "down" method just calls the "drop_table" method. If I have to explain what that does, you're in way over your head :)

OK, let's try it! Bring open a terminal to your "db" folder and run "jruby -S rake migrate". The "-S" I keep using tells Jruby to execute one of command from JRUBY_HOME/bin. If all goes well you should see the following output:

(in C:/source/activerecord)
== 1 CreateUserTable: migrating ===============================================
-- create_table(:user)
-> 0.0031s
-> 0 rows
== 1 CreateUserTable: migrated (0.0036s) ======================================
Once we've executed this migration we should be able to see our new table in mysql:
mysql> show tables;
+-------------------+
| Tables_in_test |
+-------------------+
| schema_migrations |
| user |
+-------------------+
The user table is our new table and the schema_migrations table was created by ActiveRecord to track the current version essentially. ActiveRecord actually keeps track of all the migrations applied to it as of ActiveRecord 2.0. If you see a schema_versions, table then you weren't following along very well as you have a really old version of ActiveRecord :)


Migrating the Rest of the Way

W'e're now going to push through our last migration; that message table I mentioned. First create file in "db/migrate" named "002_create_message_table.rb". That file will have the following:

class CreateMessageTable < ActiveRecord::Migration
def self.up
create_table :message do |t|
t.references :user
t.text :message
end
end

def self.down
drop_table :message
end
end
The new feature we're seeing here in the message table migration is the use of "t.references". Our create_table operation will always create an "id" column for us to represent the surrogate primary key for our table. In doing so ActiveRecord can follow some conventions here. Using "t.references" tells ActiveRecord to setup a foreign key to our user table id column. After that we tell ActiveRecord to create a text (clob) column named "message".

We're ready to execute our next migration. Again, ActiveRecord will look at the versions on our scripts we have provided and compare that with the schema_migrations table to decide what needs executing. Once that decision is made it will walk through them in order...

Executing "jruby -S rake migrate" should give the following output...

(in C:/source/dbupdate/activerecord)
== 2 CreateMessageTable: migrating ============================================
-- create_table(:message)
-> 0.0061s
-> 0 rows
== 2 CreateMessageTable: migrated (0.0085s) ===================================
Now let's have a look at what's in mysql...
mysql> show tables;
+-------------------+
| Tables_in_test |
+-------------------+
| message |
| schema_migrations |
| user |
+-------------------+
We should also see that our schema has been migrated up to version 2 by looking at our schema_migrations table...
mysql> select * from schema_migrations;
+---------+
| version |
+---------+
| 1 |
| 2 |
+---------+
2 rows in set (0.00 sec)


Downgrading

Our Rakefile.rb was looking for a VERSION parameter to read from to force our migration to go to a specific version. Generally speaking you use that to downgrade to a prior version for whatever reason. Let's try that now, execute the "jruby -S rake migrate VERSION=1" command to tell ActiveRecord to step us back to version 1. You should get the following...

== 2 CreateMessageTable: reverting ============================================
-- drop_table(:message)
-> 0.0044s
-> 0 rows
== 2 CreateMessageTable: reverted (0.0067s) ===================================

As you might have guessed ActiveRecord executed our CreateMessageTable.down method, at which point we executed the drop_table method to undo that version. And, again, if we look at the "schema_migrations" table we'll see that it too has been stepped down to version 1.

mysql> select * from schema_migrations;
+---------+
| version |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)


The Right Tool for the Job

By trade, I am a Java guy. I dabble in Groovy and Ruby and fun stuff like that, but still, I'm paid to be a Java guy. Sometimes you have to know when to use the right tool for the job. Even if you're not familiar with Ruby you really don't need to think of it that way. Ruby is used to provide you with the domain specific language used to handle portable database migrations. You don't need to concern yourself with learning the full extent of the Ruby libraries, or all of the fancy dynamic language features. You just need to pay attention to what values you're passing to these methods and in some cases (maps/hashes) their funky syntax. Honestly I've been looking at doing an article like this for a long time. I'm glad I finally sat down and right it. Hopefully this helps some folks see the power in stepping out from behind our Java comfort zone.


References

If you'd like to see what a large sampling of ActiveRecord migrations take a look at the ones in Trisano.

Sunday, October 05, 2008

Discursive: Tim O'Brien: Buy the New Maven Book Today (Support Free Books)

Discursive: Tim O'Brien: Buy the New Maven Book Today (Support Free Books)

I have a copy of this free book on the desktop of both my desktop and my laptop. An excellent resource for all things Maven. I'm planning to buy a few books here shortly, and this is on my list.

Hibernate-memcached moved to github

I just completed moving the source for the hibernate-memcached project from subversion at GoogleCode to GitHub. There's a great guide at GitHub about importing a project from subversion. The only notes I'd add is that you pretty much have to do the authors file trick or your history won't accurately show you as the person making the changes. Also, I had to push using "-f".


git svn --authors-file=/home/ray/.authors clone http://hibernate-memcached.googlecode.com/svn/tags/hibernate-memcached-1.0 hibernate-memcached
cd hibernate-memcached
git remote add origin git@github.com:raykrueger/hibernate-memcached.git
git push -f origin master
git tag hibernate-memcached-1.0
git push --tags


I probably could have tagged it initially, but I didn't think of it :P

Tuesday, September 23, 2008

Installing Adobe Acrobat Reader on Ubuntu 8

The stuff I saw out on the "internets" for installing this was totally bunk. Here's what we did...

wget http://ardownload.adobe.com/pub/adobe/reader/unix/8.x/8.1.2/enu/AdobeReader_enu-8.1.2_SU1-1.i386.deb
sudo dpkg --install AdobeReader_enu-8.1.2_SU1-1.i386.deb

Monday, September 22, 2008

What am I working on?

Lately I've been using Twitter more and more, and haven't really been updating my blog a lot. I feel bad about that really. I'd like to post more stuff more often, but frankly if it's one sentence worth of information Twitter is the way to go.

Currently I'm hacking on a few open source things (on top of my day job). First there's my hibernate-memcached project. I haven't done much with it since releasing 1.0 though. I still have a user submission to add support for the Whalin memcached client to add, as well as support for the new hibernate 3.3 cache SPI. I'm honestly not looking forward to that though, the SPI is pretty complex.

I'm also working on the Erma project. Erma is the open-sourced monitoring library from Orbitz. During my time at Orbitz I loved working with Erma and occasionally on Erma. Now that it is open-source I'm really glad I can stay in touch with it. I'm currently working on Maven-izing the build as the build it has now is pretty Orbitz specific and was dragged kicking and screaming into the public. Things were going relatively well until I ran into some issues with the tests being really fragile. I'll figure it out though.

Monday, September 01, 2008

Selling Git to the Business

An interesting article from Josh Symonds on selling Git to the business.
http://www.pathf.com/blogs/2008/08/selling-git-on-the-business-end/

Thursday, August 28, 2008

Max Payne

I've played the game and I loved it. I also dig Mark Wahlberg, he's a decent actor. I've been keeping an eye on the new Max Payne movie for a bit. Now there's a a trailer out there!
http://www.youtube.com/watch?v=JboQmDIdKWs
This... Looks... Awesome!

Wednesday, August 27, 2008

Note to Self: Read About Automating Ubuntu Installs

The Ubuntu documentation mentions using preseeding files to automate the Ubuntu 8. I may end up having the Ubuntu installs be automated into VMWare anyway, so maybe just a clean VM is the way to go.

Wednesday, August 20, 2008

Hibernate-memcached 1.0 released into the wild!

This evening I decided it was time to release hibernate-memcached 1.0. It has all the features I intended for it to have and I haven't seen any problems come up with it at all, so it must be time. Please, spend some time checking it out, even if you don't think you're going to use it right now. I'd really love to get some feedback and see if there is anything folks would like to see it do in a future release.

If you have any questions or comments please drop a line here or even use the hibernate-memcached Google group.

So, what next?

Tuesday, August 19, 2008

Hibernate 3.3 and Hibernate-memcached

I spent some time looking over the new Cache SPI released in Hibernate 3.3.0.GA. Definitely a much more in-depth API compared to the old CacheProvider/Cache interfaces. Following the new interfaces (RegionFactory, Region) you can be much more aware as to your specific responsibilities in the caching system.

I have tested that hibernate-memcached remains compatible with hibernate-3.3.0 and everything looks fine. I am going to hold off on implementing a RegionFactory/Region based implementation for now and do that as a post 1.0 release. It will require some refactoring to the current code base to get it to play nice with both APIs (I'd like to stay compatible with 3.2 for a while).

So, look forward to a hibernate-memcached 1.0 release tonight, or maybe tomorrow.

P.S. Hello China! According to Google analytics, a link from javaeye.com is generating 250+ hits a day to the hibernate-memcached project site right now.

Wednesday, August 06, 2008

Maven: The Definitive Guide

An informative book about Maven2, free, online, and straight from the source (the guys at Sonatype. Thanks Tim et al!

Tuesday, August 05, 2008

Hibernate-memcached in the MySQL faq

I was stumbling through google analytics today and saw that there were some referrals coming from dev.mysql.com. Apparently they added a link to the project in both the 5.0 and 6.0 faqs.
Neat!

http://dev.mysql.com/doc/refman/5.0/en/ha-memcached-faq.html
http://dev.mysql.com/doc/refman/6.0/en/ha-memcached-faq.html

Saturday, July 26, 2008

Hibernate-memcached 1.0-RC1 Released

This morning I've released hibernate-memcached 1.0-RC1. This release contains the new Dogpile prevention feature as well as some minor refactoring. If you're using hibernate-memcached, or are even slightly interested in testing out using memcached in combination with hibernate as a second-level cache, you should check this version out.

If you have questions or problems please visit the hibernate-memcached google group.

Friday, July 11, 2008

Dogpile Prevention for Hibernate-memcached

I posted on the hibernate-memcached project that I was going to release a 1.0-RC1 soon. I will, but first I want to implement one more feature that I think people might like; Dogpile Prevention.

If you're only running 2 or 3 instances of your application this really isn't a problem. If you're running 42 instances there is the risk of a "dogpile". If a frequently used item drops from the cache after it's expiration time comes up you run the risk of many instances of your application working concurrently to restore the cached data. Each instance overwriting the other instances attempt to update the cache until everyone sees the data is no longer missing. Other caching systems attempt to remedy this with locking. That's a really bad thing most of the time for scaling as you'd never want to have all the instances of your application synchronized on what one of them is doing.

To remedy this in hibernate-memcached I will follow the patterns mentioned in the article above. This new feature will go in as a configurable option that is, by default, turned off. I plan to make it configurable per cache-region so enabling it would look like hibernate.memcached..dogpile.prevention=true. There is a slight bit of overhead to this is why it won't be on by default. I may make it configurable at the global level as well with something like hibernate.memcached.dogpile.prevention=true.

Once I get this in and tested I plan to release a 1.0-RC1 version of hibernate-memcached.

Wednesday, July 02, 2008

Jt - Java Pattern Oriented Framework

Folks actually built an application framework dedicated directly to GOF software patterns. I'm pretty sure this absolutely what patterns were never meant to be used for. Software design patterns are meant to be applied to specific scenarios were they can be proven to be useful. Not as some golden hammer that when repeatedly bashed into your project will somehow produce the holy grail.

Tuesday, July 01, 2008

A Fantastic Example of REST

I don't know how I've missed Joe Gregorio's "RESTify DayTrader" article. THIS is what REST is all about. Great stuff...

Monday, June 30, 2008

Remember the Milk

This is the coolest use of Twitter I have seen yet...
Remember the Milk

Friday, June 27, 2008

Open Source Application Monitoring from Orbitz

This week Orbitz announced that our internal monitoring api "ERMA" is now open source. ERMA (Extremely Reusable Monitoring API), as a framework for monitoring the health of simple applications or large distributed applications alike. The framework is based on Aspect Orient Programming and Complex Event Processing.

I've had the pleasure of using ERMA at Orbitz on many applications and projects. I've also had the fun of contributing code to the ERMA code base even though it didn't really belong to my team. Sort of an "internalized open-source" model if you will, it's how things get done at Orbitz.

I am a member of the core team that will continue to develop ERMA and expand it into new areas (such as ERMArb). We've got a lot of planning to do to see where we want to go with it. ERMA has been extremely useful at Orbitz and I can't wait to see what others do with it.

Read more about it...
at InfoQ
at CNET

Thursday, June 19, 2008

Buying a Laptop: Mac or PC

For the first time, I find myself in the market to buy my own laptop. I've been going back in forth in my head about this. On one hand is the Macbook Pro with all it's sexiness. On the other hand is the fact that I don't know a damn thing about using a Mac. I could buy a PC laptop and install Windows and Ubuntu on it easily and have the best of both worlds.

Then a friend of mine at work (Thanks Ross!) pointed out that the Mac can do this too. Apparently the Leopard OS comes with "Bootcamp" which allows you to run Windows natively. Then I can do my Windows only stuff (like my beloved Tivo-to-go) without much hassle.

I'm all in now. I'm buying a Macbook Pro

(oh look, my first post with a "Mac" label)

Tuesday, June 17, 2008

Firefox 3 Download Day

Today you'll make history with Firefox

Are you ready to make history? Are you ready to set a World Record? Today is Download Day. To become part of the official Guinness World Record you must download Firefox 3 by 17:00 UTC on June 18, 2008, or roughly 24 hours from now.

Thursday, June 12, 2008

Videos from Google I/O 2008

The folks at Google posted a few videos from Google I/O 2008 on YouTube. I'm not sure but it looks like they posted videos of all the sessions too, nice.

Tuesday, June 10, 2008

Hibernate-memcached 0.6 released

I've released version 0.6 of the hibernate-memcached integration. Mainly this was to fix the "nextTimestamp" stuff that hibernate uses for query caching. Apparently that value needs to be "course grained" when using a distributed cache.
hibernate-memcached at Googlecode

Friday, June 06, 2008

Grails 1.0.3 Released

Graeme Rocher announced the release of Grails 1.0.3 this morning. Great news, time to upgrade my apps!
Read Graeme's post

Saturday, May 31, 2008

Introducing hibernate-memcached

Some of you may, or may not (care), know I am a huge fan of memcached. Its combination of simplicity, elegance and performance make it fantastic choice for any real caching solution.

I've recently begun work on implementing a bridge for using memcached as a second-level cache for hibernate. The project is hosted at googlecode right now, and the code is currently available in the googlecode hosted subversion repositories. In the future I'll probably move it over to github, but subversion is much more accessible to the public at large still.

Adding hibernate-memcached to your hibernate based application is as simple as adding hibernate-memcached.jar, memcached.jar, and spy.jar to your classpath. This can also be done using Maven.

Enabling the hibernate-memcached cache is simple as adding two properties to your hibernate config.

hibernate.cache.provider_class=com.googlecode.hibernate.memcached.MemcachedCacheProvider
hibernate.memcached.servers=server1:11211 server2:11211

Property #1 tells Hibrnate to use the MemcachedCacheProvider. Property #2 tells the MemcachedClient in use what servers to use for the cache. It really is as simple as that.

There are many other configuration properties available to configure things like the default and per-region cache times, operation timeout, hash algorithm to use, and what key strategy to use.

The hibernate-memcached cache is working great for both individual entity caching and query caching. I currently have a lot of work to do around getting documentation up on the googlecode site. It is ready to play with and easy to setup, if anyone out there has the time to check out; please do! If you run into any questions or problems you can post them on the hibernate-memached google group, or open an issue at googlecode.

Thursday, May 22, 2008

SAP Memory Analyzier

I know nothing about SAP, but they built a nice memory analyzer worth checking out.
Check it out

Wednesday, May 21, 2008

Scalability Principles

Author Simon Brown discusses 7 principles of scalability.

1. Decrease processing time
2. Partition
3. Scalability is about concurrency
4. Requirements must be known
5. Test continuously
6. Architect up front
7. Look at the bigger picture

Check it out

Friday, May 16, 2008

David Heinemeier Hansson at Startup School 08

David Heinemeier Hansson, creator of the Ruby on Rails framework and Partner at 37Signals gives insight into creating a profitable startup company.
Watch it

Wednesday, May 14, 2008

Better World Books

I found Better World Books a while back by reading a story I don't remember now. I had completely forgotten the name of the site and couldn't find it again, until now. I am selfishly blogging this so I don't have to look for it again :)

That being said, check out Better World Books next time you're looking to by some fat-ass technical book. Their mission statement sums it up pretty well...

Better World Books capitalizes on the value of the book to fund and support literacy initiatives locally, nationally, and around the world.

Thursday, May 08, 2008

Pro Web 2.0 Application Development with GWT

Jeff Dwyer has just released his book on GWT. Jeff is a really bright guy and has done some extensive work with GWT. Aside from that, he's a good guy so throw him a bone and check it out...

Pro Web 2.0 Application Development with GWT

Distributed Version Control

I've recently done some work with git as a source control system. I was pretty impressed by its functionality and the overall concept of distributed version control.

In my career I've been exposed to a rather limited set of version control systems. I've used CVS, Subversion, SourceSafe and Accurev. Each of those systems are based on a central repository with many clients. The concept is a simple client-server model that is very easy to understand.

Git is a "Distributed Version Control" system. This means that everyone effectively has their own repository of the code that they can fork and merge as much as they'd like locally. DVCS systems like git work on a peer-to-peer model. This is a very powerful feature in that if I have some code that you would like to integrate with I can exchange it with you, and you alone. In a VCS system like Subversion or CVS, I would have to commit my changes to the central repository for you and everyone else to get. Sure, I could branch and put my changes there, but merging that back in is a huge pain in Subversion and CVS.

InfoQ just posted a lengthy article discussing Distributed Version Control Systems such as git, mercurial, and bazaar.

Sunday, May 04, 2008

SpringSource Application Platform Details

Last week SpringSource announced their Application Platform project. It is an interesting attempt at slimming down the J2EE environment by tying things like Spring and OSGI together. On the SpringSource Team Blog, Rob Harrop begins an in-depth explanation of SpringSource Application Platform and it's features. Very interesting stuff...

Thursday, May 01, 2008

Trying to get Git

I'm trying to patch some stuff in the java-memcached-client right now. The code is hosted at GitHub. I've never used Git in my life so this is a brand new experience for me. Boy did I screw this up :P
I've got branches gone wild and accidental reverts. I think I'm starting to get the hang of it now though. Thanks to this cheat sheet, and this tutorial.

Wednesday, April 30, 2008

SpringSource Application Platform

The guys over at SpringSource have created an "Application Platform" based on Tomcat, Spring, and OSGI. Interesting stuff, read more at InfoQ.

I'm gonna get my hands on the beta. Though if they intend to release it as Open Source anyway, why is there a beta sign up? Odd...

Wednesday, April 16, 2008

Mastering Grails

Scott Davis has posted "Mastering Grails: Many-to-many relationships with a dollop of Ajax" in the Mastering Grails series. If anyone can master Grails; it would be Scott Davis. Have a look.

Thursday, March 13, 2008

Hibernate and Memcached

As I mentioned at the end of my last post, Cache Everything, I am working on building a library to use memcached from Hibernate as a second level cache. That project is hibernate-memcached and its in it's infancy over at googlecode.

The Hibernate second level cache is used to cache items between session invocations. Hibernate always uses it's session as a first level cache, but if you want to avoid database hits between sessions you need a second level cache. If you want these caches to stay in synch between several instances of your application, you need a distributed second level cache.

Memcached is a fantastically fast distributed cache, so why not use that? Once I build a jar of the hibernate-memcached project you'll be able to include it in your application and tell Hibernate to use it. Telling Hibernate to use it means adding the cache_provider property to your hibernate.cfg.xml, or your Spring LocalSessionFactoryBean if you're using that. The hiberante.cfg.xml looks like this...

<hibernate-configuration>
<session-factory>
<property name="hibernate.cache.provider_class">com.googlecode.hibernate.memcached.MemcachedCacheProvider</property>
<mapping class="com.yadda.yadda.Something"/>
</session-factory>
</hibernate-configuration>


Then, in your mappings you tell Hibernate that you want instances of your persistent objects to be cached, or collections from relation ships to be cached. Once Hibernate knows what you want cached you can watch it pump stuff into memcached, which is good clean geeky fun. Fire up memcahed (on windows or linux) using the -vv command line option to make it run "very verbose". You can see it storing and responding for each operation taken.

You can play with the code straight out of subversion at google code. It will actually work and cache stuff, but it is currently hardcoded to look only at localhost:11211 for a memcached instance. I'll get around to making it configurable. To build the code you'll need Maven2. I highly recommend using Don Brown's no-suck port of maven2 actually.

More to come...

Cache Everything

So I'm working on this Web Service project and its time to consider scalability. Which means its time to setup memcached. If you haven't looked at using memcached, you should.

Memcached is a totally stupid-simple distributed memory object cache. It's this super tiny application that slices off a chunk of RAM and listens on a port. Yeah, that's about it :)

It gets cool to talk about when you start talking about making it "distributed". When you start talking about "Distributed Caches" people start thinking about Coherence and other hugely complicated and hugely expensive enterprise applications. It really dosen't have to be so hard.

Here's what you do. Get a couple cheap boxes with one or two gigs of ram in them. Install the Linux flavor of your choise. Install memcached and run it with "memcached -d -m 1024". This will start memcached on it's default port (11211) and allocate 1gb of ram to the cache. If you do this on three boxes, you now have a 3gb distributed cache.

There are client libraries available for most popular languages. If you're using Java I'd highly recommend using spymemcached from Dustin Sallings.

So you give the clients a list of servers to connect to and they will basically treat that big distributed cache you created as a huge hashtable. Each get/set operation has a string key that is hashed and used to decide what "partition" of the cache to read/write to. If an instance goes down the client just begins distributing reads/writes to the other instances until the missing member comes back.

Using any of the client libraries, in just about any language, your usage looks like this:

  • Check the cache for your object.

  • If your object is not null, return the object.

  • Otherwise, read the object from the database or what have you.

  • Put the object in the cache.

  • Return the object.



Memcached uses a very light and fast binary protocol which makes it usable by just about any language. There are pre-built packages in apt if you're using Ubuntu, you can easily build it from source for just about any other *nux flavor. There's even a windows port. I've only used that for dev at this point though.

I'm working on writing a second level cache for hibernate that uses memcached. It is super simple, but I just started work on it last night (seriously). Check it out if you want. I plan to work on it over the next few nights and get it ready for prime time :)

Wednesday, March 05, 2008

Open Source Licensing: WTFPL

I think I'm going to start using this license for any open source stuff I do...
WTFPL

Friday, February 29, 2008

Battlefield Heroes

I can't wait to play this!

Tuesday, February 05, 2008

Grails 1.0 Released

Graeme Rocher, from G2One Inc., announced the release of Grails 1.0 this morning. The release notes are available from grails.org.

If you're a Java person and aren't familiar with Grails or Groovy for that matter, you should definitely check out Grails. Grails is a rapid web application development framework based on convention over configuration. It is designed MUCH like Ruby-on-Rails, but built using Groovy as a language. The main benefits of this approach is that Groovy is based on Java; which means it looks and feels like Java. This helps introduce it to a team and lower the learning curve. The other benefit is that it builds down to a WAR file that you can deploy into any old application server. No special hackery required. This is important when deploying it into a very 'enterprisey' environment.

Also, the internals of Grails and how it works are not based on it's own invented voodoo. Grails uses Spring, Hibernate, and Acegi internally. Good stuff...

Sunday, January 27, 2008

Out of the Sandbox: Spring-Security OpenID Support

I just finished moving the OpenID support For Acegi/Spring-Security out of the sandbox and out into it's own module. It is in dire need of documentation, but the code itself is pretty solid.
Here's the post to the mailing list.

Sunday, January 20, 2008

Save Windows XP







InfoWorld has started a petition aimed at getting Microsoft to keep Windows XP support around past the June 30th end-of-life date.

To summarize, here's why I like XP...

  • XP is simply the best OS Microsoft has produced. I realize that doesn't say much, but it's true.

  • I am a gamer. I'd gladly run Ubuntu or Fedora Linux, but I am not down with playing Pac-man, Super-pacman, or one of 200 Tetris clones.

  • I'd love to get a Macbook, but they're really expensive, and again, I don't like pacman.

  • Vista blows



So, sign the SaveXP Petition at SaveXP.com

Wednesday, January 16, 2008

Sun to Buy MySQL

This is huge news! MySQL has to be the single most popular open-source database in the world.

Tuesday, January 15, 2008

Acegi OpenID Support Update

I said I'd work on the OpenID support in Acegi (aka Spring-Security) and I finally did. Really nothing major, I refactored the functionality from the CAS package that we needed in OpenID up into its own existence in the "providers" package. So now there's a now AuthoritiesPopulator and DaoAuthoritiesPopulator impl that uses the UserDetailsService to look up Authorities for a given principal. This functionality was being "borrowed" from the Cas package, now it's been refactored up. For backwards compatibility I've left the original CasAuthoritesPopulator and DaoCasAuthoritiesPopulator items in as subclasses of the new classes. Both of those extensions are empty now though. They should be removed in the future.

Also, I've removed the janrain support as Janrain is dead. Spring-Security will now use openid4java exclusively. It has been updated to version 0.9.3 of that library.

Now the call goes out to Jeff Dwyer to update MyHippoCampus to the latest stuff and put it through its paces. Thanks Jeff!

Next up? Well, I'm going to slap it into one of the samples and do some testing, and then work on promoting it out of the sandbox. Hopefully we can get openId support into the main project soon :)

Wednesday, January 09, 2008

OpenID Gains Steam

From Techcrunch

TechCrunch UK’s Mike Butcher is reporting that Google, IBM and Verisign are in late stage discussions with the OpenID Foundation.

Good to see OpenID getting some traction. I really regret not finishing up the OpenID support for Acegi now. The code is still there in the sandbox. It apparently works, the folks over at MyHippoCampus were using it.

Tuesday, January 08, 2008

An Exercise in Flowcharting

This made the rounds a while ago, I thought it was great. It needed to get dusted off, so here it is. Enjoy...

Wednesday, January 02, 2008

Is Rails a Ghetto?

Zed Shaw, creator of the extremely popular Mongrel server for Rails applications, thinks so.

Rails Is A Ghetto

Even if you don't know a damn thing about Ruby or Rails this is some pretty funny shit.