Lucene 2.3 – working example of Indexer and Searcher

Hi All,

Now days I was working on Lucene a Java API that offers you search capability for your application.
Lucene is a powerful search library that lets you easily add search to any application. One of the key
factors behind Lucene’s popularity is its simplicity, but don’t let that fool you under the hood there are
sophisticated, state of the art Information Retrieval techniques quietly at work.

Current version available is 2.3.2.

The book i am referring for Lucene is Manning series "Lucene in Action ", but problem with this book is , this is handling Lucene 1.4 version that is entirely different from the latest one. There are many new syntax changes because of that you will no be able to run this books example with 2.3 Version.

I have modified its basic Indexer and Searcher example to run with latest version and posting here for your reference.

Indexer.java

This will create Index of directory provided by the user 

Continue reading “Lucene 2.3 – working example of Indexer and Searcher”

How to change Eclipse SVN Plugin Password

Subclipse does not collect or store username and password credentials when defining a repository. This is because the JavaHL and SVNKit client adapters are intelligent enough to prompt you for this information when they need to — including when your password has changed.

You can also allow the adapter to cache this information and a common question is how do you delete this cached information so that you can be prompted again? We have an open request to have an API added to JavaHL so that we could provide a UI to do this. Currently, you have to manually delete the cache. The location of the cache varies based on the client adapter used.

JavaHL caches the information in the same location as the command line client — in the Subversion runtime configuration area. On Windows this is located in %APPDATA%\Subversion\auth. On Linux and OSX it is located in ~/.subversion/auth. Just find and delete the file with the cached information.

SVNKit caches information in the Eclipse keyring. By default this is a file named .keyring that is stored in the root of the Eclipse configuration folder. Both of these values can be overriden with command line options. To clear the cache, you have to delete the file. Eclipse will create a new empty keyring when you restart.

Note: If using tortoise SVN, can reset the same by going to settings > Saved Data and clear Authentication Data.

A simple class for converting any Java object to XML string

