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.