Sunday, December 6, 2009

Search engine framework "compass"

Now a days search in web application brings you good user experience & save time.
Compass is a powerful, transactional Java Search Engine framework. Java bean mostly used in all enterprise application. Compass allow us to map our java bean to underlying search engine, sync data between compass index and datasource[persistence].

The following is the implementation of compass search in core java. Compass supports for some ORM like hibernate, iBatis.

1) Create java project & add compass jar to your lib.

2) Create a bean called "User.java"

User.java:

@Searchable(alias="user")
public class User {

private Long id;
private String name;
private Integer yearsExperience;
private Float income;

public User() {
}

public User(Long id, String name, Integer yearsExperience, Float income) {
this.id = id;
this.name = name;
this.yearsExperience = yearsExperience;
this.income = income;
}

@SearchableId
public Long getId() {
return id;
}

@SearchableProperty()
public Float getIncome() {
return income;
}

@SearchableProperty()
public String getName() {
return name;
}

@SearchableProperty()
public Integer getYearsExperience() {
return yearsExperience;
}
}


@Searchable() annotation, tells to compass that User object to be indexed.
@SearchableId() annotation, to mention unique id to refer the object.
@SearchableProperty() annotation, helps to what are the property to be index

3) indexUser(Compass) method used to index the user object.

public static void index(Compass compass) {

CompassSession session = compass.openSession();

User user1 = new User(2l, "jp" , 100, 140000.0f);

CompassTransaction tx = session.beginTransaction();

session.save(user1);


tx.commit();
session.close();
}


This method cache the user1 object to memory.

4) searchUser(Compass) method to search user1 object.

public static void searchUser(Compass compass) {
CompassSession session = compass.openSession();
CompassTransaction tx = session.beginLocalTransaction();

CompassQueryBuilder cqb = session.queryBuilder();

CompassHits hits = cqb.bool()
.addMust(cqb.alias("user"))
.addMust(cqb.term("name", "jp"))
.toQuery().hits();

for(CompassHit hit : hits) {
User usr = (User)hit.data();
System.out.println(usr.getName()+"-"+usr.getYearsExperience+"-"+usr.getIncome);
System.out.println("hits="+hit.getScore());
}

tx.commit();
session.close();
}

we need to create compass session, transaction & query builder. Then get the hits from query builder.
.addMust(cqb.alias("user") line get the user object with help of alias. If we have relational bean this alias help us to search particular object like user, address, customer.

5) Finally main() to index the user object and search the same


public static void main( String[] args ) {
CompassConfiguration cfg = new CompassConfiguration();
cfg.configure();

Compass compass = cfg.buildCompass();

index(compass);
searchUser(compass);

}

Output is
jp-100-140000.0
hits= 1
Hits is 1, because our criteria matched for only one object.
Here user1 object index to the memory and searched back from the same. As data grows we can't keep it in memory. In that case we can index objects to file system.


Thursday, December 3, 2009

javascript submitting form twice

I have form with hidden fields. When i do change the country select box, taking the value of select box  & updating  the same in hidden field. When i hit the search button to search countries, i am submitting the form using javascript.

My code:

<a href="#" onclick="submitMyForm();">Search</a>

I was wondering this javascript submitted this form twice. First time with the value in the hidden box and second time with out.

We found out the problem with my javascript code. 

Correct code:

<a href="#" onclick="submitMyForm();return false;">Search</a>

So "return false;" did trick for me.

Have fun

Wednesday, July 1, 2009

Password protected application in tomcat server

We can do container level authentication in tomcat server. Tomcat support three types of authentication. DataSourceRealm, JDBCRealm, JNDIRealm, MemoryRealm. For more detail...

we will see implementation of "MemoryRealm". This uses XML file as the source to maintain the username and password.

You can see /conf/tomcat-users.xml file contains the username, password and roles.

Step 1:
You can add new user and roles as follows
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="manager"/>
<role rolename="admin"/>
<role rolename="ananymous">
<user username="tomcat" password="tomcat" roles="manager,admin"/>
<user username="newuser" password="password" roles="ananymous"/>
</tomcat-users>


