Saturday, May 7, 2011

Hibernate Search meets Scala

Today I've pushed to github a small prototype, to test how/if Hibernate Search can play nicely with Scala 2.8.1.

If you haven't heard about Hibernate Search before, I highly recommend a quick look, it brings Lucene's power to your hibernate enabled application.
So if you are using Hibernate and you're interested in Lucene, chances are this could be for you.

Anyway, I've spent a little time building this small project, and I ran into some issues along the way:

Getting the Annotations to work right was the biggest pain point. Otherwise everything went smoothly.

The Java version:
@Indexed(index = "indexes/test")
@AnalyzerDef(name = "html_standard_analyzer", 
    tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class), 
    charFilters = { @CharFilterDef(factory = HTMLStripCharFilterFactory.class) }, 
    filters = {
        @TokenFilterDef(factory = StandardFilterFactory.class),
        @TokenFilterDef(factory = LowerCaseFilterFactory.class),
        @TokenFilterDef(factory = StopFilterFactory.class) })
@Analyzer(definition = "html_standard_analyzer")

The Scala version:
@Indexed(index = "indexes/test")
@AnalyzerDef(name = "html_standard_analyzer",
  tokenizer = new TokenizerDef(factory = classOf[StandardTokenizerFactory]),
  charFilters = { Array(new CharFilterDef(factory = classOf[HTMLStripCharFilterFactory])) },
  filters = {
    Array(new TokenFilterDef(factory = classOf[StandardFilterFactory]),
      new TokenFilterDef(factory = classOf[LowerCaseFilterFactory]),
      new TokenFilterDef(factory = classOf[StopFilterFactory]))
  })
@Analyzer(definition = "html_standard_analyzer")

I'm using Eclipse, and there are still some weird issues: although there are no problems reported on the project as a whole and the tests pass, opening the annotated class will show some 'local' errors, apparently related to the scala compiler, not eclipse ide itself:
@Field(index = org.hibernate.search.annotations.Index.TOKENIZED, store = Store.NO)
will yield this error:
Multiple markers at this line
  - annotation argument needs to be a constant; found: org{org.type}.hibernate{org.hibernate.type}.search{org.hibernate.search.type}.annotations
   {org.hibernate.search.annotations.type}.Index{org.hibernate.search.annotations.Index.type}.TOKENIZED{org.hibernate.search.annotations.Index(value TOKENIZED)}
  - annotation argument needs to be a constant; found: Store{<null>}.NO{<null>}

JUnit's @AfterClass not really related to Hibernate Search, but still interesting.

If you attempt (as I did :) to just add @AfterClass to just any method on the class, you'll see the beautiful:
java.lang.Exception: Method beforeClass() should be static

AfterClass is expected to be on a static method. Apparently in scala this is done by having a companion object.
This is how a proper JUnit test should look like.
class SimpleJunitTest {
  @Before
  def before() {
    println("before");
  }
  @Test
  def test1() {
    println("t1");
  }
  @Test
  def test2() {
    println("t2");
  }
  @After
  def after() {
    println("after");
  }
}

object SimpleJunitTest {
  @BeforeClass
  def beforeClass() {
    println("before class");
  }
  @AfterClass
  def afterClass() {
    println("after class");
  }
}
Notice class SimpleJunitTest has the tests, and object SimpleJunitTest has the static methods annotated with @BeforeClass and @AfterClass
Output:
before class
before
t1
after
before
t2
after
after class

0 comments:

Post a Comment