Archive
How to solve org.apache.lucene.index.CorruptIndexException?
If solr server stops while indexing is going on, we may get org.apache.lucene.index.CorruptIndexException error.
To solve this we have to use org.apache.lucene.index.CheckIndex class. We have to run this class to fix the corrupted indexes in solr.
1. First take back up your indexed data
2. Go to the directory where lucene-core.3.6.1.jar is there
3. then run this command
java -cp lucene-core-3.1.0.jar -ea:org.apache.lucene… org.apache.lucene.index.CheckIndex “your indexed directory path” –fix
in my case it is
java -cp lucene-core-3.1.0.jar -ea:org.apache.lucene… org.apache.lucene.index.CheckIndex “C:\Program Files\gisgraphy-3.0-beta2\solr\data\index” –fix
As there are no corrupted indexes in my case it says “No problems were detected with this index”
If there are any corrupted indexes are there then those will be fixed with this command and solr will be working fine.
Spring AOP explained in simple terms
Aspect Oriented Programming:
Developer has to concentrate on business logic, Cross cutting functionalities like Transactions, Logging, Data Access Logic should be taken care by container.
This principle is called AOP.
Until I have used AOP, I didn’t recognize its worth:
1. Let’s explore the non AOP architecture
package com.java2practice.aop; import java.math.BigDecimal; public class Account { BigDecimal currentAmount = new BigDecimal("5000"); public BigDecimal withdraw(BigDecimal withdrawlAmount){ if(withdrawlAmount.compareTo(currentAmount) < 0 ) return currentAmount.subtract(withdrawlAmount); else throw new FundsNotSufficientException(); } }
Do we have any problem with above withdraw method, if we observe closely?
First we should use logging. Otherwise resolving the errors would be a big problem.
For that we will change the above method accordingly
import java.math.BigDecimal; import org.apache.log4j.Logger; public class Account { Logger logger = Logger.getLogger(Account.class); BigDecimal currentAmount = new BigDecimal("5000"); public BigDecimal withdraw(BigDecimal withdrawlAmount){ logger.info("withdraw method started"); if(withdrawlAmount.compareTo(currentAmount) < 0 ){ return currentAmount.subtract(withdrawlAmount); } else{ throw new FundsNotSufficientException(); } logger.info("withdraw method successfully completed"); } }
Second there is no Transaction started, As withdraw method going update the currentAmount in Database it should be within Transaction so will add transaction.
import java.math.BigDecimal; import org.apache.log4j.Logger; import org.hibernate.Session; import org.hibernate.Transaction; public class Account { Logger logger = Logger.getLogger(Account.class); BigDecimal currentAmount = new BigDecimal("5000"); public BigDecimal withdraw(BigDecimal withdrawlAmount){ Transaction tx = null; Session session = getCurrentSession(); try{ logger.info("withdraw method started"); if(withdrawlAmount.compareTo(currentAmount) < 0 ){ tx = session.beginTransaction(); currentAmount = currentAmount.subtract(withdrawlAmount); tx.commit(); return currentAmount; } else{ tx.rollback(); logger.debug("FundsNotSufficientException :: withdraw method failed"); throw new FundsNotSufficientException(); } logger.info("withdraw method successfully completed"); }catch(Exception ex){ tx.rollback() logger.debug("withdraw method failed"); } } }
Now we implemented Transactions and logging successfully but what we are doing if any new requirement is coming we are changing the BankAccount class which is against Object Oriented principle.
If we think again there should be data access logic for the Bank Account class then we have to change once again the class to like this:
package com.java2practice.aop; import java.math.BigDecimal; import org.apache.log4j.Logger; import org.hibernate.Session; import org.hibernate.Transaction; public class Account { Logger logger = Logger.getLogger(Account.class); BigDecimal currentAmount = new BigDecimal("5000"); public BigDecimal withdraw(BigDecimal withdrawlAmount){ logger.info("withdraw method started"); Transaction tx = null; Session session = getCurrentSession(); try{ if(currentUser.isWIthdrawEnabled()){ if(withdrawlAmount.compareTo(currentAmount) < 0 ){ tx = session.beginTransaction(); currentAmount = currentAmount.subtract(withdrawlAmount); tx.commit(); return currentAmount; } else{ tx.rollback(); logger.debug("FundsNotSufficientException :: withdraw method failed"); throw new FundsNotSufficientException(); } logger.info("withdraw method successfully completed"); }else { logger.info("withdraw method Failed withdrawal is disabled for this user"); } }catch(Exception ex){ tx.rollback(); logger.debug("withdraw method failed"); } } }
Now it looks fine, but in future any new cross cutting functionality comes, we need to change the Bank Account class once again. What if we separate the cross cutting functionalities like Logging, Security, Transaction to outside of the business logic then we can add new cross cutting functionality without touching BankAccount class.
Imagine if the Data access logic changes, we may need to change lot of files. Same with the entire cross cutting functionalities, They should not be coupled with the business logic and should be defined separately. This we can achieve through Spring AOP.
2. Will see the AOP architecture:
For Cross cutting functionality Logging will see the AOP architecture
- CustomerDAO.java
package com.java2practice.dao; public interface CustomerDAO { String addCustomer(); String addCustomerReturnValue() void addCustomerThrowException() throws Exception; void addCustomerAround(String name); }
- CustomerDAOImpl.java
package com.java2practice.dao.impl; import com.java2practice.dao.CustomerDAO; public class CustomerDAOImpl implements CustomerDAO { public String addCustomer(){ System.out.println("addCustomer() is running "); //throw new ArithmeticException(); return "ramesh"; } public String addCustomerReturnValue(){ System.out.println("addCustomerReturnValue() is running "); return "abc"; } public void addCustomerThrowException() throws Exception { System.out.println("addCustomerThrowException() is running "); throw new Exception("Generic Error"); } public void addCustomerAround(String name){ System.out.println("addCustomerAround() is running, args : " + name); } }
Here logging will be implemented by AOP, for that we need to write an Aspect.
- LoggingAspect.java
package com.java2practice.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class LoggingAspect { @Before("execution(* com.java2practice.dao.*.*(..))") public void logBefore(JoinPoint joinPoint) { System.out.println(joinPoint.getSignature().getName()+" is started! from logBefore"); } @After("execution(* com.java2practice.dao.*.*(..))") public void logAfter(JoinPoint joinPoint){ System.out.println(joinPoint.getSignature().getName()+" is completed! from logAfter"); } @AfterThrowing(pointcut = "execution(* com.java2practice.dao.CustomerDAO.*(..))", throwing= "error") public void logAround(JoinPoint joinPoint, Object error){ System.out.println(joinPoint.getSignature().getName()+" after throwing called! from after throwing "+error); } @AfterReturning( pointcut = "execution(* com.java2practice.dao.CustomerDAO.addCustomerReturnValue(..))", returning= "result") public void afterReturning(JoinPoint joinPoint, Object result){ System.out.println("after returning called result: "+result); } @Around("execution(* com.java2practice.dao.CustomerDAO.addCustomerAround(..))") public void logAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("Around before is running!"); if(joinPoint.getArgs()[0].equals("ramesh")){ joinPoint.proceed(); //continue on the intercepted method System.out.println("Around after is running!"); } else{ System.out.println("you dont have permission to call this method"); } } }
- @Aspect annotation will tells the container it is an Aspect
- @Before(“execution(* com.java2practice.dao.*.*(..))”) — it will be executed before any method executes in com.java2.practice.dao package
- @After(“execution(* com.java2practice.dao.*.*(..))”) — it will be executed after any method execution in com.java2.practice.dao package
- @AfterThrowing(pointcut = “execution(* com.java2practice.dao.CustomerDAO.*(..))”, throwing= “error”) — It will be executed if any method throws any exception in com.java2practice.dao.CustomerDAO class and the error will be captured in “error”.
- @AfterReturning( pointcut = “execution(* com.java2practice.dao.CustomerDAO.addCustomerReturnValue(..))”, returning= “result”) – it will be executed if com.java2practice.dao.CustomerDAO.addCustomerReturnValue() method returns any value and the returned value will be stored in “result”.
- @Around(“execution(* com.java2practice.dao.CustomerDAO.addCustomerAround(..))”) – This is very powerful l aspect, it will be executed before the method execution and after the method execution. Even we can control the method execution by joinPoint.proceed()
So now will write spring-config.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <aop:aspectj-autoproxy /> <bean id="customerDAO" /> <!-- Aspect --> <bean id="logAspect" /> </beans>
Finally will write Main program to see the power of AOP.
package com.java2practice.aspect; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.java2practice.dao.CustomerDAO; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); CustomerDAO customer = (CustomerDAO) context.getBean("customerDAO"); try { //customer.addCustomer(); customer.addCustomerAround("ramesh"); //customer.addCustomerReturnValue(); //customer.addCustomerThrowException(); } catch (Exception e) { //e.printStackTrace(); } } }
Have fun with AOP.