Butterfly Components - Introduction
By: Jakob Jenkov
Butterfly Components is an ultra lightweight Java application
stack and tool box. The components can be used either separately
or together, in concert. Each component is downloaded separately and the
download page states what other components (if any) that component
depends on. Most components have no dependencies.
The focus of Butterfly Components is on ease-of-use, flexibility, lightweight and
performance. This focus means that polishing existing features is often prioritized
higher than adding new tools. In other words, making sure that what is already included
is easy to use, rather than add more hard-to-use-and-understand components.
One of the goals of Butterfly is to develop small components that are very flexible, and
thus mature quickly. Thus, do not expect hundreds of versions, and all kinds of odd bells
and whistles added. The Butterfly components will be designed so you can add all that yourself.
I don't want Butterfly to end up like Spring, with 30-50 MB JAR files, just to support your
1 MB application. No thanks. Small is elegant. And I'm all about elegance.
In the rest of this text I will explain the motivation behind Butterfly Components.
Here is a list of the topics covered:
- Why Yet Another Java Application Stack?
- Butterfly Design Philosophy
- Getting Started ...
Why Yet Another Java Application Stack?
I keep getting this question from friends and colleagues, and I also
ask myself this question from time to time. I am not the kind of person
that absolutely must invent everything myself. If what I need is of a
reasonable size, I search the internet for a project that already does this.
If I cannot find a suitable project, or I am not happy with what I find,
I implement the component myself.
Once in a while I come across genuine pearls like Jetty
or H2 Database.
But frankly, most of the time I would have done things differently than the projects
I look at. In addition, with the explosion of available frameworks you can sometimes easily
end up spending more time checking them all out, than just implement it yourself.
(This also counts for checking out Butterfly Components! )
Why Butterfly DI Container ?
I was excited about the dependency injection container
idea, so I looked at both Spring and Pico,
but I wasn't really happy with either. So I sat down and thought about how the
optimal, perfect DI container would look, and how it would be configured etc.
I examined the configuration options of XML, plain Java, and annotations. I arrived at,
that an external script language would often be a good configuration mechanism. A mechanism suitable
for both wiring up components, configuring URL's in a web app, external application configuration files,
and internationalization of components. This is how Butterfly DI Container was born.
Why Butterfly Web UI ?
I started out with Struts in 2002 and started to like it until someone pointed out
some of its rough edges. Like, how a form object isn't always what you need (you
need to copy directly into a domain object), Strut's slightly annoying configuration
mechanism etc. So I started checking out alternatives like Spring MVC and Wicket. In
Spring MVC I didn't find much new compared to Struts, except the use of DI, and a slightly
different component model. Then I looked at Wicket. After a bit of frustration understanding
the component based model rather than Spring MVC's and Struts Model 2 designs, I
finally got it. Now I really like the component based model rather than the older Model 2
architecture. Component based models has several advantages. The reason I didn't stick
with Wicket was that Wicket didn't come with a DI container. I also wasn't sure I liked
Wickets proprietary template language (page layout). So I thought: Why not
implement a light weight edition of Wicket? This is how Butterfly Web UI was born, using
Butterfly DI Container for configuration, and plain JSP as template (page layout) language.
Why Butterfly Persistence ?
This is also how Butterfly Persistence came about. A surprisingly large number of times
the world fits reasonably into tables and records. And, a reasonable amount of times you
actually need to work on records, for instance update all records matching a certain criteria.
In addition, sometimes you need to display composite views of data from joined tables.
And sometimes you need an object representation of the records. I checked out several ORM's
like Hibernate and Cayenne. But they seemed to overdo the ORM-focus compared to what I
most often needed (or wanted at least). That's why I decided to implement Butterfly Persistence
(called Mr Persister back then). Since then I have heard from some colleagues, that
they have had as many problems as benefits from ORM's. That simple JDBC utility layers
seem to work best. Feel free to disagree here - these arguments are not scientifically founded.
Why Butterfly Testing Tools ?
Back in 2001 when "Mock Testing" was the big thing, I looked around for a mock object
testing framework to use. I came across EasyMock and JMock, but I must admit I didn't
really like neither. EasyMock seemed all backwards to me. First you setup the expectations on
the mock objects,
then you "replay" (?!?), then you run the code against the mock objects. In Butterfly Testing Tools
you first create the mocks, then call the methods on them you want to, then finally check if
the mock objects were used correctly. This seems more in line with my way of thinking.
JMock seemed too big for what is was doing (but that is a personal opinion, remember!).
So, i decided to implement Butterfly Testing tools (called Testimonial back then).
Butterfly Design Philosophy
Having wondered why I so often wasn't quite happy with the components I checked out, I
tried to write down my design philosophy. Perhaps that way I could spot why I didn't like
a certain framework / component. So, here it is - the philosophy I am basing Butterfly Components
development on. Or, at least as much of it as I am conscious about. Feel free to disagree,
and to contact me via Jenkov.com with your arguments.
I have also gathered my API design experience in the
API Design Tutorial on my
growing tutorial site.
Size Does matter
The first rule in the philosophy is that "Size Does Matter". It seems to be a wide spread
opinion that the size of your components doesn't matter. Whether your component takes up
1 MB or 50MB doesn't matter. It will be deployed on a server anyways with lots of hard drive
space. However, during development you will often need to zip up all those external JAR files
into a WAR or EAR file, to test deployment. Then 1MB or 50MB external JAR files do make a difference
in how long time it takes to zip up those JAR files.
Ease of Use Does Matter
Some projects seem to care more about adding new features than making the existing
features easier to use. In Butterfly I try to provide a sensible mix of both, often
prioritizing ease-of-use over new features. After all, I'd rather have a polished, elegant core
than a hundred different peripheral components, that noone really wants to use because
they are all mediocre.
Some projects seems to have bought into the you-can-always-change-it-later tendency
spread by the KISS and YAGNI philophy. However, the rules for API's, components and
other standard products are a bit different than for inhouse enterprise projects.
Once an API is released and people start depending on it, change is expensive.
You may not be paying the price in terms of having to adapt all these peoples code
to the new interface. But you may be paying the price in people leaving your project
for something else, or having to support older versions because people have not upgraded
I spend a long time on upfront design of the Butterfly Components. I try to imagine
all the use cases, and try to figure out an interface that serves all these use cases
in the simplest possible way. With the least effort for the user. Of course I've had
to change the interface or implementation once in a while, as I learned how a component
was really used, or learned about new use cases, or about "90% use cases".
Often though, the upfront design phase
has resulted in a small, flexible core that could later easily be bend in several
directions without breaking.
Zero External Dependencies
External dependencies are evil and should be avoided at all costs. Therefore Butterfly Components
will have no external dependencies. By external dependencies I mean projects not part of
Butterfly Components, like Apache Commons etc.
External dependencies can easily inflate the size of a component or application. If all you need
is what takes 10-50 lines of code to write yourself, and you include a 1 MB external JAR file, you
may very well be making a bad deal. Size does matter!
In addition external dependencies can easily result in a dependency mess! All of sudden one component
you are using depends on component ABC v. 1.1, and another component depends on ABC v. 1.2.
If ABC v. 1.1 and 1.2 are not dropin-compatible, you've got a problem!
Minimum of Internal Dependencies
By internal dependencies I mean dependencies between the various Butterfly Components. So far
only Butterfly Web UI depends on another component - Butterfly Container. In that case it makes
a lot of sense, because Web UI needed a lot of what Butterfly Container provides. In addition,
I could easily imagine that an application based on Butterfly Web UI could benefit from Butterfly Container
quite a lot too.
The minimal internal dependencies also makes it possible to pick just a single Butterfly component for
your application, a handful, or the full stack. It is up to you.
NOTE: Some of the components may be designed to integrate well with each other, but whenever possible
this integration will be optional, and not result in dependencies. For instance, I am considering a configuration mechanism for
Butterfly Persistence that will make it easy to configure object-to-table mappings from a Butterfly Container Script.
This configuration mechanism will be optional, and will not depend on any of the
Butterfly Container classes. It will be there as a service, not a requirement.
Pick the Best Ideas from Similar Frameworks
Butterfly Components will often not be among the first to implement a new idea. Sometimes because
of limited development resources, and sometimes simply because I want to see how the idea turns
out in reality in other projects, before cluttering Butterfly Components with them. That way
I can pick and choose the best ideas from other frameworks - the ideas that prove themselves -
and leave out the ideas that turn out not to be as fantastic as imagined from the outset.
EJB's have always puzzled me. They sound very powerful in theory, but in practice I have yet to
see a single case in which ordinary Java classes weren't preferable. A real case I mean. Not
a theoretic case.
Butterfly Components will run without EJB meaning it can run in standalone applications, or
inside a Java Servlet Container like Jetty or Tomcat.
How you start using Butterfly Components depends on which of the components you intend to use.
Each component has its own "component website" where you can read its documentation and download
To learn about a specific component, click the component links in the upper right corner of this page.
If you don't know which component to start reading about, I would suggest that you browse through
the component introductions in the sequence they are listed in the menu at the top right corner
of this page, or at the bottom of this page.
I'd suggest you start reading about Butterfly DI Container.
It is a very useful and flexible
component that you can most likely always benefit from in your applications, no matter if it
is a web app, a desktop app, or a standalone server app. In addition, if you plan to use
Butterfly Web UI you will need to understand Butterfly DI Container too.
Back to Top