When should ports go native?

Our product, Secret Server, uses the DotLucene API for searching of items ("secrets") in the application.  DotLucene is an impressive API which creates index files on disk based on the data you feed to it.  It then allows for some very powerful text searches to find data such as "amazon.com~" which will find all secrets containing various spellings of amazon.com.  (More info here).

The DotLucene API is, as you might have guessed, a port of the Java Lucene search API and herein lies the problem.  Lucene is written in Java and therefore the API has a Java flavor to it.  This makes it harder and less intuitive for a native .NET developer to use. 

To index a secret, we use:

  1 IndexWriter writer = new IndexWriter(_indexLocation, new StandardAnalyzer(), false);
  2 Document document = new Document();
  3 document.Add(Field.Text("Name", secret.Name));
  4 document.Add(Field.Text("Created", secret.Created.ToShortDateString()));
  5 document.Add(Field.Keyword("Id", secret.Id.ToString()));
  6 writer.AddDocument(document);
  7 writer.Optimize();
  8 writer.Close();

A typical .NET developer would probably expect IndexWriter to implement IDisposable but it doesn't.  How do we ensure the file is closed should an error occur while indexing?

Our problem was figuring out how to reindex a "secret", simply adding it creates duplicates in the index.

  1 IndexReader reader = null;
  2 try
  3 {
  4 	reader = IndexReader.Open(_indexLocation);
  5 	reader.Delete(new Term("Id", secret.Id.ToString()));
  6 } 
  7 finally
  8 {
  9 	if (reader != null)
 10 	{
 11 		reader.Close();
 12 	}
 13 }

The solution is to use the IndexReader (?!).  Yes, not very intuitive.  This can't really be attributed to a "language style" issue since a Java developer probably wouldn't expect this either!

I have talked about language style before but porting an API has even more issues.  NUnit broke away from their Java porting heritage in 2.1 by rewriting it to use custom attributes instead of jUnit's naming conventions for testfixtures and tests.  This had many benefits since they could produce a more elegant design that would harness the power of the .NET platform and it would be more in the style of typical .NET APIs.  These benefits come at a cost however since anyone familiar with jUnit can no longer easily transfer their knowledge to NUnit. 

It also means that many other areas of knowledge from the original API are not always useful for the native port:

  • Newsgroup posts
  • Online documentation
  • Tutorials

When does it make sense to go native with a port?  Is going native a sign of maturity for an API?

Jonathan Cogley is the CEO and founder of thycotic, a .NET consulting company and ISV in Washington DC.  thycotic has just released Thycotic Secret Server which is a secure web-based solution to both "Where is my Hotmail password?" and "Who has the password for our domain name?".  Secret Server is the leader in secret management and sharing within companies and teams.

2 Comments

  • Well, to be fair, the Lucene API in Java doesn't win a lot of awards for elegance, either. Ideally someone should fix the API in both languages in this case.

  • Um, yeah, that's what he's saying... Lucene.NET is an almost direct port of Lucene Java's API.



    Anyhoo, ther's very few APIs out there that actually don't suck. Writing a decent API is very, very hard and beyond the reach of most programmers.

Comments have been disabled for this content.