top-image

LATEST ARTICLES

Hi,

After my last post presenting an example about the annotation in JAVA Java : Annotation : Example of validation with annotation (mandatory, target, maxlength…) I would expose another example of JAVA annotation and AOP to measure performance and time processing on server side.

In a previous article Java/Spring: Measure performance and time processing with AOP on server side, I presented a solution allowing a detailed report of performance based on AOP technologies.


  1. Technologies
    So, our solution is based on:

    • an annotation PerformanceWatcher specifying the class, interface or enum whose the performace must be measured and an admissible threshold (warning duration),
      /**
       * Specify the class, interface or enum whose the performace must be measured and an admissible threshold (warning duration).
       * @author huseyin
       */
      // RetentionPolicy.RUNTIME : Annotations are to be recorded in the class file by the compiler 
      //			and retained by the VM at runtime, so they may be read reflectively.
      // ElementType.TYPE : Class, interface (including annotationtype) or enum declaration
      @Retention(RetentionPolicy.RUNTIME) 
      @Target(ElementType.TYPE)
      public @interface PerformanceWatcher {
      	long msDurationWarning() default 1000;
      }
      
    • an AOP AspectJ AspectPerformanceWatcher applying on the elements annotated by the annotation PerformanceWatcher to check if the execution time of a method for this element exceeds the specified admissible threshold (warning duration). This aspect AOP “Arround” allows the calculation of the execution time of a method and add a trace in the logs via méhode “calculatePerformance”.
      @Component
      @Aspect
      @Order(5)
      public class AspectPerformanceWatcher {
      
      	private static Log log = LogFactory.getLog(AspectPerformanceWatcher.class);
      		
      	@SuppressWarnings("unchecked")
      	@Around("within(@com.ho.test.perf.measure.annotations.PerformanceWatcher *)")
      	public Object calculatePerformance(ProceedingJoinPoint pjp) throws Throwable{
      		final long start = System.currentTimeMillis();
      			
      		// Execution of target method
      		final Object result = pjp.proceed();
      			
      		final long duration = System.currentTimeMillis() - start;
      			
      		// Get the definition of annotation and of this admissible threshold (warning duration)
      		final PerformanceWatcher performanceWatcher = (PerformanceWatcher) pjp.getSourceLocation().getWithinType().getAnnotation(PerformanceWatcher.class);
      			
      		// Check if the method's execution time exceeds the admissible threshold
      		if(performanceWatcher != null && performanceWatcher.msDurationWarning() < duration){
      				log.warn("**** THE METHOD "+pjp.getSignature().getName()+" FROM "+pjp.getSignature().getDeclaringTypeName()+" TOOK "+duration+ " MS (max"+performanceWatcher.msDurationWarning()+"ms). ****");
      		}//end-if
      		
      		return result;
      	}
      }
      

    To illustrate our previous explanations, we will create a Java project with:

    • a Spring context defined in a XML file spring-business-config.xml,
    • a singleton named ApplicationContextContainer which will give an access to the Spring context (see my post on this topic Access to Spring context in all places or layers of an application),
    • a mock HIBERNATE persistence layer with the classes Business1DaoHibernateImpl, Business2DaoHibernateImpl,
    • a mock JDBC persistence layer with the class JdbcUtilsServiceImpl,
    • a simple test class named PerfMeasureTestAnnot,
    • the JARs aspectjrt-1.5.4.jar, aspectjtools-1.5.4.jar, aspectjweaver-1.5.4.jar, cglib-2.2.2.jar, commons-logging-1.1.1.jar, spring-2.5.6.jar and standard.jar (version 1.1.2).

    More, in our project, the execution/processing time of methods to monitor in the persistence layers (Hibernate and JDBC) will be random between 1 second and 5 seconds:

    • in the methods saveOrUpdate(), save(), update() and delete() of the classes Business1DaoHibernateImpl and Business2DaoHibernateImpl,
    • in the method executeQuery(String sql) in the class JdbcUtilsServiceImpl,
    /**
     * Returns a number in milliseconds between 1000 (1sec) and 5000 (5sec)
     * @return
     */
    public static long getRandomSleepTime(){
    	int lower = 1000;
    	int higher = 5000;
    
    	long random = (long)(Math.random() * (higher-lower)) + lower;
    	return random;
    }
    

  2. Spring context
    The Spring context is defined in a XML file spring-business-config.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans
    	xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:util="http://www.springframework.org/schema/util"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="
    
    http://www.springframework.org/schema/beans
    
    
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    
    
    http://www.springframework.org/schema/context
    
    
    http://www.springframework.org/schema/context/spring-context-2.5.xsd
    
    
    http://www.springframework.org/schema/util
    
    
    http://www.springframework.org/schema/util/spring-util-2.0.xsd
    
    
    http://www.springframework.org/schema/aop
    
    
    http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <!-- To enable AOP -->
    <aop:aspectj-autoproxy/>
    
    <!-- Search annotations (@Autowired in particular) -->
    <context:annotation-config/>
    <context:component-scan base-package="com.ho.test.perf.measure"/>
    
    <!-- Aspects -->
    <bean id="aspectPerformanceWatcher" class="com.ho.test.perf.measure.annotations.AspectPerformanceWatcher"/>
    
    <!-- PERSISTENCE LAYER JBDC SQL MOCK -->
    <bean name="JdbcUtilsServiceImpl" class="com.ho.test.perf.measure.commons.jdbc.JdbcUtilsServiceImpl"/> 
    
    <!-- PERSISTENCE LAYER DAO HIBERNATE MOCK -->
    <bean name="Business1DaoHibernateImpl" class="com.ho.test.perf.measure.commons.dao.hibernate.Business1DaoHibernateImpl"/>
    <bean name="Business2DaoHibernateImpl" class="com.ho.test.perf.measure.commons.dao.hibernate.Business2DaoHibernateImpl"/>
    
    </beans>
    

    … and singleton ApplicationContextContainer:

    public class ApplicationContextContainer {
    	
        // ------------------------------------------------------------------ LOG4J
    	private static Log log = LogFactory.getLog(ApplicationContextContainer.class);
    
        // -------------------------------------------------------------- CONSTANTS
    	private final static String SPRING_BUSINESS_CONFIG_XML = "spring-business-config.xml";
        
    
        // ----------------------------------------------------- PRIVATE ATTRIBUTES
        /**
         * Instance
         */
        private static ApplicationContextContainer instance = null;
        
        /**
         * Contains the spring configuration.
         */
        private ClassPathXmlApplicationContext ctx = null;
    
        // ------------------------------------------------------------- EXCEPTIONS
        // ------------------------------------------------------- INTERNAL CLASSES
        // ----------------------------------------------------------- CONSTRUCTORS
        private ApplicationContextContainer() {}
        // --------------------------------------------------------- PUBLIC METHODS
        
        /**
         * Getinstance method.
         */
        public static synchronized ApplicationContextContainer getInstance() {
            return getInstance(SPRING_BUSINESS_CONFIG_XML);
        }
        public static synchronized ApplicationContextContainer getInstance(String springContextFile) {
        	if (null == instance) {
        		instance = new ApplicationContextContainer();
        		instance.ctx = new ClassPathXmlApplicationContext();  
        		instance.ctx.setConfigLocation(springContextFile);
        		instance.ctx.refresh();
            } // end-if
            return instance;
        }
        
        /**
         * Retrieve the spring bean corresponding to the given key.
         * @param key
         * @return
         */
        public static Object getBean(String key) {
            return getInstance().ctx.getBean(key);
        }
        
        public ClassPathXmlApplicationContext getContext() {
            return ctx;
        }
        
        
    
    	/**
    	 * Returns a number in milliseconds between 1000 (1sec) and 5000 (5sec)
    	 * @return
    	 */
    	public static long getRandomSleepTime(){
    		int lower = 1000;
    		int higher = 5000;
    
    		long random = (long)(Math.random() * (higher-lower)) + lower;
    		return random;
    	}
    }
    

  3. Classes to monitor
    JdbcUtilsServiceImpl: This classes is monitored and contains an annotation @PerformanceWatcher(msDurationWarning=3500).

    @PerformanceWatcher(msDurationWarning=3500)
    public class JdbcUtilsServiceImpl implements IJdbcUtils {
    	// ----------------------------------------------------- PRIVATE ATTRIBUTES
    	private static Log log = LogFactory.getLog(JdbcUtilsServiceImpl.class);
    
    	// --------------------------------------------------------- PUBLIC METHODS
    	/**
    	 * Execute query.
    	 * @param sql the sql
    	 * @return the query execution result as a List
    	 */
    	public List executeQuery(String sql) {
    		log.info("JdbcUtilsServiceImpl:executeQuery START");
    		try {
    			Thread.currentThread().sleep(ApplicationContextContainer.getRandomSleepTime());
    		} catch(Throwable th){
    		}
    		log.info("JdbcUtilsServiceImpl:executeQuery END");
    		return new ArrayList();
    	}
     }
    

    Business1DaoHibernateImpl: This classes is monitored and contains an annotation @PerformanceWatcher(msDurationWarning=2000).

    @PerformanceWatcher(msDurationWarning=2000)
    public class Business1DaoHibernateImpl implements IBusiness1 {
    	
    	private static Log log = LogFactory.getLog(Business1DaoHibernateImpl.class);
    	
    	/**
    	 * Save or update object into database.
    	 */
    	public void saveOrUpdate() {
    		log.info("Business1DaoHibernateImpl:saveOrUpdate START");
    		try {
    			Thread.currentThread().sleep(ApplicationContextContainer.getRandomSleepTime());
    		} catch(Throwable th){
    		}
    		log.info("Business1DaoHibernateImpl:saveOrUpdate END");
    	}
    //...
    }
    

    Business2DaoHibernateImpl: This classes is monitored and contains an annotation @PerformanceWatcher(msDurationWarning=3000).

    @PerformanceWatcher(msDurationWarning=3000)
    public class Business2DaoHibernateImpl implements IBusiness2 {
    	
    	private static Log log = LogFactory.getLog(Business2DaoHibernateImpl.class);
    	
    	/**
    	 * Save or update object into database.
    	 */
    	public void saveOrUpdate() {
    		log.info("Business2DaoHibernateImpl:saveOrUpdate START");
    		try {
    			Thread.currentThread().sleep(ApplicationContextContainer.getRandomSleepTime());
    		} catch(Throwable th){
    		}
    		log.info("Business2DaoHibernateImpl:saveOrUpdate END");
    	}
    //...
    }
    

  4. Tests
    The project in attachement contains a test class named PerfMeasureAnnotTest:

    public class PerfMeasureAnnotTest {
    	
    	public static void main(String[] args) {
    		
    		ApplicationContextContainer context = ApplicationContextContainer.getInstance();
    		
    		IJdbcUtils jdbcUtils = (IJdbcUtils) context.getBean("JdbcUtilsServiceImpl");
    		IBusiness1 business1 = (IBusiness1) context.getBean("Business1DaoHibernateImpl");
    		IBusiness2 business2 = (IBusiness2) context.getBean("Business2DaoHibernateImpl");
    
    		{
    			jdbcUtils.executeQuery("");
    			//
    			business1.delete();
    			business1.save();
    			business1.saveOrUpdate();
    			business1.update();
    			//
    			business2.delete();
    			business2.save();
    			business2.saveOrUpdate();
    			business2.update();
    		}//end-for
    		
    	}
    }
    

    … os, the outputs in console could be:

    10 avr. 2014 23:23:53 com.ho.test.perf.measure.commons.jdbc.JdbcUtilsServiceImpl executeQuery
    INFO: JdbcUtilsServiceImpl:executeQuery START
    10 avr. 2014 23:23:57 com.ho.test.perf.measure.commons.jdbc.JdbcUtilsServiceImpl executeQuery
    INFO: JdbcUtilsServiceImpl:executeQuery END
    10 avr. 2014 23:23:57 com.ho.test.perf.measure.commons.dao.hibernate.Business1DaoHibernateImpl delete
    INFO: Business1DaoHibernateImpl:delete START
    10 avr. 2014 23:23:58 com.ho.test.perf.measure.commons.dao.hibernate.Business1DaoHibernateImpl delete
    INFO: Business1DaoHibernateImpl:delete END
    10 avr. 2014 23:23:58 com.ho.test.perf.measure.commons.dao.hibernate.Business1DaoHibernateImpl save
    INFO: Business1DaoHibernateImpl:save START
    10 avr. 2014 23:24:00 com.ho.test.perf.measure.commons.dao.hibernate.Business1DaoHibernateImpl save
    INFO: Business1DaoHibernateImpl:save END
    10 avr. 2014 23:24:00 com.ho.test.perf.measure.commons.dao.hibernate.Business1DaoHibernateImpl saveOrUpdate
    INFO: Business1DaoHibernateImpl:saveOrUpdate START
    10 avr. 2014 23:24:04 com.ho.test.perf.measure.commons.dao.hibernate.Business1DaoHibernateImpl saveOrUpdate
    INFO: Business1DaoHibernateImpl:saveOrUpdate END
    10 avr. 2014 23:24:04 com.ho.test.perf.measure.annotations.AspectPerformanceWatcher calculatePerformance
    ATTENTION: **** THE METHOD saveOrUpdate FROM com.ho.test.perf.measure.commons.dao.hibernate.IBusiness1 TOOK 3855 MS (max2000ms). ****
    10 avr. 2014 23:24:04 com.ho.test.perf.measure.commons.dao.hibernate.Business1DaoHibernateImpl update
    INFO: Business1DaoHibernateImpl:update START
    10 avr. 2014 23:24:08 com.ho.test.perf.measure.commons.dao.hibernate.Business1DaoHibernateImpl update
    INFO: Business1DaoHibernateImpl:update END
    10 avr. 2014 23:24:08 com.ho.test.perf.measure.annotations.AspectPerformanceWatcher calculatePerformance
    ATTENTION: **** THE METHOD update FROM com.ho.test.perf.measure.commons.dao.hibernate.IBusiness1 TOOK 4895 MS (max2000ms). ****
    10 avr. 2014 23:24:08 com.ho.test.perf.measure.commons.dao.hibernate.Business2DaoHibernateImpl delete
    INFO: Business2DaoHibernateImpl:delete START
    10 avr. 2014 23:24:10 com.ho.test.perf.measure.commons.dao.hibernate.Business2DaoHibernateImpl delete
    INFO: Business2DaoHibernateImpl:delete END
    10 avr. 2014 23:24:10 com.ho.test.perf.measure.commons.dao.hibernate.Business2DaoHibernateImpl save
    INFO: Business2DaoHibernateImpl:save START
    10 avr. 2014 23:24:11 com.ho.test.perf.measure.commons.dao.hibernate.Business2DaoHibernateImpl save
    INFO: Business2DaoHibernateImpl:save END
    10 avr. 2014 23:24:11 com.ho.test.perf.measure.commons.dao.hibernate.Business2DaoHibernateImpl saveOrUpdate
    INFO: Business2DaoHibernateImpl:saveOrUpdate START
    10 avr. 2014 23:24:16 com.ho.test.perf.measure.commons.dao.hibernate.Business2DaoHibernateImpl saveOrUpdate
    INFO: Business2DaoHibernateImpl:saveOrUpdate END
    10 avr. 2014 23:24:16 com.ho.test.perf.measure.annotations.AspectPerformanceWatcher calculatePerformance
    ATTENTION: **** THE METHOD saveOrUpdate FROM com.ho.test.perf.measure.commons.dao.hibernate.IBusiness2 TOOK 4213 MS (max3000ms). ****
    10 avr. 2014 23:24:16 com.ho.test.perf.measure.commons.dao.hibernate.Business2DaoHibernateImpl update
    INFO: Business2DaoHibernateImpl:update START
    10 avr. 2014 23:24:19 com.ho.test.perf.measure.commons.dao.hibernate.Business2DaoHibernateImpl update
    INFO: Business2DaoHibernateImpl:update END
    10 avr. 2014 23:24:19 com.ho.test.perf.measure.annotations.AspectPerformanceWatcher calculatePerformance
    ATTENTION: **** THE METHOD update FROM com.ho.test.perf.measure.commons.dao.hibernate.IBusiness2 TOOK 3034 MS (max3000ms). ****
    

