6 open source community anti-patterns (or less talk. more do.)

The Jakarta project, if you’ve never heard of it, it was once the
center of all innovation in Java, and that isn’t hyperbole. Just about
every Java developer is still using many of the projects that were
started in Jakarta at the beginning of the century: Tomcat, Ant,
Maven. While Jakarta had a huge impact on open-source Java, it also
underwent a massive transformation in 2004. Around that time it
became clear that Jakarta wasn’t a healthy community. It was too big,
there was a strange separation of commit access and PMC membership.
It had become an unmanageable “star stage” with 700+ committers paralyzed by
endless (albeit entertaining) flamewars.

The ASF Board decided to split the beast up into what you have now
where each project is a separate community unto itself. The current
approach leads to smaller, more focused communities. The Cassandra
project isn’t bothered by the Maven project’s decisions which isn’t connected to
the Felix team, and so on. The Board decided that “Umbrella” projects didn’t
work and that they added in layers on unnecessary management (they
were a distraction).

What I remember the most from that transition was
seeing how levels of rule making start to emerge once a community
attains a certain size. Once enough people are participating and
paying attention, participation in an open source project starts to
become more about endless email threads and less about code and

In this post, I’m going to talk about some of the community
dynamics that emerged five or six years back. As many of the now
separate communities are growing up, I wonder if people are seeing
some of the same patterns emerge. A few “personalities” emerged five
or six years ago, which I lump into the following categories:

The Rulemaker
These are the developers who are so irked by the idea that there
is variation in both code style, tool selection, and process that
they take it upon themselves to advocate and enforce standards.
“All projects need to standardize on Apache Ant.”, or
“Every project must use GUMP.” With size comes
infrastructure, and to a certain point there has to be a few rule
makers in any community, but you want to limit scope and reserve
rights for individual groups of developers. If your community has
devolved into rulemaking, do what the ASF Board did to Jakarta,
split it up into smaller, more focused teams. If your open source
project is governed by those closest to the code, there’s a natural
tendency to avoid needless b-cracy.
The Open-Source Politician
Politics is a fact of life at any scale. Even groups as small
as four or five people still have to manage the occasional super ego
or weather some sort of schism, but when your audience grows to the
hundreds the political grandstanding turns into heated, religious
warfare. I tend to think that this was the problem the Board was
most concerned about – the idea that teams of developers were being
distracted by flamewars over nothing. The problem with this
particular archetype is that it is infectious, once you get a handful
of politicians, everyone starts posturing like a politician on the
massive shared project list. Even if you don’t have a stake in a decision, you participate just to be a part of the decision making process. How do you avoid the Open-Source Politician?
Short answer is that you don’t, by participating in open source you
are, by definition, participating in a human, political process.
How do you avoid attracting the Grandstanding, Open-Source
Politician? Favor action over discussion, welcome initiative, and
try to find a way to discourage non-participants from contributing
only to the discussion.
The Attack Dog
There was one particular individual who was so full of vitriol
that whenever he would enter into an argument all hope of a
rational comprimise had to be abandoned. Half the time the Attack
Dogs starts barking you are not even sure if he understands why
he’s barking. All you know is that he is barking and that it is
better for you to not pour fuel on the fire. Attack Dogs are
distinct from trolls in that they are invested in the outcome. I never figured out how to deal with Attack Dogs other than to tip-toe around their pens. If your open source project has a few attack dogs, put them on a leash. Make it clear in your community that respect and decorum are required. If they rip someone’s head off on the general mailing list, ban them for a week. Open source needs less Testosterone-driven screaming.
Non-Contributing Pontificators
What does this mean? Let’s say you participate in an open source community that is having a constant flame war over some toxic issue like Ant vs. Maven. It accomplishes nothing, but it attracts an audience of non-contributors once every few months. These arguments often attract people who have no involvement in a project, and people who are just driving by and gawking at some trainwreck of a discussion. If your project were just off on its own somewhere with a GitHub project and ten contributors, no one would notice, but at the ASF in the old Jakarta world, there were multi-year lurkers who whose only contribution over a multiple year limit was discussion. If you find your open source project starting to experience the non-contributing pontificator, there’s an easy fix. Start calling them out on public lists, “That’s a great idea, but I see that you just joined the mailing list last month and I haven’t seen any patches yet. If you want to start contributing I’d be happy to help.” Statements like that are usually enough to shoo these people away.
The Back Room Dealers
Silly things like Commons Math. No, really, an open source
library devoted to simple numerical calculations were encouraging
backroom, off-list conversations about political strategy. So and
so doesn’t get along with so and so, and is going to veto an attempt
to add them as a committer. Some other person was asking people to
+1 a new committer so that they could gain more momentum for a
controversial change. I’m convinced that this sort of silliness
persists throughout open source. If you can avoid offlist antics,
do so.
The (Apache Way) Ambassador
If I had a nickel for each time someone said, “That isn’t the
Apache Way…” I’d be a rich man, and I’d also have a collection of
bizarre, contradictory emails. The ASF means many things to many
people. I only pay attention when someone from the Jedi council
chimes in, but even then I’ve seen “The Apache Way” used for justify
or prevent a number of things. I think I remember someone recently
saying that DVCS was not “The Apache Way” which just seems silly,
but then again I don’t buy much of the hocus pocus. To me “The
Apache Way” means “small groups of reasonable people not getting in
each other’s way, valuing action over discussion, and not getting in
the way of initiative”. Unfortuntately, I’m not sure that’s the
definition that has won out in some communities. Apache Way
Ambassadors are really just an alternative form of The Rule Maker,
except they are appealing to “fundamental rules” which are often
ill-defined. In particularly nasty email threads, “The Apache Way”
will tend to show up ala Godwin’s Rule
once someone’s made an appeal to Meritocracy, it is far to
late. (Note, you’ll still find me rolling into a conversation and
telling someone that aren’t being very “Apache”. I do this as an
outsider, and usually in response to someone devaluing initiative in
a project they’ve long abandoned.)

