<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Fourspaces.com</title>
    <link>http://www.fourspaces.com/blog</link>
    <description>Coding and science from the trenches.</description>
    <image>
      <title>Fourspaces.com</title>
      <url>http://www.fourspaces.com/images/logo-bw.png</url>
      <link>http://www.fourspaces.com/blog</link>
      <description>Coding and science from the trenches.</description>
    </image>
    <item>
      <title>Feather Web Framework</title>
      <link>http://www.fourspaces.com/blog/2008/4/28/Feather_Web_Framework</link>
      <description>I noticed that there was a new link on DZone today advertising a blogging engine for Ruby named &amp;quot;Feather&amp;quot;.  Well, I thought I&amp;#39;d take this opportunity to re-introduce my Java web framework named Feather. :)  (Isn&amp;#39;t name collision fun?)&#xD;
&lt;p&gt;&#xD;
(My) Feather is yet-another Java web framework.  It isn&amp;#39;t trying to take over the world, just the part of the world that uses Java and writes web apps.  Oh, and the ones that want the web framework to do as little as possible.  As such, Feather really only deals with the Controller aspects of an MVC web app (there are some utilities to help with the model and view, but they aren&amp;#39;t required).  I started it because I got frustrated with Struts and the 6 files I needed to edit to add a new action.  It is used internally for a few applications, but is available under the Apache license.&#xD;
&lt;p&gt;&#xD;
The basic idea is that you don&amp;#39;t need to extend an abstract class or implement an interface to create controllers for web apps.  You write a plain java object that has normal methods.  The methods are then wired up to incoming requests through regular expression @Path annotations.  The methods can have any number of parameters that are auto-injected by Feather based upon request parameters, session attributes, etc...  This is also configured using annotations.  The only requirement for a Feather action is that the method must return a Feather Result object.  This can send the user text, html, forward them to another URL, dispatch to a JSP page, etc...&#xD;
&lt;p&gt;&#xD;
The documentation is quite light (non-existant), but I&amp;#39;m more than willing to help anyone understand what is going on.  Out of the box, it will work with Spring or Guice to build your controller objects, so you can inject anything that you want into your objects.  You can create a fresh object for each request, or use a singleton for all requests.  The easiest way to get started is to extend the FeatherFilter class, and add that to your web.xml file.&#xD;
&lt;p&gt;&#xD;
More information is available at &lt;a href="http://feather.fourspaces.com"&gt;http://feather.fourspaces.com&lt;/a&gt;</description>
      <pubDate>Mon, 28 Apr 2008 20:35:21 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2008/4/28/Feather_Web_Framework</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2008-04-28T20:35:21Z</dc:date>
    </item>
    <item>
      <title>Why FeatherDB exists and why is it written in Java</title>
      <link>http://www.fourspaces.com/blog/2008/4/16/Why_FeatherDB_exists_and_why_is_it_written_in_Java</link>
      <description>&lt;p&gt;&#xD;