For more informations, you could contact me.

Download: testPerfMeasureAnnot.zip

Best regards,

Huseyin OZVEREN

Hello,

I would present you an example concerning the annotation in JAVA: validation POJO with annotation.

Brief presentation
Introduced with Java SE 5, the annotations are more increasingly used in the development of applications. Annotations provide informations about a class and they have no direct effect on the annotated code. Annotations can be preserved at runtime (RetentionPolicy.RUNTIME) or are only available at development time, during the compile (RetentionPolicy.SOURCE).

There are standard annotations and Java allows the definition of custom annotations.

For example, the following standard annotations are often used in Java:
@Override:
This annotation added to a method, notifies the Java compiler to check if the annotated method really overrides a method of an interface or the extended class.

@Override
public String toString(){
	return this.getClass().getName()
			+ "[id="+id
			+ ", name="+name
			+ ", price="+price
			+ ", numberOfRead="+numberOfRead
			+ ", lastReadDateTime="+lastReadDateTime
			+ ", authors="+authors
			+ "]";
}

@Deprecated
This annotation added to a field, method or constructor, indicates that the annotated element should not be used anymore. It is possible to add this annotation to a class, however, this doesn’t deprecate automatically all its fields and methods.

@Target
This annotation specifies where it is legal to use an annotation type. The possible values are constants from the
java.lang.annotation.ElementType enumeration which provides a simple classification of the declared elements in a Java program.
There are the following constants:

  • ANNOTATION_TYPE – Annotation type declaration – used for other annotations.
    @MyAnnotation
    public @interface AnotherAnnotation {..}
    
  • CONSTRUCTOR – Constructor declaration
    public class MyAnnotatedClass {
        @MyAnnotation
        public MyAnnotatedClass() {..}
    }
    
  • FIELD – Field declaration (includes enum constants)
    @MyAnnotation
    private String myAnnotatedField;
    
  • LOCAL_VARIABLE – Local variable declaration – It can’t be read at runtime, so it is used only for compile-time things, like the @SuppressWarnings annotation.
    public void someMethod() {
        @MyAnnotation int myLocalVariable = 0;
    }
    
  • METHOD – Method declaration
    @MyAnnotation
    public void myAnnotatedMethod() {..}
    
  • PACKAGE – Package declaration
    @MyAnnotation
    package com.ho.myannotatedpackage;
    
  • PARAMETER – Parameter declaration
    public void myMethod(@MyAnnotation param) {..}
    
  • TYPE – Class, interface (including annotation type), or enum declaration
    @MyAnnotation
    public class MyAnnotatedClass {..}
    

