Archive for September, 2006
Compass 1.1 M2 Released
Wednesday, September 27th, 2006OpenSymphony and the Compass team are pleased to announce the release of version 1.1 M2. This is the second milestone release of version 1.1, major features include:
- Support Unmarshall: Allowing to disable Compass support for unmarshalling objects from the search engine. This feature enable Compass not to store extra information in the index, and use much less memory.
- Dynamic Meta Data: Allows to define syntactic indexable content using scripting/expression languages like ognl, groovy, velocity, commons-el and commons-jexl.
- Simplified API usage when working within a transaction, including @CompassContext support in Spring. This feature is explained here, here, and here.
- Support for the latest Hibernate and Spring versions.
Compass at NL-JUG J-FALL
Thursday, September 21st, 2006Just found out that Compass is presented at NL-JUG J-FALL. Looks like a very interesting session about Compass by Uri Boness.
More on Compass And Spring
Wednesday, September 20th, 2006After writing the previous blog entry about @CompassContext and the ability to inject a transactional aware CompassSession that works as is (without worrying about compass transaction management code or even closing the session) it struck me that it can and should be feature available for applications that do not use annotations (for various reasons, the prime one is Java 1.4).
We now have another factory bean in Compass called LocalCompassSessionBean. It is a Spring FactoryBean that allows to inject a CompassSession directly into a Java bean with a CompassSession setter. The CompassSession injected would act the same as a @CompassContext injected session, and simplify the usage of Compass within managed transactions environments.
It can be used either by explicitly declaring it using the usual Spring bean tag, or using Compass support for Spring 2 schema based configuration using: <compass:session id=”session” />. Note, you can also set the Compass instance to use, but it is optional since LocalCompassSessionBean will automatically use a Compass instance configured within Spring application context if there is a single one.
Another feature that bubbled out of the previous post is something Hani mentioned, and is the lack of the ability to programmatically add settings / mappings to the CompassConfiguration before a Compass instance is created when using schema based configuration. If using old bean style Spring configuration, one can extend LocalComapssBean and override newCompass method where it can be done, but with schema based configuration, there is no way to do so. LocalCompassBean now has the option to plug an implementation of LocalCompassBeanPostProcessor, where the generated CompassConfiguration can be programmatically processed. It can be configured as part of the compass tag: <compass:compass postProcessor=”myPost” … />
Last, registering a Compass annotation bean post processor is now simpler with Spring 2 schema based support, and looks like: <compass:context />.
@CompassContext and Spring
Monday, September 18th, 2006The most common usage of Compass is within a Spring enabled application. If the application uses a Compass within a Spring bean, and Java 5, you can now use @CompassContext in order to inject either a Compass or a CompassSession instance.
The following simple dao uses the @CompassContext annotation:
public class CompassContextDao { @CompassContext Compass compass; CompassSession session; @CompassContext protected void setCompassSession(CompassSession session) { this.session = session; } }
The dao uses both Compass and CompassSession and shows how the annotations can be used (both on field and setter method). Note, when the dao already uses Spring declarative transactions for its operations (or has a service layer that has it), one can inject the CompassSession and just use it, without worrying about Compass transaction management (see previous blog entry).
Compass uses spring bean post processor and it must be configured within Spring configuration in order to enable this feature. Here is an example of Spring configuration file:
<bean class=“org.compass.spring.support.CompassContextBeanPostProcessor”/> <compass:compass name=“compass”> <compass:connection> <compass:file path=“target/test-index” /> </compass:connection> <compass:mappings> <compass:class name=“org.compass.spring.test.context.A” /> </compass:mappings> </compass:compass> <bean id=“dao” class=“org.compass.spring.test.context.CompassContextDao” />
This feature is part of 1.1 M2 SNAPSHOT and beyond. Enjoy!
Compass in Managed Transactions Environments
Saturday, September 16th, 2006Up until now, in order to use Compass, one had to follow the following template:
CompassSession session = compass.openSession(); CompassTransaction tr = null; try { tr = session.beginTransaction(); // work with Compass session tr.commit(); } catch (Exception e) { if (tr != null) { tr.rollback(); } } finally { session.close(); }
Compass also came with a simple CompassTemplate class that used the template design pattern in order to simplify the usage. But still, when using Compass within a managed transaction environment, there isn’t really a need for all the Compass managed transaction code, since the transactions are already managed outside of the Compass code. This is the case when working with JTA and CMT, or when using Spring transaction support (either programmatically or declaratively).
Compass already binds its sessions to a transaction, so they are reused when being opened again within the same running transaction. With this new feature Compass tries to automatically join an already running outer transaction. The transaction can be an outer local Compass transaction, a JTA transaction, or a Spring managed transaction. Basically what it means is that if your Compass code already runs in a JTA or a Spring managed transaction, you won’t have to begin a Compass transaction, commit/rollback the transaction, or even close the session. The code ends up looking like this:
// there is already a running transaciton // (outer local Compass one, JTA, or Spring) CompassSession session = compass.openSession(); // work with Compass session, no need to call // beginTransaction or close on the session
This should really simplify Compass usage within a JEE/CMT or Spring environments, and is part of 1.1 M2 SNAPSHOT and beyond. Enjoy!
Another Compass & AppFuse Tutorial
Friday, September 15th, 2006Matt Raible pointed out a tutorial for integrating Compass with AppFuse. Enjoy.
Project Build Environment
Wednesday, September 13th, 2006Configuring a proper build environment for a project is never as simple as it first looks like. There are many factors one must take into account when configuring the build environment, including testing level, project complexity, QA involvement and many more. When I try to tackle the introduction of build systems into a project, I usually take the project and tailor a build environment specialized for it. Most times I end up identifying several build types that the project should have:
CI Buid
The CI build is usually your first tick in a list of boxes for “lets make my project Agile”. Its characteristics usually revolve around the build system identifying changes made to your project Version Control System (VCS), building the project, and running its tests. Many times, the CI build includes tagging the VCS and creating a full distribution.
This is actually the way Compass works. Compass unit and integration level testing takes less than 5 minutes to execute, and a whole distribution build is less than 10 minutes. What you end up with is a complete distribution ready to be used once a build succeeds after a commit.
This is usually not the case for complex projects that takes a longer cycle time in order to create a complete distribution. There are many reasons why complex projects ends up with longer cycles, with the top one being excessive testing needed to be performed. Long running integration testing, tests that require manual execution (or partial manual execution), tests that needs to be executed on multiple platforms, all contribute for that dreaded “test hourglass”. This is why in complex projects the Nightly Build project is introduced.
Nightly Build
First, once a project has a nightly build, we can ease up the life of our CI build. What I have found in projects with nightly builds is that there is no need to create a complete distribution or tag the VCS in your CI build. You rarely need it in your day to day job.
Second, if a project has a nightly build, it does not mean that there are no tests to run in your CI build. All the unit level tests, and some of your integration tests should be run in the CI build. Choosing which tests to run is a work of art, since you want to get the test execution time into a window timeframe (usually no more than half an hour), but still be able to cover most of the cases when things break (note, this does not necessarily means that they cover more code than other tests that can run in the same amount of time).
So, what does the Nightly build do? Very similar to what we said in the CI build for simple/moderate projects. Compile the code, create a distribution, tag VCS with something that denotes un-tested, run all the tests, and then change the tag into nightly tested. Note, that the distribution is created before the tests are run, which is mainly done since in the morning QA might want to take the distribution and investigate why it failed, a process that should not stop other people from committing code (most of the times you do not want to stop everything because the nightly failed).
The tests may take several hours to run which is ok for a nightly build. When the project also has manual testing as part of its test cycle, QA (or that unlucky developer that drew the shortest straw) can perform it on the distribution created by the nightly build.
Naturally, if the project is in the complexity level of landing a human mission on mars, a night might not be enough to run all the automated tests. It simply means that you introduce another build, maybe a weekly build (kindda like a Scrum of scrums). If your project does require a weekly build, investigate why you need it, your project or your tests really should not be this complex or not optimized. Remember, the longer the cycle, the harder it is to pin point the offending code.
Developer Build
Last, but definitely not least, is the build that a developer executes on the development machine before committing any code. The build must compile the system, and must execute some tests. If the project is simple, with only CI build with compile/test cycle of less than 10 minutes, the developer can run the same CI build. If the compile/test cycle takes longer than 10 minutes, more often than not, developers will simply stop executing the tests before they commit. This means that another set of test configuration needs to be set for developer level builds which covers as much as possible within a smaller timeframe than the CI build (again, not in terms of test code coverage, but in terms of things that usually break).
Final Thoughts
Many times, your project manager as part of “agelifying” the project would task you to configure or introduce a build environment into the project. This is not a simple task, and should be analyzed properly. The most common mistake I have seen with defining build environments is not recognizing the needs for different types. The fact that a developer needs to run tests that takes more than 10 minutes is unacceptable, and the same goes for long running CI builds. If your project needs several build types, don’t be afraid to introduce them.
IntelliJ now has background VCS Commit/Update
Thursday, September 7th, 2006I have been waiting for this one for ages. The latest IntelliJ IDEA 6.0 (Demetra) builds now come with Version Control Update/Commit operations performed in the background. Finally!
Dynamic Meta Data in Compass
Wednesday, September 6th, 2006Dynamic meta data feature in the latest Compass build (1.1 M2 SNAPSHOT) allows to define syntactic meta-data definition using dynamic/expression language meta data values. There are many use cases for using dynamic meta-data, usually revolving around using Resources for displaying search results, where a property name used for displaying results is the combination of several properties or objects within the object tree.
If for example an application would like to iterate through a Resource based search results and use a single meta-data name (property name) called “display” in order to show it to the user, “display” can be a dynamic meta-data constructed out of several other Object properties.
There are many libraries/languages out there that can evaluate a dynamic expression, Compass comes with built in support for jakarta commons el/jexl, velocity, ognl, and groovy. If we use the following class:
public class A { private Long id; private String value; private String value2; private Date date; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getValue2() { return value2; } public void setValue2(String value2) { this.value2 = value2; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } }
We can use the following mappings definition (we use the same mapping for several different types of dynamic expression):
<compass-core-mapping package=“org.compass.core.test.dynamic.el”> <class name=“A” alias=“a1″> <id name=“id”/> <dynamic-meta-data name=“test” converter=“el”> ${data.value}${data.value2} </dynamic-meta-data> <dynamic-meta-data name=“test” converter=“groovy”> return data.value + data.value2 </dynamic-meta-data> <dynamic-meta-data name=“test” converter=“ognl”> data.value + data.value2 </dynamic-meta-data> </class> </compass-core-mapping>
Compass will set under the “data” key the instance of the class the mappings refer to. Note, that dynamic meta data is used only for marshalling (the process of persisting an Object to the search engine).
What other scripting/expression language libraries do you think Compass should support?

My name is Shay Banon, the founder of