In need to save XML representation of your Java object Here is a simple 200-line class that will do this using reflection. But don`t worry, there is some very powerful caching going on, so that the performance will be very good. 

 // OptimizedReflectionMarshaller.java

package my;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

/*
 * This is a utility class that marshals a Java Object into an XML
 * String.  Originally, this used StringBuffer to build the XML
 * String.  However, it has been modified from it's original
 * version to build the XML with JDOM instead.
 *
 * @author Kirill at http://www.topxml.com/rbnews/XML/re-2909_A-simple-class-for-converting-any-Java-object-to-XML-string.aspx
 *
 * @date January 21, 2008 – modified
 * @author Jimmy Honeycutt – modified to use JDOM to create XML instead of StringBuffer.
 
 */
public class OptimizedReflectionMarshaller {
    // cache for getters
    private static HashMap gettersMap = new HashMap();

    // cache for storing info on whether certain class implements Collection
    private static HashMap collectionsMap = new HashMap();

    private static final String JAVA = "java.";
    private static final String JAVAX = "javax.";
 
    private static final Class[] EMPTYPARAMS = new Class[0];
  Continue reading “A simple class for converting any Java object to XML string”

Java.io.IOException: Invalid header signature; read

Hi,

Today I was creating a Java Program to read a Excel files (created by importing text log files)  using  POI HSSF and faced the following errors:

java.io.IOException: Invalid header signature; read 8751655596022002505, expected -2226271756974174256 .

 After a analysis i found that the excel file I am using is not an Excel binary file. It's a text file with a .xls extension s.t. Excel can quietly convert it and display as a spreadsheet. HSSF deals with files written in Excel format only.

 I used the Save As… command to save that file as Excel . And now the problem is Solved :).

com.sun.mail.smtp.SMTPSendFailedException: 530 authentication required (#5.7.1)

Errors:

DEBUG SMTP: use8bit false
MAIL FROM:<nitingautam@……com>
530 authentication required (#5.7.1)
com.sun.mail.smtp.SMTPSendFailedException: 530 authentication required (#5.7.1)

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1333)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:906)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:535)
    at javax.mail.Transport.send0(Transport.java:151)
    at javax.mail.Transport.send(Transport.java:80)
    at practical.Mailer.main(Mailer.java:37)
QUIT
com.sun.mail.smtp.SMTPSendFailedException: 530 authentication required (#5.7.1)

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1333)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:906)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:535)
    at javax.mail.Transport.send0(Transport.java:151)
    at javax.mail.Transport.send(Transport.java:80)
    at practical.Mailer.main(Mailer.java:37)
 

 It requires session authentication

Working Code 

package practical;

import java.security.Security;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class GoogleTest {

private static final String SMTP_HOST_NAME = "smtp.gmail.com";
private static final String SMTP_PORT = "465";
private static final String emailMsgTxt = "Test Message Contents";
private static final String emailSubjectTxt = "A test from gmail";
private static final String emailFromAddress = "something@gmail.com";
private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
private static final String[] sendTo = {"someone@gmail.com"};

public static void main(String args[]) throws Exception {

Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

new GoogleTest().sendSSLMessage(sendTo, emailSubjectTxt,
emailMsgTxt, emailFromAddress);
System.out.println("Sucessfully Sent mail to All Users");
}

public void sendSSLMessage(String recipients[], String subject,
String message, String from) throws MessagingException {
boolean debug = true;

Properties props = new Properties();
props.put("mail.smtp.host", SMTP_HOST_NAME);
props.put("mail.smtp.auth", "true");
props.put("mail.debug", "true");
props.put("mail.smtp.port", SMTP_PORT);
props.put("mail.smtp.socketFactory.port", SMTP_PORT);
props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
props.put("mail.smtp.socketFactory.fallback", "false");

Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {

protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("something@gmail.com", "pass");
}
});

session.setDebug(debug);

Message msg = new MimeMessage(session);
InternetAddress addressFrom = new InternetAddress(from);
msg.setFrom(addressFrom);

InternetAddress[] addressTo = new InternetAddress[recipients.length];
for (int i = 0; i < recipients.length; i++) {
addressTo[i] = new InternetAddress(recipients[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);

// Setting the Subject and Content Type
msg.setSubject(subject);
msg.setContent(message, "text/plain");
Transport.send(msg);
}
}

Testing Your Controllers

One of the reasons for setting up this page was I wanted to write something somewhere about the new testing techniques I've been using over the past few days. I'm working on a Java web application, using a fairly standard MVC structure. Working on an XP team, I've always felt a little uneasy about not having a good way to build controllers test first. Typically in past projects I've tested controllers indirectly by using tools like HttpUnit to interact with the web front end, and exercise the view and controller components together. This approach has a number of drawbacks. In the case of a failure, it is difficult to determine whether the bug is in the view or the controller (or even the model). It is also necessary to develop the view and the controller in tandem, as one cannot be tested without the other. On my current project, we are using Spring to provide the MVC framework. This allows us to make use of some of the other facilities provided by Spring to enhance our testing. Spring provides support for unit testing controllers independently. This has a number of advantages:

  • We can develop controllers test-first.
  • Breakages in the unit tests point explicitly to problems in the controller, rather than problems in one of the combination of Model, View and Controller.
  • We can run the unit test outside of the container, meaning that we do not have to deploy within each code/test cycle.
  • The tests themselves run faster.
  • We can develop and test all of our controller code before developing any of the view components.
  • We can develop and test all of our controller code before creating the Spring application-context.xml, which makes the requirements for the contents of this file much clearer.

The difficulty we had had with unit testing controllers previously was that the methods in their public interface tended to take an HttpServletRequest and HttpServletResponse as parameters, and operate on these. When running a unit test, such objects are not normally to hand, and are difficult to construct. Spring aids this situation by providing the classes MockHttpServletRequest and MockHttpServletResponse in spring-mock.jar (note that these classes are not part of the core Spring jar). Here is an example of how we can use them in a JUnit test case.

import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.servlet.ModelAndView;

public MyControllerTest extends TestCase {

public void testGettingIndexPage() throws Exception {

MyController controller = new MyController();
controller.setIndexView("index.jsp");

MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletRequest();

request.setMethod("GET");

ModelAndView modelAndView = controller.handleRequest(request, response);

assertEquals("Should get index page", modelAndView.getViewName(), "index.jsp");
}
}

This test shows that we intend our controller to respond to requests on the base url to display index.jsp. By writing the test first, we can see what we need to implement in our controller. To make this test pass requires only a very simple controller (which will be a subclass of one of the Spring MVC controllers).


import org.springframework.web.servlet.mvc.AbstractController;

public class MyController extends AbstractController {

private String indexView;

public void setIndexView(String viewName) { indexView = viewName; }
public String getIndexView() { return indexView; }

public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
return new ModelAndView(getIndexView());
}
}

To make things a bit more interesting, we can add a test that passes in some parameters on the request, and expects an appropriate response, for example passing in a search query and expecting a results page back. Adding to our test case, we can write:

     public void testSearching() throws Exception {          MyController controller = new MyController();         controller.setSearchResultsView("results.jsp");         MockHttpServletRequest request = new MockHttpServletRequest();         MockHttpServletResponse response = new MockHttpServletResponse();         request.setMethod("GET");          request.addParameter("query","testing");          ModelAndView modelAndView = controller.handleRequest(request, response);          assertEquals("Should get results page", modelAndView.getViewName(), "results.jsp");             }

Again the intention of the test is pretty clear (we can now see that our testcase might benefit from factoring some common setup into a setup method, but we'll leave that for now), and again, we don't need to add much to our controller to make it pass.

 

public class MyController extends AbstractController {

// in addition to the fields and accessors from before…
private String searchResultsView;

public void setResultsView(String viewName) { searchResultsView = viewName; }
public String getSearchResultsView() { return searchResultsView; }

public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {

String query = request.getParameter("query");
if ( query != null ) {
// perform the search
return new ModelAndView(getSearchResultsView());
} else {
return new ModelAndView(getIndexView());
}
}
}

This shows a couple of very simple iterations of writing tests and implementation for a controller, you can go a lot further, making both the tests and the implementation more sophisticated. The main point is that we have built and tested the controller in a way that allows quick iteration, promotes clarity and good test coverage, and does not require a view component to be written to do so.

Unit Testing with Junit, Spring and Hibernate – Part 2

This is a continuation from my previous post on Spring and MockStrutsTestCase and focus on testing Hibernate DAO’s. As I mentioned in the previous post, Spring framework provides a nifty base class (AbstractTransactionalDataSourceSpringContextTests) that provides automatic transaction rollback, exposing a JDBC template to interact with the DB and auto wiring of beans.

Lets take a simple DAO class that save a User object to the database:

public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
  public void save(User user) {
      getHibernateTemplate().save(user);
  }
}

Now in order to test this you would write a test class as below extending from AbstractTransactionalDataSourceSpringContextTests class.

public class UserDaoTest extends AbstractTransactionalDataSourceSpringContextTests {
  private UserDao userDao;
  private SessionFactory sessionFactory = null;

  protected String[] getConfigLocations() {
      return new String[]{"test-spring-config.xml"};
  }

  /**
   * Spring will automatically inject UserDao object on startup
   * @param userDao
   */
  public void setUserDao(UserDao userDao) {
      this.userDao = userDao;
  }

  /**
   * Spring will automatically inject the Hibernate session factory on startup
   * @param sessionFactory
   */
  public void setSessionFactory(SessionFactory sessionFactory) {
      this.sessionFactory = sessionFactory;
  }

  /**
   * Test the save method
   *
   */
  public void testSave(){
      String query = "select count(*) from user where first_name = 'Firstname'";
      int count = jdbcTemplate.queryForInt(query);
      assertEquals("A user already exists in the DB", 0, count);

      User user = new User();
      user.setFirstName("Firstname");

      userDao.saveUser(user);

      // flush the session so we can get the record using JDBC template
      SessionFactoryUtils.getSession(sessionFactory, false).flush();

      count = jdbcTemplate.queryForInt(query);
      assertEquals("User was not found in the DB", 1, count);
  }
}

The test class has to implement the protected String[] getConfigLocations() method from the base class and return a String array of Spring config files which will be used to initialize the Spring context.

UserDao and SessionFactory properties are defined with the setter methods and the base class will take care of injecting them automatically from the Spring context. Auto wiring will not work if there are multiple objects implementing the same interface. In such a case you can remove the setter method and retrieve the object using the exposed applicationContext as below.

   /**
   * Overridden method from base class which gets called automatically
   */
  protected void onSetUpBeforeTransaction() throws Exception {
      super.onSetUpBeforeTransaction();
      userDao = (UserDao) applicationContext.getBean("userDao");
  }

The base class also exposes a JDBC template object (jdbcTemplate) that can be used to query data or setup test data in the database. Note that you need to have a data source and a transaction manager defined in your Spring config in order to use the AbstractTransactionalDataSourceSpringContextTests base class. The data source defined in the config file will be bound to the exposed JDBC template.

In the testSave method first we verify there is no record in the User table where first name equals to ‘Firstname’ using the jdbc template object. Then we call the save method on the UserDao passing it a User object.

Now we simple verify there is a record in the table where first name equals to ‘Firstname’. Before running the query we flush the current Hibernate session to make sure jdbcTemplate can see the newly added record.

Thats it and when the testSave method exits the current transaction will be rolled back and the record inserted to the User table will not be saved. This is great as your test database will always be at a know state at the start and end of a test method.

The spring config file will like below (test-spring-config.xml) :

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>  
    <bean name="userDao" class="com.dao.UserDaoImpl">
       <property name="sessionFactory">
           <ref bean="sessionFactory"/>
       </property>
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
       <property name="dataSource">
           <ref bean="dataSource"/>
       </property>
       <property name="mappingResources">
           <list>
               <value>hibernates/User.hbm.xml</value>
           </list>
       </property>
       <property name="hibernateProperties">
           <props>
               <prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
               <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
           </props>
      </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
       <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
       <property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL" />
       <property name="username" value="test" />
       <property name="password" value="test" />
    </bean>

    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
       <property name="sessionFactory"><ref local="sessionFactory"/></property>
    </bean>

</beans>

Achieve Automatic Transaction Rollback with MockStrutsTestCase and Spring

Spring provides a convenience base class (AbstractTransactionalDataSourceSpringContextTests which extends the TestCase class from Junit) to automatically rollback any updates made to the database at the end of a test method. This works great when integration testing Service and DAO beans but it wont help when integration testing the Struts layer with MockStrutsTestCase.

Spring does not provide a class such as AbstractTransactionalDataSourceSpringContextTests that extends from the MockStrutsTestCase. This might be due to practical issues with the way Spring context initialization works when using MockStrutsTestCase. I tried achieving the transaction rollback in the same way as was done in the AbstractTransactionalDataSourceSpringContextTests class but it didn’t work out as the application code started a new transaction and commited as usual without using the transaction I started in my own subclass of MockStrutsTestCase.

Another option left for me was to go down to the Transaction Manager level and achieve the rollbacks there. The application uses Hibernate at the DAO level and it was using HibernateTransactionManager as the transaction manager implementation when running test cases . Therefore I had to write a new class extending from HibernateTransactionManager which overrides the doCommit() method. The overridden method will call doRollback() method in the super class. This would rollback the current running transaction even if the declarative transaction handling code in Spring calls doCommit on the transaction manager.

package com.xyz.txn;import org.springframework.orm.hibernate3.HibernateTransactionManager;

public class HibernateRollbackTxnManager extends HibernateTransactionManager {

/*

  * doCommit method that calls the doRollback method of the super class.

  *

  */

 protected void doCommit(DefaultTransactionStatus txnStatus) {

     super.doRollback(txnStatus);

 }

}

Finally override the default transaction manager in your test spring bean configuration with the rollback only implementation.

  <bean id="txnManager" class="com.com.xyz.txn.HibernateRollbackTxnManager">

      <property name="sessionFactory"><ref local="sessionFactory"></property>

  </bean>

The same strategy would work with other transaction managers such as DataSourceTransactionManager too.