It is possible to specify multiple ElementTypes for a given annotation:

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})

Example : validation with annotations

When an annotation is implemented, it is necessary to tell two things to the compiler:

  • where it can be applied (that’s the @Target annotation);
  • what its retention policy is (aptly named @RetentionPolicy; some annotations are kept only at the source level, others at runtime).

Below, the official description of annotations retention policy:

+ RetentionPolicy.SOURCE: Discard during the compile. These annotations don't make any sense after the compile has completed, so they aren't written to the bytecode.
 Example: @Override, @SuppressWarnings

+ RetentionPolicy.CLASS: Discard during class load. Useful when doing bytecode-level post-processing. Somewhat surprisingly, this is the default.

+RetentionPolicy.RUNTIME: Do not discard. The annotation should be available for reflection at runtime. Example: @Deprecated

In our example, we will use the annotations with the JDK 1.6 for validate the POJO values on two criterias ans set its name:

  • an annotation Mandatory to specify if a field is mandatory or not,
  • an annotation MaxLength to specify the max length of a String field,
  • an annotation FiledName to set the field’s name,



STEP 1
Create a new project named test_annot_valid with the following librairies in test_annot_valid\lib folder:

  • commons-beanutils-1.9.0.jar,
  • commons-lang-2.6.jar,
  • commons-logging-1.1.3.jar,