Sorry about the formatting errors on some comments...  they&amp;#39;ve been fixed (I think).&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
I think that I best addressed my lack of willingness to use Erlang here: &lt;a href="http://reddit.com/info/6fvf1/comments/c03q623"&gt;http://reddit.com/info/6fvf1/comments/c03q623&lt;/a&gt;. Suffice it to say that my decision to rewrite the application was a little more complicated than my unwillingness to use Erlang.&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
So here I want to address a little better the differences between FeatherDB and CouchDB, and more importantly, where I think we go from here.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;hr size="2" width="100%" /&gt;&#xD;
&lt;p&gt;&#xD;
&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&lt;b&gt;Data model&lt;/b&gt;&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
However, the biggest reason for the rewrite was that I didn&amp;#39;t think that CouhcDB the data model quite right.  I think that the ability to allow common attributes in documents is an important one.  At least, it is for the application that I was planning on using it for.&amp;nbsp; The use-case that I&amp;#39;m specifically thinking of is the ability to tag pages in a CMS.&amp;nbsp; If you want to add a tag to a page, using CouchDB, you simply create a new revision of the document, and add the tag.&amp;nbsp; Simple.&amp;nbsp; But inefficient.&amp;nbsp; You&amp;#39;re effectively duplicating the contents of a document in the database to add common (meta) data to a document.&amp;nbsp; The concept of a tag logically can apply to all revisions of a document, so there shouldn&amp;#39;t be the need to create a duplicate.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
(Note: This inefficiency only applies to the storing/retrieving of documents, running/creating views is a different issue, and I&amp;#39;m not quite sure how CouchDB would handle it) .&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&lt;b&gt;Java&lt;/b&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Why is FeatherDB written in Java?&amp;nbsp; Another way of saying this is why didn&amp;#39;t I just work on the Erlang version?&amp;nbsp; One reason was that I was primarily using a Windows machine for&#xD;
development at the time, and the development process for CouchDB (even&#xD;
to just get it running) was quite tortuous.&amp;nbsp; I had to switch over to a Linux box just to write the Java library to connect to it.&amp;nbsp; Why? Because I couldn&amp;#39;t get the most up-to-date version running on Windows.&amp;nbsp; This isn&amp;#39;t necessarily a big deal for me, since I use a Windows, Mac and Linux machine on a daily basis.&amp;nbsp; However, for some this is a deal-breaker.&amp;nbsp;&amp;nbsp; So, I wrote it in the language that I was working with at the time... it just happened to be Java.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Would there be the same issue had I written this in Python or Ruby?&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Now, there is one big (and I mean &lt;b&gt;big&lt;/b&gt;) advantage that Java brings to the table, and that is the ability to run multiple languages (including Javascript) in the JVM.&amp;nbsp; This adds one feature that CouchDB cannot add without increasing overhead: the ability for a Javascript view to directly query the database.&amp;nbsp; This feature allows for the ability to have &amp;#39;joins&amp;#39; in your views.&amp;nbsp; Meaning that the Javascript view function that you run can pull other documents from the database.&amp;nbsp; This makes your view code much more flexible. &#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
It is perfectly reasonable to argue that you may not want this feature, but I&amp;#39;m not sure how you&amp;#39;d do it with the current view system in CouchDB.&amp;nbsp; Maybe it is possible, and I just don&amp;#39;t know it. &#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&lt;b&gt;Scalability&lt;/b&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
One of the biggest criticisms was the lack of distributed scalabilty of FeatherDB.&amp;nbsp; My flippant reply was: &#xD;
&lt;/p&gt;&#xD;
&lt;blockquote&gt;&#xD;
	&lt;p&gt;&#xD;
	&lt;i&gt;Re: Distributed - Via the plugin backend storage mechanism, it actually&#xD;
	wouldn&amp;#39;t be that hard to make the system distributed. There would need&#xD;
	to be a new backend written that delegates requests to other servers.&#xD;
	The trick is to figure out the logic to correctly &amp;#39;guess&amp;#39; which server&#xD;
	has the data you&amp;#39;re interested in. However, this is entirely possible. &lt;/i&gt;&#xD;
	&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;p&gt;&#xD;
Now, this is admittedly a little simplistic. Writing a new backend to farm a single request to a number of other&#xD;
servers and then &amp;#39;reduce&amp;#39; them back to return to the user isn&amp;#39;t&#xD;
difficult. The pseudo-code is very similar to the in-memory-cache&#xD;
implementation that is currently in SVN. For a brute force, dumb&#xD;
system, it would work. What is difficult is figuring out what other&#xD;
servers to farm the request to. This is the secret sauce of any&#xD;
distributed system, and isn&amp;#39;t trivial regardless of language.&amp;nbsp; As was said by one of the commentors, there is no such thing as a&#xD;
simple distributed system. Perhaps this is were Erlang&amp;#39;s sweet spot&#xD;
is... I don&amp;#39;t know.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Unfortunately, from what I&amp;#39;ve seen, the simple distributed scalability that is advertised with CouchDB isn&amp;#39;t quite a reality.  But this is to be expected... CouchDB is very much a work in progress.  People act as though it is a finished product, but this is far from the case.&amp;nbsp;  &#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&lt;b&gt;Motivations&lt;/b&gt;&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
I think the bigger question is what are my motivations for writing this, and what are my motivations for releasing it to the public.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
I love the things I read in &lt;a href="http://damienkatz.net/"&gt;Damien Katz&lt;/a&gt;&amp;#39;s blog and his descriptions of CouchDB and non-RDBMS style of data management.&amp;nbsp; I first heard of CouchDB from &lt;a href="http://blog.labnotes.org/2007/09/02/couchdb-thinking-beyond-the-rdbms/"&gt;&lt;span class="fn url"&gt;Assaf Arkin&lt;/span&gt;&lt;/a&gt;&amp;#39;s blog, and I have continued to follow it ever since.&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Now, I don&amp;#39;t want to compete with CouchDB, and I&amp;#39;m not looking to make any money from this.&amp;nbsp; I&amp;#39;ve released this because this is something that I worked on a few months ago, and felt bad seeing it sit in my private SVN repo gathering dust.&amp;nbsp; That and, these are some concepts that I&amp;#39;ve been looking at for a while.&amp;nbsp; I guess that my ideal outcome would be for some of these concepts to make their way into CouchDB so that I don&amp;#39;t have to think about it.&amp;nbsp; But, I&amp;#39;m more of a &amp;#39;working-code wins&amp;#39; kind of guy.&amp;nbsp; So I prototyped somethings up, and thought that maybe someone else could find it useful.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&lt;br /&gt;&#xD;
&lt;b&gt; Future&lt;/b&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
I&amp;#39;m not too sure where FeatherDB will go.&amp;nbsp; As I said, I&amp;#39;d be happy to use CouchDB (or maybe I&amp;#39;ll have to look at &lt;a href="http://strokedb.com/"&gt;StrokeDB&lt;/a&gt; or &lt;a href="http://code.google.com/p/grassyknoll/"&gt;GrassyKnoll&lt;/a&gt;), but for now, it doesn&amp;#39;t fit my needs.&amp;nbsp; Until it does, I&amp;#39;ll keep updating FeatherDB... and I&amp;#39;ll be following CouchDB closely.&#xD;
&lt;/p&gt;</description>
      <pubDate>Wed, 16 Apr 2008 19:50:21 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2008/4/16/Why_FeatherDB_exists_and_why_is_it_written_in_Java</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2008-04-16T19:50:21Z</dc:date>
    </item>
    <item>
      <title>FeatherDB - Java JSON Document database</title>
      <link>http://www.fourspaces.com/blog/2008/4/11/FeatherDB_Java_JSON_Document_database</link>
      <description>&lt;p&gt;&#xD;
I&amp;#39;ve been holding onto this code for a while now (months)...&amp;nbsp; I haven&amp;#39;t finished polishing is, and chances are I won&amp;#39;t.&amp;nbsp; But there are a few important concepts in here that I think are important to get out into the open.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
FeatherDB was my attempt at a Java clone of &lt;a href="http://incubator.apache.org/couchdb/"&gt;CouchDB&lt;/a&gt;.&amp;nbsp; When I first found out about CouchDB, I was very intrigued.&amp;nbsp; A non-relational database fits one of my projects perfectly... when you find yourself fighting with Hibernate just to get a schema mapped, there is an issue on one side or the other.&amp;nbsp; In this case it was me. [I should note that I actually like relational databases for most things, it just so happens that my particular application doesn&amp;#39;t map well to a static schema]&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
So, I did what any self-respecting geek would do - I downloaded the code and tried to get it running.&amp;nbsp; And that led to the first problem: I was on a Windows machine and the (at the time) binary download for Windows washorribly out of date.&amp;nbsp; Not to fear though, I had a linux box handy, so I just moved over to that machine.&amp;nbsp; I downloaded CouchDB, and got it running.&amp;nbsp; Then I had the problem that the java library wasn&amp;#39;t compatible with the newer JSON syntax (the old version was all XML, all the time).&lt;br /&gt;&#xD;
&amp;nbsp; No problem there either... I spend a day or two getting my feet wet with the REST API, and wrote a new library &lt;a href="http://couchdb4j.googlecode.com"&gt;couchdb4j&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Now, I was off and running working with CouchDB, and non-relational nirvana.&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Or at least I should have been.&amp;nbsp; At the time, CouchDB was (and is) very much a work in progress... there were a bunch of things that were planned but were missing, such as: support for stored/named views and any sort of authentication.&amp;nbsp; No problem!&amp;nbsp; I&amp;#39;ll just add this myself!&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Problem: CouchDB is written in Erlang.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
I don&amp;#39;t do Erlang.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
I don&amp;#39;t have anything against Erlang... we&amp;#39;ve never met.&amp;nbsp; I just don&amp;#39;t want to learn another language.&amp;nbsp; Especially one that is so specialized.&amp;nbsp; I know that I should learn a language a year, but Erlang was just too much of a hurdle for me to get in and start mucking around in code.&amp;nbsp; Plus, would you really accept a patch from a guy that is just learning a language?&amp;nbsp; Neither would I.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
No problem!&amp;nbsp; I&amp;#39;ll write my own Java version of CouchDB... and do it better.&amp;nbsp; The result was/is FeatherDB.&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
FeatherDB is a Java based document database.&amp;nbsp; It has an all HTTP/REST interface.&amp;nbsp; It supports querying by a Java class (added as a jar to the server), or via JavaScript (uses Java6&amp;#39;s JavaScript support).&amp;nbsp; In theory you could also search by any language that is on the JVM and implements the correct interface. &#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
FeatherDB allows for flexibility in the backend storage, allowing you to use any backend you&amp;#39;d like.&amp;nbsp; I wrote three: a filesystem based backend, an all-in-memory backend, and a caching backend that uses an in-memory hash and punts to a supporting backend when needed.&amp;nbsp; (I&amp;#39;d like to add a BerkeleyDB or Derby backend to make things a bit more resilient).&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
FeatherDB uses an embedded Jetty HTTP server to handle all interaction.&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
There were a few things about the way CouchDB handles documents that I didn&amp;#39;t like, so FeatherDB does things a little bit differently.&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;blockquote&gt;&#xD;
	&lt;p&gt;&#xD;
	Like CouchDB:&#xD;
	&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;blockquote&gt;&#xD;
	&lt;ol&gt;&#xD;
		&lt;li&gt;Documents are accessed through the HTTP interface by a REST API.&lt;br /&gt;&#xD;
		&lt;/li&gt;&#xD;
		&lt;li&gt; Documents are versioned.&amp;nbsp; Always.&amp;nbsp; You can access any version of any document.&lt;/li&gt;&#xD;
		&lt;li&gt;Document information is stored and retrieved in JSON format.&lt;/li&gt;&#xD;
		&lt;li&gt;The Document space is &amp;quot;flat&amp;quot;.&amp;nbsp; Documents can link to other documents, but there is no concept of &amp;quot;joining&amp;quot; documents.&lt;/li&gt;&#xD;
		&lt;li&gt;You query the database through &amp;#39;views&amp;#39;.&amp;nbsp; Views are also documents. &lt;/li&gt;&#xD;
	&lt;/ol&gt;&#xD;
	Unlike CouchDB (last I checked):&lt;br /&gt;&#xD;
	&lt;ol&gt;&#xD;
		&lt;li&gt;Access is controlled through an authentication layer.&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;Users are authenticated &lt;br /&gt;&#xD;
			&lt;ul&gt;&#xD;
				&lt;li&gt;though HTTP-Auth &lt;br /&gt;&#xD;
				&lt;/li&gt;&#xD;
				&lt;li&gt;or by loading /_auth?username=foo&amp;amp;password=bar&lt;/li&gt;&#xD;
				&lt;li&gt;or via a previously generated &amp;#39;token&amp;#39; (an authenticated user can generate a token, and pass it to an unauthenticated user for temporary access).&lt;/li&gt;&#xD;
			&lt;/ul&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;Users can be restricted to read-only, write-only, or read-write access to a database (document-level ACLs proved to be too slow). &lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
		&lt;/li&gt;&#xD;
		&lt;li&gt;Documents can have &amp;quot;common&amp;quot; data that is shared among all revisions.&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;Any attribute whose name starts with &amp;quot;_&amp;quot; is determined to be &amp;quot;common&amp;quot;.&lt;/li&gt;&#xD;
			&lt;li&gt;When you update that attribute, it is updated for all revisions.&lt;/li&gt;&#xD;
			&lt;li&gt;This makes it trivial to support a feature like tagging, where you want to update all revisions of a document, including future versions.&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
		&lt;/li&gt;&#xD;
		&lt;li&gt;Documents don&amp;#39;t need to be JSON documents.&amp;nbsp; A &amp;quot;document&amp;quot; in FeatherDB lingo is any file of any HTTP Content-type. This has a few nice side-effects.&amp;nbsp; The FeatherDB server can now serve any type of file to any client.&amp;nbsp; For example, you can upload a binary image to the server, load it in your browser, and it renders correctly!&amp;nbsp; &lt;br /&gt;&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;No need to base64 encode a binary payload.&amp;nbsp; &lt;br /&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;Content-types are determined from the HTTP Content-type header.&amp;nbsp; &lt;br /&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;Everything is stored in binary format, unless the incoming HTTP Content-type has an associated handler.&amp;nbsp; &lt;br /&gt;&#xD;
			&lt;ul&gt;&#xD;
				&lt;li&gt;So far, there are handlers for:&#xD;
				&lt;ul&gt;&#xD;
					&lt;li&gt;text/html&lt;/li&gt;&#xD;
					&lt;li&gt;text/plain&lt;/li&gt;&#xD;
					&lt;li&gt;application/javascript (JSON)&lt;br /&gt;&#xD;
					&lt;/li&gt;&#xD;
					&lt;li&gt;and image/{png,gif,jpeg}&lt;/li&gt;&#xD;
				&lt;/ul&gt;&#xD;
				&lt;/li&gt;&#xD;
			&lt;/ul&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;Only JSON documents can be properly queried&lt;/li&gt;&#xD;
			&lt;li&gt;A document&amp;#39;s id can contain the &amp;#39;/&amp;#39; character.&amp;nbsp; This means that you can &amp;#39;fake&amp;#39; an HTTP server&amp;#39;s paths by being creative with your document ids (Similar in this respect to Amazon&amp;#39;s S3).&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
		&lt;/li&gt;&#xD;
		&lt;li&gt;Because the content of a document is no longer JSON, there is the need for a &amp;quot;Meta-data&amp;quot; JSON file to accompany the main file.&amp;nbsp; This meta-file is what stores the document&amp;#39;s id, revision, etc...&amp;nbsp; For JSON only documents, the JSON data is stored directly in the meta-data entry.&amp;nbsp; For other documents, this is a separate file.&amp;nbsp; Information in this meta-file can be dynamically added by the content-type handler.&amp;nbsp; So, for example, the image handler can add width/height information to the record, and binary files can have their MD5/SHA1 sums calculated automatically on insert. &#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;If you&amp;#39;re keeping score, this means that using the default file-system backend, there are 2 files per revision for non-JSON documents, plus one more to store the common data.&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
		&lt;/li&gt;&#xD;
		&lt;li&gt;The JavaScript views can query the database for associated documents.&amp;nbsp; Okay, so this actually is like &amp;quot;joining&amp;quot; documents.&amp;nbsp; Because the JavaScript engine is hosted in the same JVM, you can query the Java backend from the JavaScript view.&amp;nbsp; This lets you create joined views of your data, if needed&lt;/li&gt;&#xD;
	&lt;/ol&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;blockquote&gt;&#xD;
	Those are the major differences, and things that I think should be in CouchDB.&amp;nbsp; As far as the status of FeatherDB, it has sat in SVN untouched for a few months, so I wanted to try and make it public, in case anyone else was interested.&amp;nbsp; AFAIK, it works.&amp;nbsp; However, there aren&amp;#39;t any included libraries for accessing the server, so the API is a little undocumented.&amp;nbsp; It does follow the CouchDB API as closely as possible though.&#xD;
&lt;/blockquote&gt;&#xD;
&lt;blockquote&gt;&#xD;
	You can access the project via SVN at: &lt;a href="http://svn.fourspaces.com/public/featherdb/trunk"&gt;http://svn.fourspaces.com/public/featherdb/trunk&lt;/a&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;blockquote&gt;&#xD;
	If you are interested in more information about it, leave a comment, or send me an email at: mbreese at fourspaces dot com.&amp;nbsp; Currently, the project requires Java 6 for the Scripting API support.&#xD;
&lt;/blockquote&gt;&#xD;
&lt;blockquote&gt;&#xD;
	&amp;nbsp;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;blockquote&gt;&#xD;
	&lt;b&gt;Getting started&lt;/b&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;blockquote&gt;&#xD;
	&lt;ol&gt;&#xD;
		&lt;li&gt;Download the code via SVN from the above url&lt;/li&gt;&#xD;
		&lt;li&gt; Run &amp;quot;ant run&amp;quot;.&lt;/li&gt;&#xD;
	&lt;/ol&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		This starts the server with the default configuration:&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;Port: 8889&lt;/li&gt;&#xD;
			&lt;li&gt;Admin username: sa&lt;/li&gt;&#xD;
			&lt;li&gt;Admin passowrd:password&lt;/li&gt;&#xD;
			&lt;li&gt;Backend: File system (directory &amp;quot;testdb&amp;quot;)&lt;/li&gt;&#xD;
			&lt;li&gt;Allow anonymous access&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
	&lt;/blockquote&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		To access the server, connect to http://localhost:8889.&#xD;
	&lt;/blockquote&gt;&#xD;
	&lt;b&gt;&lt;i&gt;Important URIs&lt;/i&gt;&amp;nbsp;&lt;/b&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;GET /_all_dbs -&amp;gt; list all databases&lt;/li&gt;&#xD;
			&lt;li&gt;GET /_auth -&amp;gt; authenticate&#xD;
			&lt;ul&gt;&#xD;
				&lt;li&gt;You can authenticate via HTTP-Auth, or by passing the request parameters &amp;quot;username&amp;quot; and &amp;quot;password&amp;quot; (?username=sa&amp;amp;password=pass)&lt;/li&gt;&#xD;
				&lt;li&gt;If anonymous access is enabled, all requests are treated as if authenticated as an administrator&lt;/li&gt;&#xD;
			&lt;/ul&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;GET /_invalidate -&amp;gt; invalidate the current credentials&lt;/li&gt;&#xD;
			&lt;li&gt;GET /_sessions -&amp;gt; show active authenticated sessions (not in anonymous mode)&lt;br /&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;GET /_shutdown -&amp;gt; shutsdown the server (must be admin)&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
		&lt;b&gt;Databases&lt;/b&gt;&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;GET /{dbnme} -&amp;gt; db stats&lt;/li&gt;&#xD;
			&lt;li&gt;PUT /{dbname} -&amp;gt; add a database (must be authenticated as admin) &lt;br /&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;DELETE /{dbname} -&amp;gt; remove a database (must be authenticated as admin)&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
		&lt;b&gt;Documents&lt;/b&gt;&lt;br /&gt;&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;GET /{dbname}/{documentid} -&amp;gt; Get the document&amp;#39;s current revision &#xD;
			&lt;ul&gt;&#xD;
				&lt;li&gt;If this isn&amp;#39;t found, but /db/docid/index is found, this will be returned instead&lt;/li&gt;&#xD;
				&lt;li&gt;Optional parameters:&#xD;
				&lt;ul&gt;&#xD;
					&lt;li&gt;showMeta=true -&amp;gt; returns the meta-information for the document (see above)&lt;br /&gt;&#xD;
					&lt;/li&gt;&#xD;
					&lt;li&gt;showRevisions=true -&amp;gt; includes a list of available revisions in the meta-information  &lt;/li&gt;&#xD;
				&lt;/ul&gt;&#xD;
				&lt;/li&gt;&#xD;
			&lt;/ul&gt;&#xD;
			&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;GET /{dbname}/{documentid}/{revision} -&amp;gt; Get the document&amp;#39;s content (see above)&lt;br /&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;POST or PUT /{dbname}/{documentid} -&amp;gt; write the request&amp;#39;s body as a new revision of the given document&#xD;
			&lt;ul&gt;&#xD;
				&lt;li&gt;If the documentid doesn&amp;#39;t exist, it is created  &lt;/li&gt;&#xD;
			&lt;/ul&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;POST /{dbname} -&amp;gt; write a new document, but use a generated id&lt;br /&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;DELETE /{dbname}/{documentid} -&amp;gt; delete the document (must be able to write to db)&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
	&lt;/blockquote&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		&lt;b&gt;Views&lt;/b&gt;&#xD;
	&lt;/blockquote&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;POST /{dbname}/_temp_view -&amp;gt; perform an adhoc query&amp;nbsp; &lt;br /&gt;&#xD;
			&lt;ul&gt;&#xD;
				&lt;li&gt;The contents of the POST should be in the format of a javascript function&lt;/li&gt;&#xD;
				&lt;li&gt;Ex: &lt;br /&gt;&#xD;
				&lt;/li&gt;&#xD;
			&lt;/ul&gt;&#xD;
			&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
		&lt;blockquote&gt;&#xD;
			&lt;blockquote&gt;&#xD;
				function(doc) { if (doc.value==&amp;#39;foo&amp;#39;) {map(doc.id,doc.value); }}&#xD;
			&lt;/blockquote&gt;&#xD;
		&lt;/blockquote&gt;&#xD;
		&lt;ul&gt;&#xD;
			&lt;li&gt;POST or PUT /{dbname}/viewname/functionname -&amp;gt; add/update a new view. &lt;br /&gt;&#xD;
			&lt;ul&gt;&#xD;
				&lt;li&gt;Note: the view name must start with an underscore (&amp;#39;_&amp;#39;).&lt;/li&gt;&#xD;
				&lt;li&gt;The default functionname is &amp;quot;default&amp;quot;&lt;/li&gt;&#xD;
			&lt;/ul&gt;&#xD;
			&lt;/li&gt;&#xD;
			&lt;li&gt;GET /{dbname}/_all_docs -&amp;gt; returns a list of all document ids&#xD;
			&lt;ul&gt;&#xD;
				&lt;li&gt;This actually calls an included view named &amp;quot;_all_docs&amp;quot; &lt;/li&gt;&#xD;
			&lt;/ul&gt;&#xD;
			&lt;/li&gt;&#xD;
		&lt;/ul&gt;&#xD;
		&lt;blockquote&gt;&#xD;
			Views can be either written in either Java or JavaScript.&amp;nbsp; View documents are JSON documents that have the following attributes:&#xD;
		&lt;/blockquote&gt;&#xD;
		&lt;blockquote&gt;&#xD;
			&lt;blockquote&gt;&#xD;
				&amp;#39;view_type&amp;#39;: &amp;#39;application/javascript&amp;#39; or &amp;#39;java:fully.qualified.class.Name&amp;#39;&#xD;
			&lt;/blockquote&gt;&#xD;
			 Java views must implement the interface: com.fourspaces.featherdb.views.View&lt;br /&gt;&#xD;
			JavaScript views are implemented as JSON documents in the format:&#xD;
			&lt;blockquote&gt;&#xD;
&lt;pre&gt;&#xD;
&amp;nbsp;{ &#xD;
&amp;#39;view_type&amp;#39;: &amp;#39;application/javascript&amp;#39;,&#xD;
&#xD;
&amp;#39;view1&amp;#39;: function(doc) {&#xD;
	// your code here&#xD;
	if (doc.val=&amp;#39;foo&amp;#39;) {&#xD;
		return doc;&amp;nbsp;&#xD;
	} ,&#xD;
&amp;#39;view2&amp;#39;: function(doc) {&#xD;
	// your code here&#xD;
	if (doc.val=&amp;#39;foo&amp;#39;) {&#xD;
		map(&amp;#39;key&amp;#39;,doc.val);&amp;nbsp;&#xD;
	}&amp;nbsp;&#xD;
}&amp;nbsp;&#xD;
&lt;/pre&gt;&#xD;
			&lt;/blockquote&gt;&#xD;
			&lt;blockquote&gt;&#xD;
				So, as you see, JavaScript views are functions that take a JavaScript object as input, and either returns a JSON object, or builds a map with a key and value. (See CouchDB docs for more information).&#xD;
			&lt;/blockquote&gt;&#xD;
			&lt;blockquote&gt;&#xD;
				There is another associated JavaScript method that you can call, and that is: function get(id,rev,db).&amp;nbsp; From JavaScript, you can retrieve other documents by id, revisions (optional), and database (optional). &#xD;
			&lt;/blockquote&gt;&#xD;
		&lt;/blockquote&gt;&#xD;
		&lt;blockquote&gt;&#xD;
			Views are maintained by a &amp;quot;ViewRunner&amp;quot;.&amp;nbsp; The ViewRunner is responsible for maintaining the index of results for documents in the database.&amp;nbsp; The only included ViewRunner doesn&amp;#39;t store an index, but instead iterates over all of the documents in the database on each request.&amp;nbsp;&#xD;
			&amp;nbsp; &lt;br /&gt;&#xD;
		&lt;/blockquote&gt;&#xD;
	&lt;/blockquote&gt;&#xD;
	&lt;b&gt;Configuration&lt;/b&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		FeatherDB is configured by writing a &amp;quot;featherdb.properties&amp;quot; file. In the src/java/com/fourspaces/featherdb directory, there is a &amp;#39;default.properties&amp;#39; file that shows the default properties and their values.&amp;nbsp; Your featherdb.properties file will overwrite the default values.&#xD;
		&lt;blockquote&gt;&#xD;
			&amp;nbsp;&#xD;
		&lt;/blockquote&gt;&#xD;
	&lt;/blockquote&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;blockquote&gt;&#xD;
	&lt;b&gt;&lt;i&gt;Additional &lt;/i&gt;&lt;i&gt;Notes&lt;/i&gt;&lt;/b&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		If you are using an access mechanism that doesn&amp;#39;t support cookies, you&amp;#39;ll need to pass a &amp;quot;token&amp;quot; with each authenticated access.&amp;nbsp; This can be passed as a request parameter (?token=asdfasdf), or via an HTTP Header &amp;quot;FeatherDB-Token&amp;quot;.&amp;nbsp; The token is given to you when you access &amp;quot;/_auth&amp;quot;.&amp;nbsp; This isn&amp;#39;t needed in anonymous access mode.&#xD;
	&lt;/blockquote&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		There is a severe lack of unit tests.&amp;nbsp; I&amp;#39;m sorry :).&amp;nbsp; Specifically, there is a lack of tests for running views, but it _should_ work.&#xD;
	&lt;/blockquote&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		I make no promises about this code.&amp;nbsp; If it works for you, great.&amp;nbsp; If not, let me know, and I&amp;#39;ll see what I can do about it.&amp;nbsp; As always, patches are gratefully accepted.&amp;nbsp;&#xD;
	&lt;/blockquote&gt;&#xD;
	&lt;blockquote&gt;&#xD;
		&amp;nbsp;&#xD;
	&lt;/blockquote&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;p&gt;&#xD;
&amp;nbsp;&lt;b&gt;Future directions&lt;/b&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;blockquote&gt;&#xD;
	&lt;p&gt;&#xD;
	I&amp;#39;m not sure what to do with this project.&amp;nbsp; I&amp;#39;d prefer to not maintain a separate code base that may or may not track the CouchDB API.&amp;nbsp; I&amp;#39;d personally like to see the changes in the document structures implemented in CouchDB, but I&amp;#39;m not sure if it is possible given the split in a document data and meta data.&amp;nbsp; Then again, I&amp;#39;m completely unfamiliar with the CouchDB code base, so perhaps this will be possible.&#xD;
	&lt;/p&gt;&#xD;
	&lt;p&gt;&#xD;
	I wanted to make this all public to see if anyone else may be interested in using this type of database and may be interested in helping to flesh it all out.&#xD;
	&lt;/p&gt;&#xD;
	&lt;p&gt;&#xD;
	Hope you enjoy it!&amp;nbsp;&#xD;
	&lt;/p&gt;&#xD;
&lt;/blockquote&gt;</description>
      <pubDate>Fri, 11 Apr 2008 18:55:39 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2008/4/11/FeatherDB_Java_JSON_Document_database</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2008-04-11T18:55:39Z</dc:date>
    </item>
    <item>
      <title>Java Building Java</title>
      <link>http://www.fourspaces.com/blog/2008/2/16/Java_Building_Java</link>
      <description>&lt;p&gt;&#xD;
My &lt;a href="http://fourspaces.com/blog/2008/2/1/The_problem_with_Java_building_Java_hint_it_s_Java" mce_href="../../blog/2008/2/1/The_problem_with_Java_building_Java_hint_it_s_Java"&gt;last post&lt;/a&gt; was all about the problems inherent with using Java as a builder for Java programs.&amp;nbsp; My conclusion was that it isn't a good idea... mainly because you have to solve a bootstrapping problem - you need to compile your builder before it can work.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Well, I thought about it a bit more, and figured, eh, what the hell?&amp;nbsp; After all, working code wins.&amp;nbsp; So, I sat around and attempted to make my own Java based Java builder.&amp;nbsp; This ultimately turns out to be a two-step process:&#xD;
&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
	&lt;li&gt;Compile/package your builder&lt;/li&gt;&#xD;
	&lt;li&gt;Call your builder with it's own classloader&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;&#xD;
So, how does it work?&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
You put your builder code in it's own source tree.&amp;nbsp; I decided the "builder" folder would be a good choice.&amp;nbsp; So, you put your builder's java source code in "builder/src", dependencies in "builder/lib", and your compiled code will end up in "builder/classes".&amp;nbsp; My "Builder" class will compile everything in builder/src, and call whatever methods in one of your classes.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
What?&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Maybe it would help if I included an example... Here is how you build the builder:&#xD;
&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;pre&gt;&lt;code&gt;&#xD;
java -cp builder.jar com.fourspaces.builder.Builder com.fourspaces.builder.BuilderBuilder&lt;/code&gt;&lt;/pre&gt;&#xD;
(or more simply)&#xD;
&lt;pre&gt;&lt;code&gt;&#xD;
java -jar builder.jar com.fourspaces.builder.BuilderBuilder&lt;/code&gt;&lt;/pre&gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&#xD;
What this does is pretty simple: it uses the &lt;pre&gt;&lt;code&gt;com.fourspaces.builder.Builder&lt;/code&gt;&lt;/pre&gt; class to compile all the source code in "builder/src" and then calls the &lt;pre&gt;&lt;code&gt;@Default&lt;/code&gt;&lt;/pre&gt; task in &lt;pre&gt;&lt;code&gt;com.fourspaces.builder.BuilderBuilder&lt;/code&gt;&lt;/pre&gt;.  In this case, the default task compiles the Builder project itself and creates the builder.jar file.  You can call any method (that has no parameters) in the class that you call.  So, for example, this will clean-up any artifacts from a previous build (clean method) and create the builder.jar (jar method):&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;pre&gt;&lt;code&gt;java -jar builder.jar com.fourspaces.builder.BuilderBuilder clean jar&lt;/code&gt;&lt;/pre&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&#xD;
Not only can you call any method, you can also configure &lt;pre&gt;&lt;code&gt;@Depends&lt;/code&gt;&lt;/pre&gt; task-dependencies.&amp;nbsp; So, in the above case, the "jar" task depends on "compile", which depends on "init".&amp;nbsp; So, the methods that are called are (in order) clean, init, compile, jar.&lt;/p&gt;&lt;p&gt;The final little feature is that you can optionally create a single custom-builder jar file. If you do this, your command-line can be as simple as:&lt;/p&gt;&lt;pre&gt;&lt;pre&gt;&lt;code&gt;java -jar custom-builder.jar clean jar&lt;/code&gt;&lt;/pre&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;hr size="1" width="100%"&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Okay, so you can successfully create a bootstrapping builder in Java.&amp;nbsp; Woohoo :)&amp;nbsp; The real question is: &lt;b&gt;is it worth it&lt;/b&gt;? &lt;/p&gt;&lt;p&gt;After much deliberation, I can say this: &lt;b&gt;maybe&lt;/b&gt;.&amp;nbsp; It doesn't suck as much as I thought it would, and you can really do some amazing things that you can't do in Ant.&amp;nbsp; You can create whatever type of building infrastructure that you want without having to adapt your process to your build tool.&amp;nbsp; The downside is that you have to do your own coding, so there isn't much already done for you.&lt;/p&gt;&lt;p&gt;As an example of what you can do, here is the BuilderBuilder class.&amp;nbsp; I wrote three helper classes as well "JavaCompile", "JarBuilder", and "FileSupport".&amp;nbsp; These helper tasks make compiling and jar building quite nice... from this code you can see how to define task dependencies, how to configure the default task, how to compile, how to jar up files, and how to do some basic file operations.&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;pre&gt;&lt;code&gt;public class BuilderBuilder {&#xD;
&#xD;
	private String srcDir = "src/java";&#xD;
	private String buildDir = "build/classes";&#xD;
	&#xD;
	@Depends("init")&#xD;
	public void compile() throws IOException {&#xD;
		new JavaCompile()&#xD;
			.setTarget(buildDir)&#xD;
			.addSource(srcDir)&#xD;
			.compile();&#xD;
	}&#xD;
	&#xD;
	@Default&#xD;
	@Depends("compile")&#xD;
	public void jar() throws FileNotFoundException, IOException {&#xD;
		new JarBuilder()&#xD;
			.setFileName("builder.jar")&#xD;
			.addSource(buildDir)&#xD;
			.addInclude("**/*.class")&#xD;
			.addSource(".")&#xD;
			.addInclude("LICENSE")&#xD;
			.setMainClass("com.fourspaces.builder.Builder")&#xD;
			.create();&#xD;
		&#xD;
		FileSupport.copyFile("builder.jar","builder/lib/builder.jar");&#xD;
	}&#xD;
	&#xD;
	public void init() {&#xD;
		mkdirs(buildDir);&#xD;
		mkdirs(srcDir);&#xD;
	}&#xD;
&#xD;
	public void clean() {&#xD;
		deleteDir(buildDir);&#xD;
	}&#xD;
	public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, FileNotFoundException, IOException {&#xD;
		Builder.invokeBuilderTasks(new BuilderBuilder(),args);&#xD;
	}&#xD;
}&#xD;
&lt;/code&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;p&gt;So, all in all, not bad.&amp;nbsp; I'm curious to see if there is any interest in this builder.&amp;nbsp; If there is, I'm interested in polishing things up a bit and making this project a bit bigger (and give it a name).&amp;nbsp; I'm planning migrating my own projects over to this type of builder, so the built-in tasks will be pretty much centered around what I need.&amp;nbsp; Specifically, the tasks that are on the list are: SVN update/commit, Javadoc generation, creating a WAR file, starting a Jetty container (using said WAR file), and JUnit testing.&amp;nbsp; One other things that I'd like to add is integration with Maven/Ivy jar repositories.  If you're interested in checking it out, you can check it out from SVN at: &lt;a href="http://svn.fourspaces.com/public/javabuilder/trunk/" mce_href="http://svn.fourspaces.com/public/javabuilder/trunk/"&gt;http://svn.fourspaces.com/public/javabuilder/trunk/&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; it should be mentioned that this requires using Java 6, since it relies on the Java Compiler API.  When running, you should make sure that you are using the "java" executable from the JDK and not the JRE (a common problem)&#xD;
&lt;/p&gt;</description>
      <pubDate>Sat, 16 Feb 2008 07:53:21 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2008/2/16/Java_Building_Java</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2008-02-16T07:53:21Z</dc:date>
    </item>
    <item>
      <title>The problem with Java building Java (hint: it's Java)</title>
      <link>http://www.fourspaces.com/blog/2008/2/1/The_problem_with_Java_building_Java_hint_it_s_Java</link>
      <description>&lt;p&gt;&#xD;
I am very intrigued with the idea of new Java building infrastructure.  I&amp;#39;m a pretty committed Ant devotee, owing to bad experiences with some early Maven builds.  So far, there hasn&amp;#39;t really been anything that I want to do that I can&amp;#39;t get Ant to do.  Every so often I needed to write a custom ant task, but that&amp;#39;s pretty rare.  However the main reason that I don&amp;#39;t like Maven is that I&amp;#39;m a control freak.  I like things in the directories that I want them.  I don&amp;#39;t like my project&amp;#39;s build to the build tool.  That just seems so counter-intuitive to me.  But this post isn't about Maven...&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Now, my needs are pretty simple: 1) setup directories, 2) compile classes, 3) run unit tests, 4) assemble jars/wars, 5) sometimes start/restart Tomcat.  I don&amp;#39;t deal with much inheritance simply because I don&amp;#39;t need it.  The few times I&amp;#39;ve tried, it ended up a giant sticky mess (that ultimately didn&amp;#39;t work).  My basic build directory setup is also pretty standard, so I can (for the most part) reuse a build.xml file from one project to another.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Even though Ant has served me well in the past, I have always had some uneasiness with the concept of using an XML &amp;quot;script&amp;quot;.  I&amp;#39;ve been slowly removing all XML configuration from my projects, opting instead for Annotations or DSL-style Java configuration (much like Guice).  So, you could say that I&amp;#39;ve been in the market for an Ant replacement.  &#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
One top contender is &lt;a href="http://incubator.apache.org/buildr/"&gt;Buildr&lt;/a&gt;.  If you don&amp;#39;t know, Buildr is a Ruby based build system for Java projects.  (Such is the life of a polyglot).  However, I&amp;#39;ve been holding off on trying Buildr until Ruby 1.9 comes out...  I honestly don&amp;#39;t have a good reason for not trying it...&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Today I ended up reading about &lt;a href="http://gosling.dev.java.net"&gt;Gosling&lt;/a&gt;.  Now this is an interesting idea that doesn&amp;#39;t seem to be going anywhere (the last release was in January 2007).  I starting to think about this a little more...  &lt;b&gt;why isn&amp;#39;t there a Java based Java builder&lt;/b&gt;?  I think this is a &lt;b&gt;chicken and the egg&lt;/b&gt; problem.  You need a builder to build the builder.  And then it&amp;#39;s even a little more complicated.  &lt;i&gt;You need a builder to build the builder so it can build your project&lt;/i&gt;.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Let&amp;#39;s take a step back.  What would the workflow look like for the developer?  Well, if you&amp;#39;re doing command-line builds (you can build all of your deliverables from a single command, right?) then you expect to be able to type a command and maybe an optional task.  Such as: &lt;pre&gt;&lt;code&gt;make all&lt;/code&gt;&lt;/pre&gt;&lt;br/&gt;  Even if you&amp;#39;re doing some nifty &lt;a href="http://blog.markturansky.com/archives/21"&gt;bootstrapping&lt;/a&gt;, you&amp;#39;re still looking at something like: &lt;pre&gt;&lt;code&gt;java -cp . Bootstrap Builder task&lt;/code&gt;&lt;/pre&gt;&#xD;
&lt;br/&gt;&#xD;
Now, if it were me I&amp;#39;d add a bash script to at least cover the java bootstrapping, so we&amp;#39;re looking at something like &lt;pre&gt;&lt;code&gt;build.sh task&lt;/code&gt;&lt;/pre&gt;&lt;br/&gt;  That&amp;#39;s a little better.  But, you still have to compile your project&amp;#39;s builder.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
So now instead of having one set of source code, you have two.  Your project, and your project&amp;#39;s builder.  And if your builder requires libraries, you have two sets of dependencies (at least... your unit test may have their own as well).  But, once your builder is compiled, you can finally compile your project. &lt;pre&gt;&lt;code&gt;java -cp builder/classes MyBuilder task&lt;/code&gt;&lt;/pre&gt;&lt;br/&gt; but that looks like crap (and takes too many keystrokes), so you&amp;#39;ll have to write another shell/batch script.  But at least we&amp;#39;re getting somewhere.&#xD;
&lt;/p&gt;&#xD;
&lt;hr/&gt;&#xD;
&lt;p&gt;&#xD;
This all seems very much like the saying &amp;quot;&lt;a href="http://regex.info/blog/2006-09-15/247"&gt;now you have two problems&lt;/a&gt;&amp;quot;.  I guess the point of this all is that while a Java based Java builder is an interesting idea, I&amp;#39;m not sure how much sense it makes.  Look at the granddaddy of them all: make.  Make exists largely to build C programs.  &lt;b&gt;Why not write a C builder in C?&lt;/b&gt;  Well, then you&amp;#39;d have to first compile your builder...&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
(note to self: just try Buildr) &#xD;
&lt;/p&gt;</description>
      <pubDate>Fri, 01 Feb 2008 07:49:28 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2008/2/1/The_problem_with_Java_building_Java_hint_it_s_Java</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2008-02-01T07:49:28Z</dc:date>
    </item>
    <item>
      <title>JavaCloth - Textile for Java (via JRuby)</title>
      <link>http://www.fourspaces.com/blog/2007/9/20/JavaCloth_Textile_for_Java_via_JRuby</link>
      <description>&lt;p&gt;&#xD;
This was quite the week for quick little projects for me.  I&amp;#39;m gearing up to make a release of my web app framework (renamed from Scratch to avoid name-collision with the MIT project).  It&amp;#39;s now called Feather (&lt;a href="http://feather.fourspaces.com" title="Feather" target="_blank"&gt;http://feather.fourspaces.com&lt;/a&gt;), and as a bonus, I&amp;#39;m including a sample application as well... the Feather site source code itself.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Well, because I like making things more difficult than needed, the Feather web site is as close to being a wiki as possible without going full-out.  Editing of the pages is done on the site.  This means that I needed to either add a full WYSIWYG HTML editor, use a plain text box but hand-code HTML, stick with just plain text, or use another markup language.  Well, I did what all the &lt;a href="http://rubyonrails.com/" title="Ruby on Rails" target="_blank"&gt;cool kids&lt;/a&gt; are doing... used the Textile markup language.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Textile is a fun little plain text code that allows you to use a simple set of markup rules to create HTML quickly.&amp;nbsp; Unfortunately, the two Java libraries that performed the conversion are no longer maintained, and don&amp;#39;t work for all the rules (tables in particular).&amp;nbsp; So I did what any self-respecting hacker would do... started my own.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Now, after about 12 hours at this, I had a pretty good compiler design setup... it read in the files, and processed chunks step by step.&amp;nbsp; But it wasn&amp;#39;t done...&amp;nbsp; I still had a few extra rules to support, and it was looking like some of my edge cases were going to be a bit difficult to tweak.&amp;nbsp; (In retrospect, I should have used a state-machine concept or a compiler-compiler to just figure out the grammar and have it write the converter, but that&amp;#39;s still a bit over my head).&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Now, I mentioned the &lt;a href="http://rubyonrails.com/" title="Ruby on Rails" target="_blank"&gt;cool kids&lt;/a&gt;... how do they do it?&amp;nbsp; Well, there is a little Ruby class called &lt;a href="http://whytheluckystiff.net/ruby/redcloth/" title="RedCloth" target="_blank"&gt;RedCloth&lt;/a&gt; that handles it.&amp;nbsp; It&amp;#39;s nice, easy to use, and more importantly works.&amp;nbsp; So I decided to scrap my code and go the Ruby way... sort of.&amp;nbsp; I quickly learned how to setup a JRuby instance, and embedded the redcloth.rb file...&amp;nbsp; a few tweaks later, and I have a full Java textile parser.&amp;nbsp; Only, it uses JRuby to actually do it.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
I was pretty happy with the results, so I put it up on SourceForge: &lt;a href="http://javacloth.sf.net" title="JavaCloth on SF.net" target="_blank"&gt;http://javacloth.sf.net&lt;/a&gt;.&amp;nbsp; It only requires Java 1.5, since I didn&amp;#39;t use the Java6 interface for JRuby...&amp;nbsp; I might have to compile a different version for Java 6.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
All in all, the JRuby code is quite easy to work with.&amp;nbsp; Once you have an instance, you can just execute ruby code as you&amp;#39;d like... which makes it easy to setup the RedCloth class, and create a new instance to convert text on demand.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
The main magic occurs in this bit of Ruby:&#xD;
&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;code&gt;String script = &#xD;
&amp;quot;require &amp;#39;java&amp;#39;\n&amp;quot; +&#xD;
&amp;quot;class RTextilize &amp;lt; Java::&amp;quot;+JavaCloth.class.getPackage().getName()+&amp;quot;.Textilize\n&amp;quot; + &#xD;
&amp;quot;	def textilize(txt)\n&amp;quot; +&#xD;
&amp;quot;		RedCloth.new(txt).to_html.to_s\n&amp;quot;+&#xD;
&amp;quot;	end\n&amp;quot; +&#xD;
&amp;quot;end\n&amp;quot;;&#xD;
runtime.evalScript(script);&#xD;
&lt;/code&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&#xD;
This creates a new Ruby class that extends the Java abstract class Textilize and implements its single abstract method &lt;pre&gt;&lt;code&gt;String textilize(String s)&lt;/code&gt;&lt;/pre&gt;.  From here, you can get a handle on the object from Java like this:&#xD;
&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;code&gt;Object rfj =  runtime.evalScript(&amp;quot;RTextilize.new()&amp;quot;);&#xD;
Textilize rTextilize = (Textilize) JavaEmbedUtils.rubyToJava(runtime, &#xD;
(org.jruby.runtime.builtin.IRubyObject) rfj, &#xD;
Textilize.class);&#xD;
&lt;/code&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&#xD;
And from here, you can call &lt;pre&gt;&lt;code&gt;rTextilize.textilize(String s)&lt;/code&gt;&lt;/pre&gt; all you want!&#xD;
Now, I ended up wrapping the entire thing up into a single JavaCloth class to handle&#xD;
all the Ruby initialization and RedCloth.rb loading, but I was quite impressed with what JRuby can handle and how easy it is to work with.  All this in a single 4MB jar file (with all the dependencies included).&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
For more information on my library, check out the SoruceForge page: &lt;a href="http://javacloth.sf.net" title="JavaCloth on SF.net" target="_blank"&gt;http://javacloth.sf.net&lt;/a&gt;&#xD;
&lt;/p&gt;</description>
      <pubDate>Thu, 20 Sep 2007 04:47:44 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2007/9/20/JavaCloth_Textile_for_Java_via_JRuby</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2007-09-20T04:47:44Z</dc:date>
    </item>
    <item>
      <title>CouchDB4J</title>
      <link>http://www.fourspaces.com/blog/2007/9/15/CouchDB4J</link>
      <description>I added a new GoogleCode project today... so my limit is now down to 8.  I don't know if you read much about CouchDB over the past few weeks, but it's a pretty interesting idea.  Basically, it's the Document-centric framework that I've talked about before, but it uses JSON as it's data transfer language as opposed to XML/SOAP.  It also operates using only REST style HTTP requests.  The server is actually designed to operate at a very large scale across a grid to deal with queries in a Map/Reduce format.&#xD;&lt;br/&gt;&#xD;&lt;br/&gt;Now, I've used about all the buzzwords that I'm allowed to use in one post, so I'll stop there.&#xD;&lt;br/&gt;&#xD;&lt;br/&gt;I wanted to play with it, but my language of choice didn't have a good api that dealt with the newer CouchDB JSON style.  36 hours later, I have a new Google project that looks like it might work.&#xD;&lt;br/&gt;&#xD;&lt;br/&gt;The API needs some cleaning up, but it's not too bad.  Now I just need a project to dogfood it.  Hmmm... a project that can dog food both a web framework and a document-base data store.  What could that be?</description>
      <pubDate>Sat, 15 Sep 2007 04:51:03 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2007/9/15/CouchDB4J</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2007-09-15T04:51:03Z</dc:date>
    </item>
    <item>
      <title>Java versus Mac: User interface debate</title>
      <link>http://www.fourspaces.com/blog/2007/2/19/Java_versus_Mac_User_interface_debate</link>
      <description>&lt;p&gt;&#xD;
I was reading this blog entry over at java.net this past weekend, and I tried to register for an account and sign in for the past two days just so that I could reply to this blog entry of Kirill&amp;#39;s.&amp;nbsp; Alas, java.net and I have issues, so I&amp;#39;ll write my reply here.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
There are a few issues with comparing NetBeans Matisse and Apple&amp;#39;s Interface Builder (IB).&amp;nbsp; The first off, is that each exists in their own ecosystems.&amp;nbsp; Apple developers usually use Xcode and IB exclusively in designing their (Cocoa) applications.&amp;nbsp; There are a few large counter examples, but for the most part, most developers use Apple&amp;#39;s tools.&amp;nbsp; Because of this, everything tends to conform to the Apple Human Interface Design specs.&amp;nbsp; It&amp;#39;s much easier to program a Mac Apple&amp;#39;s way than to try to do it yourself.&amp;nbsp; &lt;b&gt;The expectation of Mac developers and users alike is that things will be done Apple&amp;#39;s way&lt;/b&gt;, using Apple&amp;#39;s APIs.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
In Java, things are different.&amp;nbsp; In Java-land, developers have different expectations because Java GUI programs live mainly on Windows and Linux boxes (okay, mainly Windows).&amp;nbsp; However, since cross-platform ability is one of the main selling points of Java, we can treat Java programs as needing to work on Windows/Mac/Linux/Solaris (I threw in Solaris for fun).&amp;nbsp; Additionally, most Java developers (at least the vocal ones), are very used to Apache-style open source access to common libraries.&amp;nbsp; This means that &lt;b&gt;Java developers expect open formats&lt;/b&gt;.&amp;nbsp; They expect to be able to muck around with an XML file.&amp;nbsp; They expect to &lt;i&gt;not&lt;/i&gt; have binary/proprietary file formats describing things.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
.Net/C#/Microsoft world is much closer to the Mac landscape from a developer&amp;#39;s point of view.&amp;nbsp; Microsoft has some of the best tooling in the industry.&amp;nbsp; If you live and work in Visual Studio, you can expect that your programs will look and work like &amp;quot;Windows programs&amp;quot;.&amp;nbsp; Visual studio developers could care less about open formats... so long as it can be edited in Visual Studio, that&amp;#39;s sufficient for most .Net/C# devs.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
So the two main questions raised by Kirill are described by this comment by him:&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
&lt;span class="ltcaption1"&gt;&lt;/span&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
	&lt;li&gt;&#xD;
	&lt;a title="23047" name="23047"&gt;&lt;/a&gt;&#xD;
	&lt;div id="c23047"&gt;&#xD;
	&lt;p&gt;&#xD;
	elharo - i&amp;#39;ve raised two questions, and you didn&amp;#39;t answer them. The&#xD;
	first is - what tool besides Interface Builder can be used to operate&#xD;
	on NIB files. If there is none, then the &amp;quot;locking&amp;quot; part of NetBeans&#xD;
	argument is irrelevant. The second question concerned designed /&#xD;
	intended use of each one of the tools (Interface Builder / NetBeans).&#xD;
	As long as you stay in NetBeans (even if it means locking), what does&#xD;
	it matter that it&amp;#39;s split between two places? How would that get out of&#xD;
	sync?&#xD;
	&lt;/p&gt;&#xD;
	&lt;p&gt;&#xD;
	Of course, both questions are about Interface Builder against&#xD;
	NetBeans, and not about NetBeans against other Java IDEs. My belief is&#xD;
	that if you (as the developer) decide to use some IDE to visually&#xD;
	operate on your UIs, you shouldn&amp;#39;t complain about locking (&lt;a href="http://jcp.org/en/jsr/detail?id=198"&gt;JSR 198&lt;/a&gt;&#xD;
	is simply bound to fial {sic} miserably in such a dynamic and highly evolving&#xD;
	field as Java IDEs). If you want interoperability and portability,&#xD;
	don&amp;#39;t use tools for your UIs.&#xD;
	&lt;/p&gt;&#xD;
	&lt;/div&gt;&#xD;
	&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;&#xD;
To which, I answer Apple developers don&amp;#39;t care about &amp;quot;locking&amp;quot;.&amp;nbsp; They are using a Mac for crying out loud.&amp;nbsp; Macs are proprietary systems built upon an open source foundation.&amp;nbsp; You are very much locked into the Apple design aesthetic if you are using a Mac.&amp;nbsp; You can&amp;#39;t compare the two development tools from this perspective.&amp;nbsp; &lt;b&gt;IB is the tool to design interfaces&lt;/b&gt; on a Mac.&amp;nbsp; You don&amp;#39;t have other options, and you wouldn&amp;#39;t want them anyway because it didn&amp;#39;t come from Apple.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
Now, if you are &lt;b&gt;in Java-land, you come in with a different set of expectations, largely due to the ecosystem that Java has fostered&lt;/b&gt;.&amp;nbsp; Things are expected to be open.&amp;nbsp; Things are expected to be XML configurable.&amp;nbsp; Things are expected to work with multiple tools (because everything can read XML right?).&amp;nbsp; It is &lt;strike&gt;expected&lt;/strike&gt; demanded that a developer be able to view and change configurations of things by hand, if needed. &#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
However, you can certainly compare the two approaches (IB and Matisse) from a structural standpoint.&amp;nbsp; You might as well throw in Visual Studio into the mix as well (although, I&amp;#39;m less familiar with the newest version).&amp;nbsp; I like the IB and Visual Studio technique of placing things in one location (regardless of the implementation of that store).&amp;nbsp; I don&amp;#39;t know why NetBeans has things repeated at the .form and source code levels.&amp;nbsp; This just seems silly to me.&amp;nbsp; As far as the argument that having a binary format lets the Matisse developers could change things quickly, why not just include a version tag in an XML config file?&amp;nbsp; Then they could load a different handler for whatever version the file requested.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&#xD;
In my opinion, the main reason why Java is so ridiculed on the client side is that Java development tries to ignore the underlying operating system.&amp;nbsp; It tries to hack on a look-and-feel to mimic the underlying operating system.&amp;nbsp; There are definite up sides to this... however, there are very real downsides as well.&amp;nbsp; If you try to be all things to all people, you can easily end up being nothing to no one.&amp;nbsp; If, however, there was a way for Java GUIs to embrace the existing methods of the underlying operating systems to draw and design GUIs, then you may have something.&amp;nbsp; However, if the &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/LanguageIntegration/index.html" target="_blank"&gt;java-cocoa bridge&lt;/a&gt; is any indication, then the validity of this approach has passed us by. &#xD;
&lt;/p&gt;</description>
      <pubDate>Mon, 19 Feb 2007 18:54:47 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2007/2/19/Java_versus_Mac_User_interface_debate</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2007-02-19T18:54:47Z</dc:date>
    </item>
    <item>
      <title>One reason why I don't like Ruby on Rails</title>
      <link>http://www.fourspaces.com/blog/2007/1/22/One_reason_why_I_don_t_like_Ruby_on_Rails</link>
      <description>I recently started playing with RoR again, just to see why it is so hot.  I know one of the big pushes with Ruby is that it is very flexible and thus very fast to program in.  Well, I don't really doubt that one bit.  The only problem is, what if you don't know the language or the API for Rails that well.&#xD;&lt;br/&gt;&#xD;&lt;br/&gt;It comes down to, "How do you learn the Rails API?".  Or for that matter, how do you learn Ruby?&#xD;&lt;br/&gt;&#xD;&lt;br/&gt;In the Java world, you have quite possibly the best IDE suites and toolsets ever made.  (Well, I actually like Visual Studio quite a lot and it sets the bar quite high, but I don't do much C#/.NET programming).  One of the benefits of having such a robust toolset is the ability to view the API on demand.  Let's say you have a HashMap named "hashMap".  If you don't know the API for a HashMap, all you have to do is dot your way through the API in Eclipse.&#xD;&lt;br/&gt;&#xD;&lt;br/&gt;HashMap hashMap = new HashMap();&#xD;&lt;br/&gt;hashMap. opens a window will all the methods for the class.  This is brilliant, and how I learned most of the Java I know.  If you expect there to be some method to put something in the map... well, you can guess that it's name is something like "store", or "place" or "put".&#xD;&lt;br/&gt;&#xD;&lt;br/&gt;Now for a complex API such as Rails, this type of completion would be nice, but due to the way that Ruby operates as a late typed/bound language, there isn't any way to really allow for this.  Since you can dynamically change the signature for a class on the fly using mixins or proxies (I'm probably using the wrong words), you can never get the full API for a class at coding time.  The only way would be to actually run the code, and then reflect though the class then.&#xD;&lt;br/&gt;&#xD;&lt;br/&gt;So, how do you learn Rails?  Websites, books, and videos.  This isn't to say that it isn't worth learning, but it does make it a bit more difficult to learn how to do more advanced things without a lot of page flipping.</description>
      <pubDate>Mon, 22 Jan 2007 08:02:35 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2007/1/22/One_reason_why_I_don_t_like_Ruby_on_Rails</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2007-01-22T08:02:35Z</dc:date>
    </item>
    <item>
      <title>scratch - Google Code</title>
      <link>http://www.fourspaces.com/blog/2007/1/15/scratch_Google_Code</link>
      <description>The Scratch web app framework now has a new home.  The project was originally hidden in the Fourspaces.com SVN server.  Now, it has been let loose on the world, thanks to Google Code.  This is the first project that I've hosted through Google Code, so we'll see how it all turns out.&#xD;&lt;br/&gt;&#xD;&lt;br/&gt;The trunk version has been pretty stable for the past few months, so feel free to download it and try it out.</description>
      <pubDate>Mon, 15 Jan 2007 07:24:05 GMT</pubDate>
      <guid>http://www.fourspaces.com/blog/2007/1/15/scratch_Google_Code</guid>
      <dc:creator>Marcus R. Breese</dc:creator>
      <dc:date>2007-01-15T07:24:05Z</dc:date>
    </item>
  </channel>
</rss>

