Quick Tip on Mockito — Mocking Iterator

Today I was writing unit test for a piece of code which required me to mock a iterator. My requirement was that I wanted to return true first time when hasNext() method and return false in the second iteration. It took me sometime to figure out how to write such a test case. My class for which I was writing test looks like as shown below.

import java.util.Iterator;

public class ResultFetcher {

	private ResultStore store;
	private ResultProcessor processor;

	public void fetchResults() {
		Iterator<String> iterator = store.resultIterator();
		while (iterator.hasNext()) {
			String result = iterator.next();
			processor.process(result);
		}
	}
}

The unit test code is shown below. The important line in the test is Mockito.when(iterator.hasNext()).thenReturn(true,false); which will return true first time and false second time.

import java.util.Iterator;

import org.junit.Test;
import org.mockito.Mockito;

public class ResultFetcherTest {

@Test
public void testFetchResults() {
ResultFetcher fetcher = new ResultFetcher();

ResultStore store = Mockito.mock(ResultStore.class);
ResultProcessor processor = Mockito.mock(ResultProcessor.class);
fetcher.store = store;
fetcher.processor = processor;

Iteratoriterator = Mockito.mock(Iterator.class);
Mockito.when(store.resultIterator()).thenReturn(iterator);
Mockito.when(iterator.hasNext()).thenReturn(true,false);
Mockito.when(iterator.next()).thenReturn("Hello");
fetcher.fetchResults();
Mockito.verify(processor).process("Hello");
}

}

Spring Roo PGP Exception

Today when I fired Spring Roo shell I started getting exception as shown below and I was not able to execute any command. I uninstalled Spring Roo (thinking that it might have got corrupted) but it didn’t helped after lot of firefighting I figured out the solution to overcome this problem. The problem was that yesterday I trusted some pgp keys and somehow Roo was not able to find them and started throwing exception. The solution is to remove a file name .spring_roo_pgp.bpg and restart Spring Roo. Spring Roo will create a new clean file. Continue reading “Spring Roo PGP Exception”

Fixing Exception — Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)

If you are working with Spring Roo and suddenly start getting exception “Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)” then make sure you have _Configurable.aj ITD in your project. This ITD makes the sure that your entity classes have all the required dependencies like EntityManager injected in them. Configurable ITD  looks like as shown below

privileged aspect Movie_Roo_Configurable {

    declare @type: Movie: @Configurable;

}

Spring Roo + OpenShift Express == Extreme Productivity In Cloud Part 1

Today, I released the second version of OpenShift Express Spring Roo Add-on. With this release add-on also support creation of domain namespace and changing the domain namespace. Now the only important thing left in the add-on is support for session management so that users does not  have to enter email and password with every command. From today, I am starting a series of short blog posts which will cover the features of this add-on. In this post I will be  talking about creating and changing domain namespace. Before I get into details lets me first tell you what is Spring Roo and OpenShift Express in case you don’t know about them.

Note :You can also refer to my Spring Roo series on IBM DeveloperWorks for more details.

What is Spring Roo?

Spring Roo is a lightweight productivity tool for Java™ technology that makes it fast and easy to develop Spring-based applications. Applications created using Spring Roo follow Spring best practices and are based on standards such as JPA, Bean Validation (JSR-303), and Dependency Injection (JSR-330). Roo offers a usable, context-aware, tab-completing shell for building applications. Spring Roo is extensible and allows add-ons, enhancing its capability.

What is OpenShift Express?

OpenShift Express is a Platform as a Service offering from RedHat. OpenShift Express allows you to create and deploy applications to the cloud. The OpenShift Express client is a command line tool that allows you to manage your applications in the cloud. It is currently free and runs on Amazon EC2. Currently it supports Java, Ruby, PHP, Python run times. You can refer to OpenShift Express documentation for more details.

OpenShift Express Client Tools