For information, our project structure will be:
test_annot_valid-scr1



STEP 2
We will create the definition of new annotations by creating 3 new classes in the package “com.ho.annotations.common.annotations”:

FieldName:

package com.ho.annotations.common.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldName {
	
	EnumFieldName name();
	
	public enum EnumFieldName{
		ID,
		NAME,
		PRICE,
		LAST_READ_DATETIME,
		NB_OF_READ,
		AUTHORS
		;
	}
}

Mandatory:

package com.ho.annotations.common.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
 * Marks the field as Mandatory : a null value is illegal.
 * @author huseyin
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Mandatory {

}

Maxlength:

package com.ho.annotations.common.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Specify the maximum length of the annotated field.
 * @author huseyin
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MaxLength {
	int maxLength();
}



STEP 3
Then, it is necessary to create POJO on whom the previous annotations must be applied. The class AbstractEntity will contain a list of errors corresponding to validation errors:

package com.ho.annotations.data.entity;

import java.util.ArrayList;
import java.util.List;

public abstract class AbstractEntity {

	// ------------------------- PROTECTED ATTRIBUTES
	protected List<ErrorEntity> errors = new ArrayList<ErrorEntity>();
	
	// ------------------------------- PUBLIC METHODS
	public void addError(ErrorEntity error){
		this.errors.add(error);
	}
	
	public void addErrors(List<ErrorEntity> errors){
		this.errors.addAll(errors);
	}
	
	public boolean hasError(){
		return errors!=null && errors.size()>0;
	}
	