And, while the Politicians, Attack Dogs, and Anti-trolls were at
each other’s throats, another set of programmers was getting real work
done. I call them…

The Initiators
The initiators are the polar opposite of the politician.
Instead of wanting to engage the community with flighty rhetoric,
they would often just ignore the discussion and decide amongst
themselves. If they needed to use Maven, they would proceeed
without asking permission. They would ask each other if it made
sense and, as a smaller group, they would make the decision to
proceed. They would engage the larger community after the work had
been completed and, if anyone had an issue, they would argue on the
merits, but this kind of programmer saw no need to engage in
discussion for the sake of discussion. If “the community” didn’t
have the same ideas and they felt strongly enough, they’d maintain
an external fork or quietly develop on a branch. (Even though many
would call this sort of behavior “anti-community”, it actually turns
out that this is the silent majority of open source

A recent discussion on Jakarta reminded me of some of these old
roles, and a recent discussion with someone about the Velocity project
also reminded me of some of the “control” issues that seem to corrupt
the process at Apache. Don’t get me wrong, these roles are not unique
to Apache, open source attracts a “special” mix of personalities. I’m
generally positive about the ASF, I think that people do great work
there, and I’m happy when I see a company like Google or
Facebook decide that the ASF is a good platform for open source
projects. That being said, I have decided to contribute in my own way
from outside of the formal structure of the Foundation (I’ll save that
for another post, I think the structure of the place has a corrupting

If you find yourself working in an open source project that has
grown rapidly, there’s a good chance that you’ll notice the emergence
of some of these same archetypes. If you find yourself spending more
time dealing with community issues than dealing with code, you might
want to think about proposing a peaceful breakup to reduce the
organizational tendency toward procedure once communities scale. If
you find yourself participating in longish email threads with a larger
population of observers than participants, it is time to start
focusing. If you want your community or project to succeed, start
encouraging both new and existing developers to be Initiators.

Rails v. Liquibase: Creating Tables in Liquibase (Part 6)

Creating a table with Liquibase is straightforward. Unlike Rails, there’s no choice that has to be made about whether your database migration (or “change set” in Liquibase) is connected to a model object. It isn’t. Liquibase isn’t concerned with your application, as it only does one thing: it manages database changes. When compared to Rails it also makes fewer assumptions (if any) about table names and relationships. In this post, I’m going to introduce some very basic change sets to create tables. One change set will use the Liquibase createTable element and the other will demonstrate how to do the same thing with raw SQL.

Compare the Liquibase change sets with the Rails migrations from yesterday’s post covering the same topic from a Rails Migrations perspective.

Creating a New Table with Liquibase

Note: If you want to follow along with this post and experiment
with Liquibase you will find instructions for setting up a new
Liquibase project in this post

If you created the project from this post, you have an
empty Maven project with an empty Liquibase changelog and you’ve
already run “mvn liquibase:update” to create the necessary support
tables in your database. Since a datbase without tables isn’t very
useful, let’s see what it takes to create the tables from yesterday’s
Rails post

In liquibase, you create a new table by editing your changelog.
In this project, your changelog lives in src/main/db in a file named
db-changelog.xml. Let’s create the politician table by putting the
following XML in your db-changelog.xml.

    Creating the Politician Table

To execute this changeset, execute “mvn liquibase:update” from the
root directory of your project. You should see the following output
as Liquibase connects to your database, reads the DATABASECHANGELOG
table and figures out which updates need to be executed against your

$ mvn liquibase:update
[INFO] --- liquibase-plugin: (default-cli) @ liquibase-test ---
[INFO] ------------------------------------------------------------------------
[INFO] Parsing Liquibase Properties File
[INFO]   File: src/main/db/liquibase.properties
[INFO] ------------------------------------------------------------------------
[INFO] Executing on Database: jdbc:mysql://localhost/liquitest_development
Nov 26, 2010 8:51:57 AM liquibase.database.template.JdbcTemplate comment
INFO: Lock Database
Nov 26, 2010 8:51:57 AM liquibase.lock.LockHandler acquireLock
INFO: Successfully acquired change log lock
Nov 26, 2010 8:51:57 AM liquibase.database.AbstractDatabase getRanChangeSetList
Nov 26, 2010 8:51:57 AM liquibase.database.template.JdbcTemplate comment
INFO: Changeset
::(MD5Sum: a1416efaa95f2f91538ce37aae56b45)
Nov 26, 2010 8:51:57 AM liquibase.database.template.JdbcTemplate comment
INFO: Creating the Politician Table
Nov 26, 2010 8:51:58 AM liquibase.database.template.JdbcTemplate comment
INFO: Release Database Lock
Nov 26, 2010 8:51:58 AM liquibase.lock.LockHandler releaseLock
INFO: Successfully released change log lock
Nov 26, 2010 8:51:58 AM liquibase.database.template.JdbcTemplate comment
INFO: Release Database Lock
Nov 26, 2010 8:51:58 AM liquibase.lock.LockHandler releaseLock
INFO: Successfully released change log lock

If you look at your database, you’ll see that there is a new table
“politicians” with the fields: if, first_name, last_name, party,
created_at, and updated at.

What is in a changeset?

the changeSet element defines a group of database
changes to apply to the database. Each changeset is assigned a
unique id attribute and an author attribute. In addition to
these attributes, it is often a good idea to write a simple
comment in the comment element. After the identifying
information, you’ll see the element that tells Liquibase to create
a new table – the createTable element.

What’s going on in the createTable element?

Self-explanatory, this just configures the name of the table.
Here we’re just configuring the name of the column and the type
of the column.
When you are specifying database column type,
Liquibase does offer a series of abstracted types which are
translated to specific database implementations: BOOLEAN, CURRENCY,
we’re just specifying types “int” and “varchar(255)”.
When the database support auto-increment (for ids and other
values), you can pass in autoIncrement = true to create a table with
this feature.
The constraints element gives you the opportunity to put
constraints on columns. Is the column a primary key, is there a
unique constraint on a column, is there a foreign key? In this
example, we use constraints to make id a non-nullable PK.

You will also notice that the changeset specified
a rollback element. The rollback element is
important if you ever need to rollback change to the database. If you
want to rollback the change we just made to politician, you can
rollback with "mvn liquibase:rollback -Dliquibase.rollbackCount=1".
The "liquibase.rollbackCount" property tells Liquibase to rollback a
single database change.

Creating a table with Raw SQL

If you need to create database tables that make use of specific
database features, you will likely want to use raw SQL to create these
tables. If you are creating tables with partitions in MySQL, or if
you are passing table specific query cache configuration, the only
reliable way to do this in a tool like Liquibase is to use the sql
element in your changeSet.

    Creating the Election Table
      CREATE TABLE election (
      election_date DATE,
      name VARCHAR(128)
      ) TYPE=innodb;
      DROP TABLE election;

To execute this migration run “mvn liquibase:update” and to
rollback after running it run “mvn liquibase:rollback

In the next post, I’m going to draw some comparisons between Rails
and Liquibase in the area of table creation.