OpenShift Express has three client tools for creating and deploying applications to cloud. These are RHC Ruby Gem., OpenShift Express Eclipse Plugin, and SeamForge RHC Plugin. I have mainly used RHC Ruby Gem and it is very easy to use and work. There were two problems why I decided to write Roo add-on. One is that you need Ruby Runtime and second is I use Spring Roo a lot so it allows me to perform full lifecycle of the application from within Roo shell. Because I am writing add-on I can also do lot of interesting stuff like session management, making some changes to the code to avoid repetitive work. One such thing that I have already added is adding OpenShift profile in the pom.xml. This will help me automate repetitive work.

Lets Get Started

Getting started with the add-on is very easy. First you need to download Spring Roo and fire the Roo shell. Once inside the Roo shell we have to install the add-on. To do this execute the following command as shown below.

osgi start --url http://spring-roo-openshift-express-addon.googlecode.com/files/org.xebia.roo.addon.openshift-0.2.RELEASE.jar

It will take couple of seconds to install the add-on. You can view that a new OSGI process has started using osgi ps command.

Creating Domain

Before you can create domain please signup at https://openshift.redhat.com/app/express.  The email and password with which you signup will be the credentials for accessing the cloud. After you have signed up the next step is to create a domain. You can’t create the applications before creating a domain. The domain is a logical name within which all your applications will reside. It forms the part of your application url. For example if you created a domain with name “paas” and application with name “openshift” your application url will be http://openshift-paas.rhcloud.com . We can create the domain using rhc-create-domain command but in this blog I will show you how to create using Spring Roo add-on. To create domain using Spring Roo execute the command shown below.

rhc create domain --namespace openpaas --rhLogin <rhlogin> --password <password> --passPhrase <passphrase>

This command does the following things :

  1. It will create the ssh keys under user.home/.ssh folder if they does not exist. The passphrase is required for creating the sshkeys.
  2. If ssh keys already exists it loads the ssh keys from user.home/.ssh location and reuse them.
  3. finally it creates the domain with namespace openpaas.
  4. In case your credentials are wrong it will show a log line saying that credentials are wrong.

Changing Domain Namespace

Although you can’t delete a domain after you have created but you can change the domain name. To do that you can use the command shown below.

rhc change domain --namespace xyz --rhLogin <rhlogin> --password <password>

This will change the domain name to xyz.

Thats it for this blog. In the next blog we will look at how to create Spring JPA application using Spring Roo and deploy it to OpenShift Express.

Spring Roo Add-on Release Problems