	public List<ErrorEntity> getErrors(){
		List<ErrorEntity> result = new ArrayList<ErrorEntity>();
		for(ErrorEntity error : errors){
			result.add(error);
		}//end-for
		return result;
	}
}

And an error entity ErrorEntity class representing one error that occured when validating the object:

package com.ho.annotations.data.entity;

import com.ho.annotations.common.annotations.FieldName;

/**
 * Entity class representing one error that occured when validating the object
 * @author huseyin
 *
 */
public class ErrorEntity extends AbstractEntity{
	
	public static enum ErrorLevel{
		ERROR,
		WARNING,
		INFO,
		;
	}
	
	// --------------------------- PRIVATE ATTRIBUTES
	private Integer id;
	private FieldName.EnumFieldName enumFieldName;
	private String error;
	private Integer entityId;
	private ErrorLevel errorLevel;
	
	// ---------------------------------- CONSTRUCTOR
	public ErrorEntity(){}
	
	public ErrorEntity(FieldName.EnumFieldName enumFieldName, String error){
		this.enumFieldName = enumFieldName;
		this.error = error;
		this.errorLevel = ErrorLevel.ERROR;
	}
	
	public ErrorEntity(FieldName.EnumFieldName enumFieldName, String error, ErrorLevel errorLevel){
		this.enumFieldName = enumFieldName;
		this.error = error;
		this.errorLevel = errorLevel;
	}
	
	// ---------------------------- PUBLIC ATTRIBUTES
	@Override
	public String toString(){
		StringBuilder errorBuilder = new StringBuilder();
		errorBuilder.append(getEnumFieldName());
		errorBuilder.append(" ");
		errorBuilder.append(getError());
		return errorBuilder.toString();
	}
	
	
	// --------------------------------- GET/SET TERS
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public FieldName.EnumFieldName getEnumFieldName() {
		return enumFieldName;
	}

	public void setEnumFieldName(FieldName.EnumFieldName enumFieldName) {
		this.enumFieldName = enumFieldName;
	}

	//...etc.
	
	// ------------------------- PROTECTED ATTRIBUTES
}

Finally, the entity class BookEntity will be validated:

package com.ho.annotations.data.entity;

import java.util.Calendar;

import com.ho.annotations.common.annotations.FieldName;
import com.ho.annotations.common.annotations.Mandatory;
import com.ho.annotations.common.annotations.MaxLength;

/**
 * Entity mapping the table BOOK
 * @author huseyin
 *
 */
public class BookEntity extends AbstractEntity{

	// --------------------------- PRIVATE ATTRIBUTES
	// ID
	@Mandatory
	@FieldName(name=FieldName.EnumFieldName.ID)
	private Integer id;

	// NAME
	@Mandatory
	@MaxLength(maxLength = 10)
	@FieldName(name=FieldName.EnumFieldName.NAME)
	private String name;

	// PRICE
	@Mandatory
	@FieldName(name=FieldName.EnumFieldName.PRICE)
	private Double price;
	
	// NB_OF_READ
	@FieldName(name=FieldName.EnumFieldName.NB_OF_READ)
	private Integer numberOfRead;

	// LAST_READ_DATETIME
	@FieldName(name=FieldName.EnumFieldName.LAST_READ_DATETIME)
	private Calendar lastReadDateTime;

	// AUTHORS
	@FieldName(name=FieldName.EnumFieldName.AUTHORS)
	private String[] authors;
	
	// ---------------------------------- CONSTRUCTOR
	public BookEntity(){}
	
	// ------------------------------- PUBLIC METHODS
	@Override
	public String toString(){
		return this.getClass().getName()
				+ "[id="+id
				+ ", name="+name
				+ ", price="+price
				+ ", numberOfRead="+numberOfRead
				+ ", lastReadDateTime="+lastReadDateTime
				+ ", authors="+authors
				+ "]";
	}

	// --------------------------------- GET/SET TERS
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}
	//...etc.
}

So, the book entity has the following fields:

  • id containing the technical ID : mandatory field named ID,
  • name corresponding to the book’s name : mandatory field named NAME with a max length of 10 characters,
  • price corresponding to the book’s price : mandatory field named PRICE,
  • numberOfRead corresponding to the number of read of this book : no mandatory field named NB_OF_READ,
  • lastReadDateTime corresponding to the last read datetime of this book : no mandatory field named LAST_READ_DATETIME,
  • authors containing the book’s authors : no mandatory field named AUTHORS,



STEP 4
In this step, we create an utility class ValidatorUtil to handle the validation of entities:

package com.ho.annotations.validator;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;

import com.ho.annotations.common.annotations.FieldName;
import com.ho.annotations.common.annotations.Mandatory;
import com.ho.annotations.common.annotations.MaxLength;
import com.ho.annotations.data.entity.AbstractEntity;
import com.ho.annotations.data.entity.ErrorEntity;

/**
 * This class handles the validation of the entity.
 * @author huseyin
 */
public final class ValidatorUtil {

	// ---------------------------------- CONSTRUCTOR
	private ValidatorUtil(){}