Step 2:
Next thing Enable MemoryRealm in the <tomcat-home>/conf/server.xml file.
By default UserDatabaseRealm is enabled. Comment out this and add the add the MemoryRealm <Realm className="org.apache.catalina.realm.MemoryRealm" />

Step 3:
Have to add the security-constraint in our application's web.xml file. Assume that we have deployed "webapplication1" in tomcat[<tomcat-home>/webapp/webapplication1].
We need to add following security-constraint in <tomcat-home>/webapp/webapplication1/WEB-INF/web.xml.

<security-constraint>
<web-resource-collection>
<web-resource-name>Tomcat User authentication</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>anonymous</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Tomcat User authentication</realm-name>
</login-config>

Role <role-name>anonymous</role-name> applied for all request comes to the webapplication1 for the url-pattern <url-pattern>/*</url-pattern>.

If tomcat container encounter the security-constraint in the web.xml for the given request, it add the authentication header in the response. So broswer popups the window to receive username and password.

IF username and password matches in the tomcat-users.xml, container allow the access the resource.

<auth-method>BASIC</auth-method> defines the authentication method to define the Realm. The possible values are BASIC, DIGEST and FORM.

If our application uses some other security, tomcat MemoryRealm may give issues.


Thursday, June 18, 2009

How to change OS boot priority in Ubuntu

Login as root user.
edit the following file
/boot/grub/mentu.lst

you could see list of all installed OS here as follows:
Note: I have installed Ubuntu and XP in my machine

title
Ubuntu 8.10, kernel 2.6.27-7-generic
uuid
1d034dd4-58c3-4ae9-abc0-c1b5e4591639
kernel /boot/vmlinuz-2.6.27-7-generic root=UUID=1d034dd4-58c3-4ae9-abc0-c1b5e4591639 ro quiet splash

initrd
/boot/initrd.img-2.6.27-7-generic

title
Ubuntu 8.10, kernel 2.6.27-7-generic (recovery mode)
uuid
....
kernel
....

title
Ubuntu 8.10, memtest86+
uuid
....
kernel
....

title
Other operating systems:
root
....

title
Microsoft Windows XP Home Edition
root
....

The id start from 0.
i.e.
0 = Ubuntu 8.10, kernel 2.6.27-7-generic
1 = Ubuntu 8.10, kernel 2.6.27-7-generic (recovery mode)
2 = Ubuntu 8.10, memtest86+
3 = Other operating systems:
4 = Microsoft Windows XP Home Edition

The following line is taking care of which OS to boot by default

default 0

this means by default Ubuntu 8.10, kernel 2.6.27-7-generic will be booted

If we want to boot XP as default, change this line to

default 4

save the file. When you boot next time by default XP will be booted.

Tuesday, June 16, 2009

java UnsupportedClassVersionError

While deploy java code into tomcat, it thrown exception as follows

SEVERE: Exception starting filter struts
java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class jcaptcha4struts2.core.actions.support.CaptchaImageResult)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal( WebappClassLoader.java:1851)
at org.apache.catalina.loader.WebappClassLoader.findClass( WebappClassLoader.java:890)
.......
.......
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
17 Mar, 2009 1:29:25 PM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext

The problem is version conflict [development machine java version is 1.5 but machine where i deploy has the 1.6 version]

To fix this problem we need to install java-1.6 version in the deployment machine.

Monday, June 15, 2009

JSP form getting submitted twice

When i was working in the struts2,hibernate and spring technology, strangely "null pointer exception" thrown for attribute which used in the form even i give valid input.

I dig this issue and found that, struts action called twice when i request for the URL. Again this also crazy for me. When debug the application, found that browser sending new request if any empty 'src' in the <img> tag present in the code.

code

<img src="">

In our case browser sent second request with empty form[no data] . so obviously "null pointer exception".

so take out or give the valid image src name and this will fix the problem.