I am writing a add-on for deploying Spring Roo applications to OpenShift Express cloud just like the Cloud Foundry Spring Roo add-on. The add-on is available at http://code.google.com/p/spring-roo-openshift-express-addon/. But I face problems when I release the add-on using Maven Release plugin (mvn release:prepare release:perform). So, this is simple guide to help me next time I face these issues.

  1. SnapShot Dependencies : The first problem I face is that my add-on depend on OpenShift Java client which is available as Snapshot dependency. So, I need to ignore the snapshot dependencies. This is not recommeded but some times you don’t have any other solution. For more information refer to this post http://stackoverflow.com/questions/245932/how-to-release-a-project-which-depends-on-a-3rd-party-snapshot-project-in-maven
    mvn release:prepare release:perform -DignoreSnapshots=true
    
  2. Adding Third Party Jars in an OSGI bundle. I have blogged this at https://whyjava.wordpress.com/2012/01/02/adding-third-party-jars-to-an-osgi-bundle/.
  3. The third problem I face is that svn client is not able to authenticate with Google Code. The exception that I get is shown below. To fix this I specify username and password with mvn release command as shown below.
    mvn release:prepare release:perform -DignoreSnapshots=true -Dusername=shekhar.xebia@gmail.com -Dpassword=password
    

    The exception that I get is

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.2:prepare (default-cli) on project org.xebia.roo.addon.openshift: Unable to commit files
    [ERROR] Provider message:
    [ERROR] The svn command failed.
    [ERROR] Command output:
    [ERROR] svn: Commit failed (details follow):
    [ERROR] svn: MKACTIVITY of '/svn/!svn/act/b8000ba7-c3c6-4bb2-9d3b-bd3c1db73dd3': authorization failed: Could not authenticate to server: rejected Basic challenge (https://spring-roo-openshift-express-addon.googlecode.com)
    [ERROR] -> [Help 1]
    [ERROR]
    [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
    [ERROR] Re-run Maven using the -X switch to enable full debug logging.
    [ERROR]
    [ERROR] For more information about the errors and possible solutions, please read the following articles:
    [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
    

Deploying Application To OpenShift Express using Spring Roo OpenShift Express Add-on

Last couple of years Spring Roo has been one of my favorite tool to rapidly build Spring applications for demo, POC, and learning new technologies. With Spring Roo Cloud Foundry integration you can not only build applications rapidly but deploy to Cloud Foundry public cloud with a couple of commands. In case you are not aware of Spring Roo and Cloud Foundry you can refer to my Spring Roo series on IBM DeveloperWorks. From last 5-6 months I have been following OpenShift platform as a service and I am really in love with OpenShift Express because of its feature set and simplicity. In case you are not aware of OpenShift Express please refer to the documentation. There are two ways Java applications can be deployed to express — using ruby command line tool called RHC and using Eclipse plugin. Personally I like rhc command line more than eclipse plugin. The rhc command line tool is great but you should have ruby runtime installed on your machine. Being Spring Roo afficianado I decided to write Spring Roo OpenShift Express add-on to create, deploy, add cartridges from with Roo shell. This can be thought of as a third way to deploy applications to OpenShift Express. The project is hosted on Google Code at http://code.google.com/p/spring-roo-openshift-express-addon/. In this blog I will show you how you can install the add-on, create a template OpenShift Express application, convert that application to a Spring MongoDB application using Spring Roo, and finally deploy application to OpenShift Express.  You can read the full blog at my company blog http://xebee.xebia.in/2012/01/09/running-spring-java-mongodb-apps-on-openshift-express-using-spring-roo-openshift-express-addon/

Spring Roo 1.1 Cookbook Review

This review is about Spring Roo 1.1 Cookbook by Ashish Sarin from Packt Publishing. Before I get into details lets me first tell you what is Spring Roo in case you don’t know.

Note : I am author of Spring Roo series on IBM DeveloperWorks.

What is Spring Roo?

Spring Roo is a lightweight productivity tool for Java™ technology that makes it fast and easy to develop Spring-based applications. Applications created using Spring Roo follow Spring best practices and are based on standards such as JPA, Bean Validation (JSR-303), and Dependency Injection (JSR-330). Roo offers a usable, context-aware, tab-completing shell for building applications. Spring Roo is extensible and allows add-ons, enhancing its capability.

Book Details

  1. 7 chapters covered in 460 pages. Each chapter has some recipes and each recipe is divide into four parts — Getting Started, How to do it, How it works, and there’s more. So each recipe give you all the details required from getting started to details related to how it works. I liked this approach.
  2. Book costs $44.99 http://www.packtpub.com/spring-roo-1-1-cookbook/book
  3. This book covers Spring Roo in detail.

Pros

  1. Recipes represents solution to real world problems. This book covered how to define composite keys, talked about how you can use JNDI datasource, how you can create application which has to interact with multiple databases etc. These are the problems you will face in real world and this book tries to answer them.
  2. The two chapters I liked the most are chapter 3 and 4 which covered Advanced JPA and Spring MVC web applications. Chapter 3 covered in detail how you can create many-to-one, one-to-many relations, create mapped super class etc. Chapter 4 gives you all detail you need to create Spring MVC application and customize them according to your requirement.
  3. This book from the start talks how different features are provided by Spring Roo through Add-ons. I think it is very important to share Spring Roo add-on architecture from the start as this tells you that you can extend Spring Roo by writing your own add-ons.
  4. The book not only covers Spring Roo but also provides good introduction to the technologies it uses.
  5. Chapter 6 gives good introduction to technologies like Solr, GAE, JMS. It really shows the power of Spring Roo.
  6. I think this book does good justice to the power of Spring Roo.

Cons

  1. One thing that I was looking forward was customizing GWT applications. This book talked in detail about the GWT application created about Spring Roo but does not cover how to customize the GWT app.
  2. Same is the case with the 7th chapter which cover writing add-ons. The book cover in good detail the default add-on generated by Spring Roo but does not shows how you can customize them to write your own add-ons.
  3. This book is based on Spring Roo 1.1.5 Release version but recently Spring Roo has released 1.2 version. Some commands talked in this book are deprecated and are not the recommended now. Also, lot of new features like MongoDB support, JSF support , multi module projects etc. are not there.

Conclusion

Overall I liked the book and I think it is a good book to read if you are thinking of using Spring Roo in future. Yes it is missing some new features but if you will not be using those features this book is a good buy.

Using MongoDB Replica Set With Spring MongoDB 1.0.0.RC1

The primary means for replication is to ensure data survives single or multiple machine failures. The more replicas you have, the more likely is your data to survive one or more hardware crashes. With three replicas, you can afford to lose two nodes and still serve the data. MongoDB supports two forms of replication, Replica Sets and Master Slave. Replica Sets is the recommended way to do replication in MongoDB and will cover only Replica Sets in this post.

Couple of weeks back I was working in POC where we need to set up MongoDB replication. As I am Spring aficionado I decided to use Spring MongoDB to interact with Replica Set. We used Spring Roo to quickly bootstrap the project. All the project setup, Spring MongoDB setup, JUnit test cases, evern Spring MVC UI was created in minutes thanks to Spring Roo. I am big Spring Roo fan — I just love it. Thanks SpringSource for such an amazing project. Spring Roo uses Spring MongoDB version 1.0.0.M5 which has a bug that it does not support WriteConcern value REPLICAS_SAFE. But with the current release 1.0.0.RC1 that issue has been fixed and now you can use REPLICAS_SAFE. REPLICAS_SAFE is the recommended value for WriteConcern in case of replication.  This is a step by step guide from creation of Spring project to working MongoDB replica set.

  1. Create the project using Spring Roo. If you are not aware of Spring Roo you can read my Spring Roo series. I am using Spring Roo to quickly configure a Spring MongoDB project.
    project --topLevelPackage com.xebia.mongodb.replication --projectName mongodb-replication-demo --java 6
    mongo setup --databaseName bookshop --host localhost --port 27017
    entity mongo --class ~.domain.Book --testAutomatically --identifierType org.bson.types.ObjectId
    field string --fieldName title --notNull
    field string --fieldName author --notNull
    field number --type double --fieldName price --notNull
    repository mongo --interface ~.repository.BookRepository --entity ~.domain.Book
    

    This will create a Spring maven project, configure MongoDB to work with Spring, create one Collection Book and will add three fields title, author, and price to the collection. All the CRUD operations will carried out using BookRepository.

  2.  Start the MongoDB server using ./mongod and run BookIntegrationTest and make sure all tests pass.
  3. Setup replica set following the MongoDB documentation http://www.mongodb.org/display/DOCS/Replica+Set+Tutorial.
  4. Update the applicationContext-mongo.xml as shown below but before add the property mongo.replicaset which will have all nodes.
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:cloud="http://schema.cloudfoundry.org/spring" xmlns:context="http://www.springframework.org/schema/context" xmlns:mongo="http://www.springframework.org/schema/data/mongo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd        http://www.springframework.org/schema/data/mongo        http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd        http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd        http://schema.cloudfoundry.org/spring http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd">
    
        <mongo:db-factory dbname="${mongo.database}" id="mongoDbFactory" mongo-ref="mongo"/>
    
        <mongo:repositories base-package="com.xebia.mongodb.replication"/>
    
        <!-- To translate any MongoExceptions thrown in @Repository annotated classes -->
        <context:annotation-config/>
    
        <bean class="org.springframework.data.mongodb.core.MongoTemplate" id="mongoTemplate">
            <constructor-arg ref="mongoDbFactory"/>
        </bean>
    
    	<mongo:mongo id="mongo" replica-set="${mongo.replicaset}" write-concern="REPLICA_SAFE">
    		<mongo:options auto-connect-retry="true"/>
    	</mongo:mongo>
    </beans>
    

    If you run the tests again all the tests will fail and you will see following exception.

    Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from file [/home/shekhar/dev/workspaces/writing/mongodb-replication-demo/target/classes/META-INF/spring/applicationContext-mongo.xml]; nested exception is java.lang.ArrayIndexOutOfBoundsException: 1
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.
    doLoadBeanDefinitions(XmlBeanDefinitionReader.java:412)
    

    The reason for this exception is because there is a bug in Spring MongoDB 1.0.0.M5 which is not able to parse WriteConcern REPLICA_SAFE value.

  5. To make it work we have to work with Spring MongoDB latest version 1.0.0.RC1. This is released just 3 days back on 7th December 2011.Update the pom.xml with 1.0.0.RC1.
     <dependency>
    	<groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>1.0.0.RC1</version>
    </dependency>
    

    Run the BookIntegrationTest the tests will fail again and see the following exception stacktraces.

    java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotationUtils
    .getAnnotation(Ljava/lang/reflect/AnnotatedElement;Ljava/lang/Class;)
    Ljava/lang/annotation/Annotation;
    at org.springframework.transaction.annotation.SpringTransactionAnnotationParser
    .parseTransactionAnnotation(SpringTransactionAnnotationParser.java:38)
    
  6. To make it ran you have to use latest Spring version 3.1.0.RC2 in pom.xml
    <spring.version>3.1.0.RC2</spring.version>
    
  7. Final change you need to make is in applicationContext-mongo.xml. Change the value of write-concern to REPLICAS_SAFE.
    <mongo:mongo id="mongo" replica-set="${mongo.replicaset}" write-concern="REPLICAS_SAFE">
    	<mongo:options auto-connect-retry="true"/>
    </mongo:mongo>
    
  8. Run the tests and all the tests will pass.

Spring Roo CompareTo Add-on Released

Over the weekend I created an advanced Spring Roo add-on to provide support for creation of compareTo method. This add-on is on similar lines of Spring Roo own equals add-on which provide implementation of equals and hashcode methods. The add-on is released and available for community to use. The add-on is listed in Spring Roo repository XML http://spring-roo-repository.springsource.org/roobot/roobot.xml . It is built using Spring Roo latest version 1.2.0.RC1. This post will talk about how to install and use the add-on.

Installing the compareTo add-on

Open the operating system command line and type roo. In case you don’t have Spring Roo setup please refer to my IBM DeveloperWork article on Spring Roo. After the roo shell initiates type the following command to install the add-on.

addon install bundle --bundleSymbolicName org.xebia.roo.addon.compareto

If you don’t have automatic pgp trust enable you will see a message on Roo shell saying that you first have to trust my pgp key before you can install the add-on. To trust the key type the following Roo command.

pgp trust --keyId 0x9B68220C

Once it is enable re-run the addon install command and add-on should get installed. To verify that add-on is installed type the osgi ps command and you should compareto add-on listed at the bottom of the command output.

[  78] [Active     ] [    1] spring-dw-roo-compareto-addon (0.1.1.BUILD)

This add-on exposes two commands compareto setup and compareto and these commands are enabled after you have created entity. This is because before you have created any entity it does not make sense to have compareTo method.

Using the compareTo add-on

Lets first create a simple bookshop application. Type the following command which will create the project, setup database and create a simple book entity.

project --topLevelPackage com.xebia.bookshop --projectName bookshop
jpa setup --database HYPERSONIC_IN_MEMORY --provider HIBERNATE
entity jpa --class ~.domain.Book --testAutomatically
field string --fieldName title --notNull
field string --fieldName author --notNull
field number --type double --fieldName price --notNull

After you have ran the commands above you can now create compareTo method for book entity.To create the compareTo method type the following commands.

compareto setup
compareto add --type ~.domain.Book

The first command will add the required dependencies and second will create the Book_Roo_Compareto.aj ITD which contains the compareTo method.

If you want to exclude some fields in compareTo method you should specify i.e. if you don’t want author and price field to be used in compareTo method you can specify them in excludeFields attribute as shown below.

compareto add --type ~.domain.Book --excludeFields "author price"

Use this add-on and share feedback.