	// ------------------------------- PUBLIC METHODS
	/**
	 * Validation of the given entity annotations
	 * @param myEntity
	 * @throws Exception
	 */
	public static void validateEntity(AbstractEntity myEntity) throws Exception{
		myEntity.addErrors(validateAnnotatedFields(myEntity));
	}

	
	// ------------------------------ PRIVATE METHODS
	/**
	 * Validates all the annotated field of the given entities.
	 * Supported annotation are {@see Mandatory} {@see MaxLength}
	 * @param myEntity
	 * @return
	 * @throws Exception
	 */
	private static List<ErrorEntity> validateAnnotatedFields(AbstractEntity myEntity) throws Exception{
		List<ErrorEntity> errors = new ArrayList<ErrorEntity>();
		
		for(Field field : myEntity.getClass().getDeclaredFields()){
			// Mandatory field
			final Mandatory mandatory = field.getAnnotation(Mandatory.class);
			if(mandatory != null){
				final Object fieldValue = PropertyUtils.getProperty(myEntity, field.getName());
				if(fieldValue == null){
					final FieldName fieldName = field.getAnnotation(FieldName.class);
					errors.add(new ErrorEntity(fieldName.name(), "Mandatory."));
				}
			}// Mandatory
			
			// MaxLength
			final MaxLength maxLength = field.getAnnotation(MaxLength.class);
			if(maxLength != null){
				final Object fieldValue = PropertyUtils.getProperty(myEntity, field.getName());
				if(fieldValue instanceof String ){
					if(maxLength.maxLength() < ((String)fieldValue).length()){
						final FieldName fieldName = field.getAnnotation(FieldName.class);
						errors.add(new ErrorEntity(fieldName.name(), "Value is too large. Max length is: "+maxLength.maxLength()));
					}
				}
			}// MaxLength
					
		}//end-for
		
		return errors;
	}
}

The important point of this class is the part concerning the checking of annotations on entity object:

// Mandatory field
final Mandatory mandatory = field.getAnnotation(Mandatory.class);
if(mandatory != null){
	final Object fieldValue = PropertyUtils.getProperty(myEntity, field.getName());
	if(fieldValue == null){
		final FieldName fieldName = field.getAnnotation(FieldName.class);
		errors.add(new ErrorEntity(fieldName.name(), "Mandatory."));
	}
}// Mandatory
// MaxLength
final MaxLength maxLength = field.getAnnotation(MaxLength.class);
if(maxLength != null){
	final Object fieldValue = PropertyUtils.getProperty(myEntity, field.getName());
	if(fieldValue instanceof String ){
		if(maxLength.maxLength() < ((String)fieldValue).length()){
			final FieldName fieldName = field.getAnnotation(FieldName.class);
			errors.add(new ErrorEntity(fieldName.name(), "Value is too large. Max length is: "+maxLength.maxLength()));
		}
	}
}// MaxLength



STEP 5
Finally, we are creating a main method TestValidator to check our valiation based on annotations:

package com.ho.annotations.validator.test;

import java.util.GregorianCalendar;
import java.util.Iterator;

import com.ho.annotations.data.entity.AbstractEntity;
import com.ho.annotations.data.entity.BookEntity;
import com.ho.annotations.data.entity.ErrorEntity;
import com.ho.annotations.validator.ValidatorUtil;

public class TestValidator {

	public static void main(String[] args) {
		try{
			// Test n°1 : All fields are filled => OK
			{
				System.out.println("----- Test n°1 : All fields are filled ----"); 
				final BookEntity book = new BookEntity();
				book.setId(456789); // Mandatory
				book.setName("Germinal"); // Mandatory
				book.setPrice(123.23); // Mandatory
				book.setNumberOfRead(12);
				book.setLastReadDateTime(GregorianCalendar.getInstance());
				book.setAuthors(new String[]{"Emile Zola"});
				ValidatorUtil.validateEntity(book);
				printErrors(book);
			}
			
			// Test n°2 : Some optional fields are missing => OK
			{
				System.out.println("----- Test n°2 : Some optional fields are missing ----"); 
				final BookEntity book = new BookEntity();
				book.setId(456789); // Mandatory
				book.setName("Germinal"); // Mandatory
				book.setPrice(123.23); // Mandatory
				book.setNumberOfRead(12);
				book.setLastReadDateTime(GregorianCalendar.getInstance());
				ValidatorUtil.validateEntity(book);
				printErrors(book);
			}

			// Test n°3 : Some mandatory fields are missing => NOK Errors messages
			{
				System.out.println("----- Test n°3 : Some mandatory fields are missing ----"); 
				final BookEntity book = new BookEntity();
				book.setId(456789); // Mandatory
				book.setName(null); // Mandatory
				book.setPrice(123.23); // Mandatory
				book.setNumberOfRead(12);
				book.setLastReadDateTime(GregorianCalendar.getInstance());
				book.setAuthors(new String[]{"Emile Zola"});
				ValidatorUtil.validateEntity(book);
				printErrors(book);
			}
			
			// Test n°4 : All fields are filled but a field's value is too large (maxlength is reached) => NOK Errors messages
			{
				System.out.println("----- Test n°4 : All fields are filled but a field's value is too large (maxlength is reached) ----"); 
				final BookEntity book = new BookEntity();
				book.setId(456789); // Mandatory
				book.setName("dsf sdf ezrezk jlezjr ezrezlrjezlrjezlrjez lrjezlkjr ezrezjrezrezrez"); // Mandatory
				book.setPrice(123.23); // Mandatory
				book.setNumberOfRead(12);
				book.setLastReadDateTime(GregorianCalendar.getInstance());
				book.setAuthors(new String[]{"Emile Zola"});
				ValidatorUtil.validateEntity(book);
				printErrors(book);
			}			
		}catch(Throwable th){
			th.printStackTrace();
		}
	}
	

	private static void printErrors(AbstractEntity myEntity){
		if(myEntity!=null && myEntity.hasError()){
			for (Iterator<ErrorEntity> iterator = myEntity.getErrors().iterator(); iterator.hasNext();) {
				ErrorEntity currErrorEntity = iterator.next();
				System.out.println(currErrorEntity);
			}//end-for
		}else{
			System.out.println("No error found in the validation of this entity!");
		}//end-if
	}	
}

The outputs are:

----- Test n°1 : All fields are filled ----
No error found in the validation of this entity!
----- Test n°2 : Some optional fields are missing ----
No error found in the validation of this entity!
----- Test n°3 : Some mandatory fields are missing ----
NAME Mandatory.
----- Test n°4 : All fields are filled but a field's value is too large (maxlength is reached) ----
NAME Value is too large. Max length is: 10

That’s all!!!!

Huseyin OZVEREN

Hi,

I continue with Unix commands concerning archiving ZIP, TAR…etc.

First, we list the content of current folder /opt/tomcat/webapps/host-manager:

huo@myserver:/opt/tomcat/webapps/host-manager>ls -lR
.:
total 20
drwxr-xr-x 2 huoadmin huoadmin 4096 2014-01-06 10:18 images
-rw-r--r-- 1 huoadmin huoadmin  889 2013-07-02 09:59 index.jsp
-rw-r--r-- 1 huoadmin huoadmin 1103 2013-07-02 09:59 manager.xml
drwxr-xr-x 2 huoadmin huoadmin 4096 2014-01-06 10:18 META-INF
drwxr-xr-x 3 huoadmin huoadmin 4096 2014-01-06 10:18 WEB-INF

./images:
total 40
-rw-r--r-- 1 huoadmin huoadmin 1037 2013-07-02 09:59 add.gif
-rw-r--r-- 1 huoadmin huoadmin 7279 2013-07-02 09:59 asf-logo.gif
-rw-r--r-- 1 huoadmin huoadmin  394 2013-07-02 09:59 code.gif
-rw-r--r-- 1 huoadmin huoadmin  608 2013-07-02 09:59 design.gif
-rw-r--r-- 1 huoadmin huoadmin  261 2013-07-02 09:59 docs.gif
-rw-r--r-- 1 huoadmin huoadmin  345 2013-07-02 09:59 fix.gif
-rw-r--r-- 1 huoadmin huoadmin 1934 2013-07-02 09:59 tomcat.gif
-rw-r--r-- 1 huoadmin huoadmin  627 2013-07-02 09:59 update.gif
-rw-r--r-- 1 huoadmin huoadmin   43 2013-07-02 09:59 void.gif

./META-INF:
total 4
-rw-r--r-- 1 huoadmin huoadmin 1191 2013-07-02 09:59 context.xml

./WEB-INF:
total 12
drwxr-xr-x 2 huoadmin huoadmin 4096 2014-01-06 10:18 jsp
-rw-r--r-- 1 huoadmin huoadmin 4838 2013-07-02 09:59 web.xml

./WEB-INF/jsp:
total 12
-rw-r--r-- 1 huoadmin huoadmin 2833 2013-07-02 09:59 401.jsp
-rw-r--r-- 1 huoadmin huoadmin 3592 2013-07-02 09:59 403.jsp
-rw-r--r-- 1 huoadmin huoadmin 4838 2013-07-02 09:59 404.jsp

Archive a folder in TAR.GZ

huo@myserver:/opt/tomcat/webapps>tar cf - ./host-manager/ | gzip -c > /tmp/HUO/host-manager.tar.gz

huo@myserver:/opt/tomcat/webapps>ls -lR /tmp/HUO/
/tmp/HUO/:
total 16
-rw-r--r-- 1 huoadmin huoadmin 15438 2014-02-10 16:49 host-manager.tar.gz

Check the content in TAR.GZ archive

huo@myserver:/tmp/HUO>gunzip -c /tmp/HUO/host-manager.tar.gz | tar tf - 
./host-manager/
./host-manager/manager.xml
./host-manager/index.jsp
./host-manager/WEB-INF/
./host-manager/WEB-INF/jsp/
./host-manager/WEB-INF/jsp/404.jsp
./host-manager/WEB-INF/jsp/401.jsp
./host-manager/WEB-INF/jsp/403.jsp
./host-manager/WEB-INF/web.xml
./host-manager/META-INF/
./host-manager/META-INF/context.xml
./host-manager/images/
./host-manager/images/add.gif
./host-manager/images/fix.gif
./host-manager/images/docs.gif
./host-manager/images/code.gif
./host-manager/images/void.gif
./host-manager/images/design.gif
./host-manager/images/asf-logo.gif
./host-manager/images/update.gif
./host-manager/images/tomcat.gif

Unarchive a TAR.GZ archive in a folder

huo@myserver:/tmp/HUO>gunzip -c /tmp/HUO/host-manager.tar.gz | tar xf - 

huo@myserver:/tmp/HUO>ll
total 20
drwxr-xr-x 5 huoadmin huoadmin  4096 2014-01-06 10:18 host-manager
-rw-r--r-- 1 huoadmin huoadmin 15438 2014-02-10 17:00 host-manager.tar.gz

huo@myserver:/tmp/HUO>ls -lR
.:
total 20
drwxr-xr-x 5 huoadmin huoadmin  4096 2014-01-06 10:18 host-manager
-rw-r--r-- 1 huoadmin huoadmin 15438 2014-02-10 17:00 host-manager.tar.gz

./host-manager:
total 20
drwxr-xr-x 2 huoadmin huoadmin 4096 2014-01-06 10:18 images
-rw-r--r-- 1 huoadmin huoadmin  889 2013-07-02 09:59 index.jsp
-rw-r--r-- 1 huoadmin huoadmin 1103 2013-07-02 09:59 manager.xml
drwxr-xr-x 2 huoadmin huoadmin 4096 2014-01-06 10:18 META-INF
drwxr-xr-x 3 huoadmin huoadmin 4096 2014-01-06 10:18 WEB-INF

./host-manager/images:
total 40
-rw-r--r-- 1 huoadmin huoadmin 1037 2013-07-02 09:59 add.gif
-rw-r--r-- 1 huoadmin huoadmin 7279 2013-07-02 09:59 asf-logo.gif
-rw-r--r-- 1 huoadmin huoadmin  394 2013-07-02 09:59 code.gif
-rw-r--r-- 1 huoadmin huoadmin  608 2013-07-02 09:59 design.gif
-rw-r--r-- 1 huoadmin huoadmin  261 2013-07-02 09:59 docs.gif
-rw-r--r-- 1 huoadmin huoadmin  345 2013-07-02 09:59 fix.gif
-rw-r--r-- 1 huoadmin huoadmin 1934 2013-07-02 09:59 tomcat.gif
-rw-r--r-- 1 huoadmin huoadmin  627 2013-07-02 09:59 update.gif
-rw-r--r-- 1 huoadmin huoadmin   43 2013-07-02 09:59 void.gif

./host-manager/META-INF:
total 4
-rw-r--r-- 1 huoadmin huoadmin 1191 2013-07-02 09:59 context.xml

./host-manager/WEB-INF:
total 12
drwxr-xr-x 2 huoadmin huoadmin 4096 2014-01-06 10:18 jsp
-rw-r--r-- 1 huoadmin huoadmin 4838 2013-07-02 09:59 web.xml

./host-manager/WEB-INF/jsp:
total 12
-rw-r--r-- 1 huoadmin huoadmin 2833 2013-07-02 09:59 401.jsp
-rw-r--r-- 1 huoadmin huoadmin 3592 2013-07-02 09:59 403.jsp
-rw-r--r-- 1 huoadmin huoadmin 4838 2013-07-02 09:59 404.jsp

Archive each element (subfolder, file) of root folder in TAR.GZ
In this example, we will create a TAR.GZ archive for each element (folder or file) contained in a root folder. The archives’ names will be the name of element suffixed by “.tar.gz”. So to do this, we create a shellscript file named “createMultipleArchives.sh”.

huo@myserver:/tmp/HUO>more ./createMultipleArchives.sh
cd /opt/tomcat/webapps/host-manager
for f in * ; do
       tar cf - $f | gzip -c > /tmp/HUO/${f}.tar.gz
done

huo@myserver:/tmp/HUO>./createMultipleArchives.sh

huo@myserver:/tmp/HUO>ll

huo@myserver:/opt/tomcat/webapps>tar cf - ./host-manager/ | gzip -c > /tmp/HUO/host-manager.tar.gz
total 32
-rw-r--r-- 1 huoadmin huoadmin 11538 2014-02-11 09:51 images.tar.gz
-rw-r--r-- 1 huoadmin huoadmin   660 2014-02-11 09:51 index.jsp.tar.gz
-rw-r--r-- 1 huoadmin huoadmin   788 2014-02-11 09:51 manager.xml.tar.gz
-rwxr-xr-x 1 huoadmin huoadmin   121 2014-02-11 09:51 createMultipleArchives.sh
-rw-r--r-- 1 huoadmin huoadmin  3275 2014-02-11 09:51 WEB-INF.tar.gz

That’s all!!!

Huseyin OZVEREN

Hi,

In this article, I propose you some useful Unix commands relative to Tomcat.



Delete the Tomcat log without restart
It’s possible to empty the Tomcat log wihout restart it:

huo@myserver:/opt/tomcat/logs>ls -l Catalina.out
-rw-r--r-- 1 huoadmin huoadmin 12345898 2014-02-15 10:15 catalina.out

huo@myserver:/opt/tomcat/logs>echo "" > catalina.out
-rw-r--r-- 1 huoadmin huoadmin 1 2014-02-15 10:16 catalina.out



Restart Tomcat
First, it is necessary to do a sudo in order to run programs with the security privileges of superuser:

huo@myserver:/opt/tomcat>sudo su - huoadmin
...

…try to stop the server:

huo@myserver:/opt/tomcat>/etc/init.d/tomcat restart 
or
huo@myserver:/opt/tomcat>/etc/init.d/tomcat stop

….but if this command doesn’t done and returns an error : we must get the PID of process:

huo@myserver:/opt/tomcat>ps -ef | grep tomcat
huoadmin    15945   1  0 Nov13  00:26:45  /usr/java....

…so, it is necessary to stop the process linked to the Tomcat server:

huo@myserver:/opt/tomcat>kill -9 15945

…finally, ensure that the process has been killed:

huo@myserver:/opt/tomcat>ps -ef | grep tomcat
huoadmin   5871 5850 0  07:31   pts/4   00:00:00 grep  --color=auto tomcat

…to finish, we can restart the Tomcat server:

huo@myserver:/opt/tomcat>/etc/init.d/tomcat start


That’s all!!!

Huseyin OZVEREN

Page 1 of 29:1 2 3 4 »Last »
bottom-img
Copyright ® 2012 Huseyin Ozveren. No reproduction, even partial, can be used from this site and all its contents including text, documents, images, etc.. without the express permission of the author.
Jeux gratuit | flash jeux gratuits