Saturday, April 30, 2016

SSH

See here first if network has issues http://gvace.blogspot.com/2016/04/linux-network-configs.html

Without password

  1. Client save its public key to remote ssh server.
  2. When ssh login, remote ssh server send client a random string.
  3. Client use its private key to encrypt this random string.
  4. Client send ssh server the encrypted string.
  5. SSH server use saved public key to decrypt.
  6. If decrypt succeed, ssh server allow client to login, without password.



ssh client

Generate key
ssh-keygen -t rsa
generated public and private key will be in ~/.ssh
private key file: id_rsa
public key file: id_rsa.pub


copy the public key to target ssh-server
ssh-copy-id user1@192.168.3.4
this command will copy the public key from client to ssh server, saved in ~/.ssh/authorized_keys

keep public key and private key in ssh-client side

ssh server

Check if SSH is running
sudo netstat -anp | grep sshd
If nothing on port 22, means ssh-server is not running, install ssh-server or start it.

check firewall(iptables which is ufw), make sure ssh can go through



















Linux Network configs

Check port 61616
netstat -an|grep "61616"


Which program is using port 61616
netstat -nlap|grep 61616




check all networks
ifconfig -a

Config IP address dhcp netmask gateway etc..

/etc/network/interfaces

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto em1
iface em1 inet dhcp
# This is an autoconfigured IPv6 interface
iface em1 inet6 auto
#another
auto enp0s3
iface enp0s3 inet static
address 192.168.56.95
netmask 255.255.255.0
network 192.168.56.0
broadcast 192.168.56.255



Change hostname
/etc/hostname

Assign ip to hostname
/etc/hosts



iptables

ubuntu
https://help.ubuntu.com/community/IptablesHowTo
sudo iptables -L

centOS
service iptables status


See what port is opened
netstat -tnlp








Friday, April 29, 2016

REST

REST Representational State Transfer


Representational
In any form: XML, JSON, HTML

State
More concerned with the state of a resource than with the actions we can take against resources.

Transfer
Trensfering data

Transfering the state of resources- in whatever form is most appropriate--from a server to a client(or client to server)





Wednesday, April 27, 2016

Spring Transaction Isolation Level

Spring Transaction Isolation Level

The standard levels are 2,3,4,5, the higher level, the poorer concurrency/effi
  1. ISOLATION_DEFAULT (Spring)
    This is a PlatformTransactionManager Default isolation level, using Default Database transaction level. The other 4 are correspond to JDBC isolation level
  2. ISOLATION_READ_UNCOMMITTED
    Lowest isolation level. Allow other transaction to see the data from this transaction. This level can cause dirty read, non-repeatable read, and illusion read
  3. ISOLATION_READ_COMMITTED (normally used)
    Promise other transaction can read data until this transaction committed.
  4. ISOLATION_REPEATABLE_READ
    Prevent dirty read, non-repeatable read. But can illusion read.
  5. ISOLATION_SERIALIZABLE
    This is most expensive level, but most reliable. It promise Sequence. Prevent dirty read, non-repeatable read, and illusion read

Transaction Definition

Transaction Definition

  1. PROPAGATION_REQUIRED (normally used)
    If transaction existed, use it, otherwise open a new transaction
  2. PROPAGATION_SUPPORTS
    If transaction existed, use it, otherwise run as non-transaction
  3. PROPAGATION_MANDATORY
    If transaction existed, use it, otherwise throw Exception
  4. PROPAGATION_REQUIRES_NEW
    Always open a new transaction, if transaction existed, hang up the existed transaction
  5. PROPAGATION_NOT_SUPPORTED
    Always run without transaction, if transaction existed, hang up the existed transaction
  6. PROPAGATION_NEVER
    Always run without transaction, if transaction existed, throw Exception
  7. PROPAGATION_NESTED (in Spring)
    If transaction existed, run nested transaction inside the existed transaction.
    If no transaction existed, run as PROPAGATION_REQUIRED

PropagationT1 NoneT1 Existed
REQUIREDT2=>newT1
SUPPORTST2 NoneT1
MANDATORYT2 ExceptionT1
REQUIRES_NEWT2=>newT2=>new
NOT_SUPPORTEDNoneHang up T1
NEVERNoneT2 Exception
NESTEDAs REQUIREDNested

Log


Three main types of log

  • Operation Log
  • Safety Log
  • Event Log

Dynamic Proxy: JDK VS CGLIB

If target object implements interface, by default, spring will use Dynamic Proxy from JDK for AOP.
If target object implements interface, we can force to use CGLIB to make Dynamic Proxy for AOP.
If target object does not implements interface, we MUST use CGLIB to make Dynamic Proxy for AOP.

In conclusion:
JDK can only apply to class which implements interface
CGLIB can apply to class with/without implementing interface

Spring will dynamically choose to use JDK or CGLIB for each target object.


JDK proxy example:
userManager $Proxy2  (id=42)
h JdkDynamicAopProxy  (id=54)

CGLIB example:
UserManagerImpl$$EnhancerBySpringCGLIB$$7f895f28  (id=46)

You can see CGLIB extends the target class to generate proxy, JDK did not
Because CGLIB do extends, our target class should NOT be final

to Enable CGLIB:

dependency:
<dependency>
 <groupId>cglib</groupId>
 <artifactId>cglib</artifactId>
 <version>3.2.2</version>
</dependency>

applicationContext.xml config

<!-- proxy-target-class="true" means force to use CGLIB -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

But if we want spring to choose for us, we don't have to force to do the config, just add dependency.






Tuesday, April 26, 2016

Spring AOP AspectJ Advice

An advice is really simple,
If config it in xml:
package com.gvace.aop;

/*
 * To define an Aspect
 * 
 */
public class SecurityHandler {

 private void checkSecurity() {
  System.out.println("Runned checkSecurity");
 }
}


If with Annotation
package com.gvace.aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


/*
 * To define an Aspect
 * 
 */
@Aspect
public class SecurityHandler {
 //@Pointcut Describe the target functions
 //So this function is ONLY JUST A FLAG, it will NEVER be called anyway
 //(* add*(..)), means return any type, name likes "add*", parameter can be anything 
 // the addAddMethod function does not want parameter and return type
 @Pointcut("execution(* add*(..))")
 private void addAddMethod(){}
 
 
 //define this Advice is run before target function
 //And it applied to some @Pointcut described functions
 @Before(value = "addAddMethod()")
 //@After(value = "addAddMethod()")
 private void checkSecurity() {
  System.out.println("Runned checkSecurity");
 }
}



Add a JoinPoint argument to get target class method information
package com.gvace.aop;

import org.aspectj.lang.JoinPoint;

/*
 * To define an Aspect
 * 
 */
public class SecurityHandler {
 //add a JoinPoint argument to get target class method information

 private void checkSecurity(JoinPoint joinPoint){
  System.out.println("Method name: "+joinPoint.getSignature().getName());
  for(int i=0; i<joinPoint.getArgs().length; i++){
   System.out.println(joinPoint.getArgs()[i]);
  }
  System.out.println("Runned checkSecurity");
 }
}

Spring AOP AspectJ Pointcut Expression


any public functions
any return type
any function name
any/no arguments
execution(public * *(..))


Any public functions which name start with "set"
execution(* set*(..))

All ABCService interface's function
execution(* com.abc.ABCService.*(..))

All functions classes in package abc
execution(* com.abc.*.*(..))


All functions classes in package abc or sub-package of abc
execution(* com.abc..*.*(..))


can use "||"  "&&" like
execution(* set*(..)) && execution(* com.abc.*.*(..))


More See this
http://howtodoinjava.com/spring/spring-aop/writing-spring-aop-aspectj-pointcut-expressions-with-examples/

Spring AOP with AspectJ no Annotation config

Concepts

Cross Cutting Concern: A isolated service, across all procedure in system

Aspect: The model pattern of Cross Cutting Point

Advice: The implementation of Aspect

Pointcut: Defines which JoinPoint(s) applied by Advice. For Spring, it's function invoke.

JoinPoint: the time point when Advice run, Spring only support JoinPoint on function

Weave: Apply Advice to Target Object called Weave. Spring support dynamic Weave.

Target Object: The Target Object that Advice applied to.

Proxy: Spring AOP default uses dynamic proxy from JDK, it's proxy is created when running. It can also use CGLIB proxy(when not using Interface).

Introduction: Add function for Class dynamically


See this first: Spring AOP
 http://gvace.blogspot.com/2016/03/aop.html

To skip this and see: Spring AOP with AspectJ and Annotation
http://gvace.blogspot.com/2016/04/spring-aop-with-annotation.html

Example

Using Spring Version 4.2.5
Add dependency AspectJ

pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>spring_static_proxy</groupId>
 <artifactId>spring_static_proxy</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <build>
  <sourceDirectory>src</sourceDirectory>
  <plugins>
   <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
     <source>1.7</source>
     <target>1.7</target>
    </configuration>
   </plugin>
  </plugins>
 </build>
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.build.mainClass>com.gvace.main</project.build.mainClass>
  <java.version>1.7</java.version>
  <spring.version>4.2.5.RELEASE</spring.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-beans</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
  </dependency>
  <dependency>
   <groupId>commons-logging</groupId>
   <artifactId>commons-logging</artifactId>
   <version>1.2</version>
  </dependency>
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>1.8.9</version>
  </dependency>
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.8.9</version>
  </dependency>
 </dependencies>
 <repositories>
  <repository>
   <id>spring-milestones</id>
   <name>Spring Milestones</name>
   <url>https://repo.spring.io/libs-milestone</url>
   <snapshots>
    <enabled>false</enabled>
   </snapshots>
  </repository>
 </repositories>
</project>

Create a class as Aspect

SecurityHandler.java
package com.gvace.aop;

/*
 * To define an Aspect
 * 
 */
public class SecurityHandler {

 private void checkSecurity() {
  System.out.println("Runned checkSecurity");
 }
}


An example interface(Target Object)
package com.gvace.inter;

public interface UserManager {
 public void addUser(String username,String password);
 public void delUser(int userId);
 public String findUserById(int userId);
 public void modifyUser(int userId, String username,String password);
}


The implementation of the interface(Target Object)

UserManagerImpl.java
package com.gvace.impl;

import com.gvace.inter.UserManager;

// each method have to call checkSecurity()
// and you don't want to change it based on requirement changes(like the codes being comment out)
public class UserManagerImpl implements UserManager {

 @Override
 public void addUser(String username, String password) {
  //checkSecurity();
  System.out.println("addUser:"+username+" "+password);
 }

 @Override
 public void delUser(int userId) {
  //checkSecurity();
  System.out.println("delUser:"+userId+" ");
 }

 @Override
 public String findUserById(int userId) {
  //checkSecurity();
  System.out.println("findUserById:"+userId+" ");
  return "findUserById"+userId;
 }

 @Override
 public void modifyUser(int userId, String username, String password) {
  //checkSecurity();
  System.out.println("modifyUser:"+userId+" "+username+" "+password);
 }
 /*
 public void checkSecurity(){
  System.out.println("Runned checkSecurity");
 }
 */
}


Register beans and aspect annotation

applicationContext.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:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/aop/spring-tx.xsd">
 
 <!-- Data Source -->
 <bean id="userManager" class="com.gvace.impl.UserManagerImpl"></bean>
 
 <!-- Aspect Class-->
 <bean id="securityHandler" class="com.gvace.aop.SecurityHandler"></bean>
 <aop:config>
  <!-- Define Aspect, link to Aspect Class -->
  <aop:aspect id="securityAspect" ref="securityHandler">
   <!-- Define Pointcut -->
   <aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/>
   <!-- Link the Advice method to Pointcut -->
   <aop:before method="checkSecurity" pointcut-ref="addAddMethod"/>
  </aop:aspect>
 </aop:config>
</beans>



Test to run

Client.java
package com.gvace.test;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.gvace.inter.UserManager;

public class Client {
 public static void main(String[] args){
  BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserManager userManager = (UserManager)factory.getBean("userManager");
  //Since this UserManager interface contains function like execution(* add*(..))
  //this userManager reference will not be the implementation class, it will be a Proxy
  userManager.addUser("a", "b");
 }
}













Spring AOP with AspectJ and Annotation

Concepts

Cross Cutting Concern: A isolated service, across all procedure in system

Aspect: The model pattern of Cross Cutting Point

Advice: The implementation of Aspect

Pointcut: Defines which JoinPoint(s) applied by Advice. For Spring, it's function invoke.

JoinPoint: the time point when Advice run, Spring only support JoinPoint on function

Weave: Apply Advice to Target Object called Weave. Spring support dynamic Weave.

Target Object: The Target Object that Advice applied to.

Proxy: Spring AOP default uses dynamic proxy from JDK, it's proxy is created when running. It can also use CGLIB proxy(when not using Interface).

Introduction: Add function for Class dynamically


See this first: Spring AOP
 http://gvace.blogspot.com/2016/03/aop.html

Then see this Spring AOP with AspectJ with no Annotation Config
http://gvace.blogspot.com/2016/04/spring-aop-with-aspectj-no-annotation.html


Example

Using Spring Version 4.2.5
Add dependency AspectJ

pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>spring_static_proxy</groupId>
 <artifactId>spring_static_proxy</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <build>
  <sourceDirectory>src</sourceDirectory>
  <plugins>
   <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
     <source>1.7</source>
     <target>1.7</target>
    </configuration>
   </plugin>
  </plugins>
 </build>
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.build.mainClass>com.gvace.main</project.build.mainClass>
  <java.version>1.7</java.version>
  <spring.version>4.2.5.RELEASE</spring.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-beans</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
  </dependency>
  <dependency>
   <groupId>commons-logging</groupId>
   <artifactId>commons-logging</artifactId>
   <version>1.2</version>
  </dependency>
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>1.8.9</version>
  </dependency>
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.8.9</version>
  </dependency>
 </dependencies>
 <repositories>
  <repository>
   <id>spring-milestones</id>
   <name>Spring Milestones</name>
   <url>https://repo.spring.io/libs-milestone</url>
   <snapshots>
    <enabled>false</enabled>
   </snapshots>
  </repository>
 </repositories>
</project>

Create a class as Aspect

SecurityHandler.java
package com.gvace.aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


/*
 * To define an Aspect
 * 
 */
@Aspect
public class SecurityHandler {
 //@Pointcut Describe the target functions
 //So this function is ONLY JUST A FLAG, it will NEVER be called anyway
 //(* add*(..)), means return any type, name likes "add*", parameter can be anything 
 // the addAddMethod function does not want parameter and return type
 @Pointcut("execution(* add*(..))")
 private void addAddMethod(){}
 
 
 //define this Advice is run before target function
 //And it applied to some @Pointcut described functions
 @Before(value = "addAddMethod()")
 //@After(value = "addAddMethod()")
 private void checkSecurity() {
  System.out.println("Runned checkSecurity");
 }
}


An example interface(Target Object)
package com.gvace.inter;

public interface UserManager {
 public void addUser(String username,String password);
 public void delUser(int userId);
 public String findUserById(int userId);
 public void modifyUser(int userId, String username,String password);
}


The implementation of the interface(Target Object)

UserManagerImpl.java
package com.gvace.impl;

import com.gvace.inter.UserManager;

// each method have to call checkSecurity()
// and you don't want to change it based on requirement changes(like the codes being comment out)
public class UserManagerImpl implements UserManager {

 @Override
 public void addUser(String username, String password) {
  //checkSecurity();
  System.out.println("addUser:"+username+" "+password);
 }

 @Override
 public void delUser(int userId) {
  //checkSecurity();
  System.out.println("delUser:"+userId+" ");
 }

 @Override
 public String findUserById(int userId) {
  //checkSecurity();
  System.out.println("findUserById:"+userId+" ");
  return "findUserById"+userId;
 }

 @Override
 public void modifyUser(int userId, String username, String password) {
  //checkSecurity();
  System.out.println("modifyUser:"+userId+" "+username+" "+password);
 }
 /*
 public void checkSecurity(){
  System.out.println("Runned checkSecurity");
 }
 */
}


Register beans and aspect annotation

applicationContext.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:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/aop/spring-tx.xsd">

 <!-- Enable AspectJ Annotation -->
 <aop:aspectj-autoproxy/>
 
 <!-- Data Source -->
 <bean id="userManager" class="com.gvace.impl.UserManagerImpl"></bean>
 
 <!-- Aspect -->
 <bean id="securityHandler" class="com.gvace.aop.SecurityHandler"></bean>
</beans>


Test to run

Client.java
package com.gvace.test;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.gvace.inter.UserManager;

public class Client {
 public static void main(String[] args){
  BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserManager userManager = (UserManager)factory.getBean("userManager");
  //Since this UserManager interface contains function like execution(* add*(..))
  //this userManager reference will not be the implementation class, it will be a Proxy
  userManager.addUser("a", "b");
 }
}













Monday, April 25, 2016

Static Proxy and Dynamic Proxy

Normally like security check, transaction, log, these commonly used functions are not related to business logic, we can use proxy to separate these code from business codes

Think an interface has some functions
And before running each function in this interface, you need to call checkSecurity() first
To make the implementation cleaner
And which does not change when requirement for checkSecurity() changes
What solutions we have?

Example Interface:
package com.gvace.inter;

public interface UserManager {
 public void addUser(String username,String password);
 public void delUser(int userId);
 public String findUserById(int userId);
 public void modifyUser(int userId, String username,String password);
}

Clear Implementation example:
package com.gvace.impl;

import com.gvace.inter.UserManager;

// each method have to call checkSecurity()
// and you don't want to change it based on requirement changes(like the codes being comment out)
public class UserManagerImpl implements UserManager {

 @Override
 public void addUser(String username, String password) {
  //checkSecurity();
  System.out.println("addUser:"+username+" "+password);
 }

 @Override
 public void delUser(int userId) {
  //checkSecurity();
  System.out.println("delUser:"+userId+" ");
 }

 @Override
 public String findUserById(int userId) {
  //checkSecurity();
  System.out.println("findUserById:"+userId+" ");
  return "findUserById"+userId;
 }

 @Override
 public void modifyUser(int userId, String username, String password) {
  //checkSecurity();
  System.out.println("modifyUser:"+userId+" "+username+" "+password);
 }
 /*
 public void checkSecurity(){
  System.out.println("Runned checkSecurity");
 }
 */
}

Solution 1: Static Proxy
To simplify target implementation class, we build this proxy
We do checkSecurity() in proxy
So target implementation will not changed when requirement change
But we still have to call checkSecurity() in every method in this proxy
And we still have to change this proxy when requirement change

package com.gvace.proxy.static_;

import com.gvace.inter.UserManager;

/*
 * To simplify target implementation class, we build this proxy
 * We do checkSecurity() in proxy
 * So target implementation will not changed when requirement change
 * But we still have to call checkSecurity() in every method in this proxy
 * And we still have to change this proxy when requirement change
 * 
 * Thinking:
 * Actually checkSecurity() is separate logic from the target functions.
 * We need to find a way to separate it
 */
public class UserManagerImplProxy implements UserManager {
 UserManager userManager;
 public UserManagerImplProxy(UserManager userManager){
  this.userManager = userManager;
 }
 @Override
 public void addUser(String username, String password) {
  checkSecurity();
  userManager.addUser(username, password);
 }

 @Override
 public void delUser(int userId) {
  checkSecurity();
  userManager.delUser(userId);
 }

 @Override
 public String findUserById(int userId) {
  checkSecurity();
  return userManager.findUserById(userId);
 }

 @Override
 public void modifyUser(int userId, String username, String password) {
  checkSecurity();
  userManager.modifyUser(userId, username, password);
 }
 private void checkSecurity(){
  System.out.println("Runned checkSecurity");
 }
}


Thinking:
Actually checkSecurity() is separate logic from the target functions.
We need to find a way to separate it, so we have Solution 2



Solution 2: Dynamic Proxy

Create a Handler which implements InvocationHandler
This handler will register all functions from the target interfaces
So every-time the registered functions runs, it needs to go through the invoke() function in this handler
In this way, we can control the registered functions



package com.gvace.proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


 //To use Dynamic Proxy
 //We build a InvocationHandler only for the function checkSecurity()


public class SecurityHandler implements InvocationHandler {
 private Object targetObject;

 public Object createProxyInstance(Object targetObject){
  //Save the targetObject as a reference
  this.targetObject = targetObject;
  
  
   // By creating this proxy
   // all interfaces' functions(targetObject.getClass().getInterfaces())
   // will be registered to this handler(filter) 
  return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
        targetObject.getClass().getInterfaces(),
        this);
 }

 
  // see java.lang.reflect.InvocationHandler
  // invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
  // 
  // invoke() like a filter of the target function
  // This will run every-time when the registered interfaces' functions runs
  

 @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  //do the checkSecurity()
  checkSecurity();
  
  //after checkSecurity() the filter is finished
  //we can invoke targetObject's function now.(like a filter chain)
  //or we can choose to return null, if it's not pass the checkSecurity() requirement
  return method.invoke(targetObject, args);
 }

 /*
  * checkSecurity() runs like invisible
  */
 private void checkSecurity() {
  System.out.println("Runned checkSecurity");
 }
}




And to run the target through this Handler
You can also use factory pattern to hide the procedure of creating handler and proxy instance

package com.gvace.test;

import com.gvace.impl.UserManagerImpl;
import com.gvace.inter.UserManager;
import com.gvace.proxy.dynamic.SecurityHandler;

public class Client {
 public static void main(String[] args){
  //Create a proxy instance
  //You can also hidden this by using a factory pattern
  SecurityHandler handler = new SecurityHandler();
  UserManager userManager = (UserManager)handler.createProxyInstance(new UserManagerImpl());
  
  userManager.addUser("aaa", "123");
 }
}

Static Proxy and Dynamic Proxy
Since dynamic proxy is dynamic registering the function, it's not efficient as static proxy.

Solution 3: Spring AOP
http://gvace.blogspot.com/2016/03/aop.html

Spring VS ejb

Plain transaction is complicate:

beginTransaction
run function
if(error) rollback;
endTransaction

We have ejb to simplify the transaction code:

  • ejb has session bean, to simplify the transaction codes, can do declare service
  • But cannot run in Tomcat
  • ejb can run in jboss and weblogic
  • ejb is not POJO

Why Spring

  • Lite weight
  • Can run in Tomcat
  • Spring can take over the function of ejb's session bean, declare service
  • Spring can replace part functions of ejb
But ejb has much better performance on distributed system than Spring

Sunday, April 24, 2016

Spring CustomEditorConfigurer

When doing DI, some format of property will need to transfer.

Example:
The target property is java.util.Date, but we can only inject String "2016-04-24"
<property name="date" value="2016-04-24"></property>
So we need a customEditorConfigurer



 <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="customEditors">
   <map>
   <!-- key: target property's class -->
   <!-- value: PropertyEditor bean -->
<entry key="java.util.Date">
     <!-- Inner Bean -->
     <bean class="com.gvace.util.DatePropertyEditor">
      <property name="format" value="yyyy-MM-dd"></property>
     </bean>
    </entry>
   </map>
  </property>
 </bean>
 <!-- Use inner Bean instead -->
 <!-- <bean id="datePropertyEditor" class="com.gvace.util.DatePropertyEditor"></bean>  -->


Create custom PropertyEditor, which extends PropertyEditorSupport
package com.gvace.util;

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

//extends PropertyEditorSupport
public class DatePropertyEditor extends PropertyEditorSupport{
 private String format;
 @Override
 public void setAsText(String text) throws IllegalArgumentException {
  System.out.println("PropertyEditor:"+text);
  try {
   Date date = new SimpleDateFormat(format).parse(text);
   this.setValue(date);
  } catch (ParseException e) {
   e.printStackTrace();
   throw new IllegalArgumentException("IllegalArgumentException"+text);
  }
 }
 public String getFormat() {
  return format;
 }
 public void setFormat(String format) {
  this.format = format;
 }
 
}






Spring DI(Dependency Injection)

Scope

singleton: initialized instance when bean creates by application context
prototype: one bean to many instances
request: get a new instance for a bean in each request
session: get a new instance for a bean in each session
global session: get a new instance for a bean in whole spring container



Lazy mode

Spring default is not lazy mode, when spring starts up, it inits all beans.

If we want bean to init when calling ac.getBean()
do this:
<beans .... default-lazy-init="true">


Example

public class Bean1 {
 private String strValue;
 private int intValue;
 private List listValue;
 private Set setValue;
 private String[] arrayValue;
 private Map mapValue;
 public String getStrValue() {
  return strValue;
 }
 public void setStrValue(String strValue) {
  this.strValue = strValue;
 }
 public int getIntValue() {
  return intValue;
 }
 public void setIntValue(int intValue) {
  this.intValue = intValue;
 }
 public List getListValue() {
  return listValue;
 }
 public void setListValue(List listValue) {
  this.listValue = listValue;
 }
 public Set getSetValue() {
  return setValue;
 }
 public void setSetValue(Set setValue) {
  this.setValue = setValue;
 }
 public String[] getArrayValue() {
  return arrayValue;
 }
 public void setArrayValue(String[] arrayValue) {
  this.arrayValue = arrayValue;
 }
 public Map getMapValue() {
  return mapValue;
 }
 public void setMapValue(Map mapValue) {
  this.mapValue = mapValue;
 }
 
}


 <bean id="bean1" class="com.gvace.domain.Bean1">
  <property name="strValue" value="abc"/>
  <property name="intValue" value="123"/>
  <property name="listValue">
   <list>
    <value>a</value>
    <value>b</value>
   </list>
  </property>
  <property name="setValue">
   <set>
    <value>c</value>
    <value>d</value>
   </set>
  </property>
  <property name="arrayValue">
   <list>
    <value>e</value>
    <value>f</value>
   </list>
  </property>
  <property name="mapValue">
   <map>
    <entry key="k1" value="v1"/>
    <entry key="k2" value="v2"/>
   </map>
  </property>
 </bean>

Monday, April 11, 2016

Spring Annotation

Looking at this good doc, which explains really clear:

http://howtodoinjava.com/spring/spring-core/how-to-use-spring-component-repository-service-and-controller-annotations/
In real life, you will face very rare situations where you will need to use @Component annotation. Most of the time, you will using @Repository@Service and @Controller annotations. @Component should be used when your class does not fall into either of three categories i.e. controller, manager and dao.
If you want to define name of the bean with which they will be registered in DI container, you can pass the name in annotation itself e.g. @Service (“employeeManager”).


Enable Config Annotation in applicationContext.xml
 <!-- Enable Annotation -->
 <context:annotation-config/>
or
 <!-- Enable Annotation in base-package -->
 <context:component-scan base-package="com.gvace.spring.annotation"/>

<context:component-scan> is to help you automatically find classes and register them as beans in base-package, and its all sub packages.

<context:component-scan> annotations:
  • @Component: Indicate the class is a Spring Component
    @Component: register the bean id: camel-casing the class name Class Cat => id "cat"
    @Component("cat1") register the bean with specified id
  • @Controller: Indicate the class defines a Spring MVC controller 
  • @Repository: Indicate the class defines a data repository
  • @Service: Indicates that the class defines a service
Filter types in <context:component-scan>
  1. annotation: class with annotation
  2. assignable: class that assignable to target a Class
  3. aspectj: match aspectj type
  4. custom: uses a custom implementation of org.springframework.core.type.TypeFilter
  5. regex: regular expression
Example:
Assume you have a target Class and a custom Annotation: TargetClass and @SkipIt
<context:component-scan base-package="com.gvace.spring">
 <context:include-filter type="assignable" expression="com.gvace.model.TargetClass">
 <context:exclude-filter type="annotation" expression="com.gvace.spring.annotation.SkipIt">
</context:component-scan>


@Configuration and @Bean
<context:component-scan> also scans @Configuration, looking for class which is Configuration for beans
With @Configuration and @Bean, we can move all bean declarations from XML to Java Class!
To use @Configuration and @Bean, just like a class and its function.

@Configuration
public class MyBeansConfig{
 @Bean
 public Cat myCat1(){
  return new Cat();
 }
 @Bean
 public Cat myCat2(){
  Cat cat2 = new Cat();
  cat2.setName("miamia");
  return cat2;
 }
 @Bean
 public Cat myCat1Copy(){
  return myCat1();
  //This is a ref, and Spring is clever enough to intercept function myCat1()
  //And return the existed bean from context, instead of creating a new instance 
 }
}

When using reference, Spring is clever enough to intercept the ref function. And return the existed bean from context, instead of creating a new instance



Property Injection
@Autowired and @Qualifier, is a pair provided by Spring
@Inject and @Named, is a pair provided by Java community, which is suggested to use


@Autowired(required=false)

Doesn't inject if did not find a bean to wire

@Autowired(required=false)
private Cat myCat;

or

@Autowired(required=false)
public void setMyCat(Cat myCat){
 this.myCat = myCat;
}


@Qualifier
specify a bean by bean id/qualifier

Define a bean with qualifier:
<bean class="com.gvace.Cat">
    <qualifier value="miamia"/>
</bean>

or define by Annotation


@Qualifier("miamia")
class Cat {}


Use Qualifier to narrow down selection
@Autowired
@Qualifier("miamia")
private Cat myCat;


You can also create custom qualifiers.



@Inject
From Java community, almost a replacement to@Autowired, so suggest to use @Inject
Remember to add dependency:
<dependency>
 <groupId>javax.inject</groupId>
 <artifactId>javax.inject</artifactId>
 <version>1</version>
</dependency>

@Inject
@Named("cat")
private String name;

Different to @Autowire, @Inject has a Provider interface, which can do lazy injection and inject multiple instances.
In this constructor, we inject a provider and get() gives different instances each time.

 private Set<Cat> cats;
 @Inject
 public CatTest(Provider<Cat> catProvider){
  cats = new HashSet<Cat>();
  for(int i=0;i<5;i++){
   cats.add(catProvider.get());
  }
 }


Difference between @Named and @Qualifier:
@Qualifier is to narrow the selection of matching beans(use bean's ID by default)
@Named specifically identifies a selected bean by its ID


@Value
Inject a hard coded value is not interesting. But we can also inject with SpEL expressions.

Example: We inject a value from a property file
@Value("#{systemProperties.myAddress}")
private String address;



@Resource Auto-wire, find the property name as bean id from applicationContext.xml usage:
@Resource
EmployeeServiceInterface employeeService;
bean config:
<!-- Service Beans -->
<bean id="employeeService" class="com.gvace.service.impl.EmployeeService">
</bean>
@Resource(name="myCat") Set property by annotation in class, by-name In bean class, put @Resource on property or set function
@Resource(name="myCat")
private Cat myCat;
or
@Resource(name="myCat")
public void setMyCat(Cat myCat){
 this.myCat = myCat;
}
@Resource Auto-wire, find the property name as bean id from applicationContext.xml usage:
@Resource
EmployeeServiceInterface employeeService;
bean config:
<!-- Service Beans -->
<bean id="employeeService" class="com.gvace.service.impl.EmployeeService">
</bean>

Git

Pull
get latest code and merge
git pull

Fetch
get the latest code, require manually merge
this is better than pull, since we can check diff and decide to merge or not
git fetch
git log -p master..origin/master
git merge origin/master

Config
git config --global user.name "Yushan Lu"
git config --global user.email "lushan6999@gmail.com"

Create/Init a repository
git init

Add file
git add hello.txt

Commit
git commit -m "Commit1"

See log:
git status
git diff
git log
gitk

Change commit message
git commit --amend -m "Changes commit message"

Show remote repositories
git remote

Switch to branch
checkout master

See local branches
git branch

See local and remote branches
git branch -a

New branch
git branch newMyBranch


Stash
git stash


Push Conflict

We will get conflict error when the remote branch pushed by others
git push
So we can first pull
git pull origin master
Then use mergetool, choose meld or any editor to manually merge codes.
git mergetool
Then commit again, and push
git commit -m "Merged codes"
git push

Rebase
Git Rebase has two features
  • Combine multiple commits to one
    We can have multiple commits, but changes for one feature should stay in one commit, so the history is clean

    See log:   git log
    Merge last 3 commits:      git rebase -i HEAD~3
          Options:  pick|reword|edit|squash|fixup|exec|
                          or directly delete that line means cancel this commit
    Then :  git rebase (--continue | --abort | --skip | --amend)

    Do not commit again during this procedure, makes life easier.
  • Add one branch as a patch to another branch
    Different to merge, this will make cleaner commits history and keep change like within one route

    rebase the master: git rebase master


    example:
  • commit
    commit ...

    rebase commits for same feature(if necessary)

    stash un-commited changes (if necessary)
    git rebase master
    git push

Patch

Patch is good to use for large group of developers.
Developer generate a patch, then send the patch to project manager, or other developers to review.
Manager can apply patch.
If patch rejected, developer rebase the change and fetch to latest code, then generate the patch again.
Manager then apply the patch finally.

Suggest to use format-patch instead of git diff


Create one/more patch, based on commits
git format-patch origin/master
generated three patches
0001-Add-A.patch
0002-Add-B1.patch
0003-A-change.patch




Apply Patch

apply patch
git am 0001-Add-A.patch
or
git am --ignore-space-change --ignore-whitespace 0001-Add-A.patch

git add .
git commit -m "Apply patch"





Create a repository

mkdir mmm

cd mmm

git init

touch test.txt

git add .

git commit -m "create test.txt"


Clone from a repository, create a new branch

cd ..

mkdir m1

cd m1

git clone ~/servergit/mmm .

git branch m1

git checkout m1


Change the file

echo "fix from m1" >> test.txt

git add .

git commit -a -m "fix1"


Create a patch for master branch

git format-patch -m master

Apply patch on master branch

git checkout master

git am 0001-fix1.patch

git add .

git commit -m "apply fix"

























Spring Web character encoding

web.xml

Use filter:  org.springframework.web.filter.CharacterEncodingFilter provided by spring.


 <!-- Encoding with spring filter -->
 <filter>
  <filter-name>encoding</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>encoding</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

Saturday, April 9, 2016

Maven Eclipse

Config Maven Build
Eclipse Maven run on Tomcat with different port number

Run configurations -> Maven Build -> [Goals]:
 tomcat:run -Dmaven.tomcat.port=8081

So any change you made in webapp will immediately affect on server


Clean Project
Run Project -> Clean... 
Some time the project does not load changes, so run this to clean project first.



Run Maven Build
Right click on project -> Run As -> Maven Build

To deploy app to webserver

Spring 3 Hibernate 4 Struts 1.3 Maven

The example project is here:
https://github.com/ylu999/myssh6


1. New Maven Project
groupId: com.gvace
Archetype: org.apache.maven.archetypes
packaging:war

I faced some memory size issue when selecting Archetype, so I increased it in eclipse.ini.

  • -Xms512m
  • -Xmx1024m

2. Project Structure

3. pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.gvace</groupId>
 <artifactId>myssh6</artifactId>
 <packaging>war</packaging>
 <version>0.0.1-SNAPSHOT</version>
 <name>myssh6 Maven Webapp</name>
 <url>http://maven.apache.org</url>
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.build.mainClass>com.gvace.main</project.build.mainClass>
  <java.version>1.7</java.version>
  <spring.version>3.2.16.RELEASE</spring.version>
  <hibernate.version>4.1.7.Final</hibernate.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>javax.annotation</groupId>
   <artifactId>javax.annotation-api</artifactId>
   <version>1.2</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-orm</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context-support</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <!-- Spring Struts -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-struts</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <!--@Transactional -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-tx</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
   <version>${hibernate.version}</version>
  </dependency>
  <!-- <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-search</artifactId> 
   <version>4.1.1.Final</version> </dependency> -->
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-ehcache</artifactId>
   <version>${hibernate.version}</version>
  </dependency>
  <dependency>
   <groupId>net.sf.ehcache</groupId>
   <artifactId>ehcache-core</artifactId>
   <version>2.6.5</version>
  </dependency>
  <!-- connection pooling with c3p0 -->
  <dependency>
   <groupId>c3p0</groupId>
   <artifactId>c3p0</artifactId>
   <version>0.9.1.2</version>
  </dependency>

  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
  </dependency>

  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.38</version>
  </dependency>

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
   <scope>test</scope>
  </dependency>

  <dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib</artifactId>
   <version>3.1</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>${spring.version}</version>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>1.7.20</version>
  </dependency>
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-simple</artifactId>
   <version>1.7.20</version>
  </dependency>

  <!-- Struts 1.3 -->
  <dependency>
   <groupId>antlr</groupId>
   <artifactId>antlr</artifactId>
   <version>2.7.7</version>
  </dependency>
  <dependency>
   <groupId>bsf</groupId>
   <artifactId>bsf</artifactId>
   <version>2.3.0</version>
  </dependency>
  <dependency>
   <groupId>commons-beanutils</groupId>
   <artifactId>commons-beanutils</artifactId>
   <version>1.9.2</version>
  </dependency>
  <dependency>
   <groupId>commons-chain</groupId>
   <artifactId>commons-chain</artifactId>
   <version>1.2</version>
  </dependency>
  <dependency>
   <groupId>commons-digester</groupId>
   <artifactId>commons-digester</artifactId>
   <version>1.8.1</version>
  </dependency>
  <dependency>
   <groupId>commons-fileupload</groupId>
   <artifactId>commons-fileupload</artifactId>
   <version>1.1.1</version>
  </dependency>
  <dependency>
   <groupId>commons-io</groupId>
   <artifactId>commons-io</artifactId>
   <version>1.1</version>
  </dependency>
  <dependency>
   <groupId>commons-logging</groupId>
   <artifactId>commons-logging</artifactId>
   <version>1.0.4</version>
  </dependency>
  <dependency>
   <groupId>commons-validator</groupId>
   <artifactId>commons-validator</artifactId>
   <version>1.3.1</version>
  </dependency>
  <dependency>
   <groupId>commons-dbcp</groupId>
   <artifactId>commons-dbcp</artifactId>
   <version>1.2.2</version>
  </dependency>

  <dependency>
   <groupId>oro</groupId>
   <artifactId>oro</artifactId>
   <version>2.0.8</version>
  </dependency>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>
  <dependency>
   <groupId>org.apache.taglibs</groupId>
   <artifactId>taglibs-standard-impl</artifactId>
   <version>1.2.5</version>
  </dependency>
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts-core</artifactId>
   <version>1.3.10</version>
  </dependency>
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts-el</artifactId>
   <version>1.3.10</version>
  </dependency>
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts-extras</artifactId>
   <version>1.3.10</version>
  </dependency>
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts-faces</artifactId>
   <version>1.3.10</version>
  </dependency>
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts-mailreader-dao</artifactId>
   <version>1.3.10</version>
  </dependency>
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts-scripting</artifactId>
   <version>1.3.10</version>
  </dependency>
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts-taglib</artifactId>
   <version>1.3.10</version>
  </dependency>
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts-tiles</artifactId>
   <version>1.3.10</version>
  </dependency>
  <!-- -->
 </dependencies>
 <build>
  <finalName>myssh6</finalName>
 </build>
</project>





4. web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 <display-name>myssh6</display-name>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>
 
 <!-- Spring config
  classpath: starts from src folder
  -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <!-- <param-value>/WEB-INF/applicationContext.xml</param-value> -->
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!-- Initialize Spring Container -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- Struts -->
 <servlet>
  <servlet-name>struts</servlet-name>
  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  <load-on-startup>2</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>struts</servlet-name>
  <url-pattern>*.do</url-pattern>
 </servlet-mapping>
 <!-- Encoding with spring filter -->
 <filter>
  <filter-name>encoding</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>encoding</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
</web-app>


5. applicationContext.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:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx"
 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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
 >
 <!-- Enable Annotation -->
 <context:annotation-config/>
 <!-- Data Source -->
 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/myssh"/>
  <property name="username" value="root"/>
    <property name="password" value="root"/>
    <property name="initialSize" value="3"/>
    <property name="maxActive" value="500"/>
    <property name="maxIdle" value="2"/>
    <property name="minIdle" value="1"/>
 </bean>
 
 <!--Spring Cache--> 
 <!-- 
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" />
            </set>
        </property>
    </bean>
    -->
 <!-- Local Session Factory Bean -->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource"/>
  <property name="mappingResources">
   <list>
    <value>hbm/Employee.hbm.xml</value>
    <value>hbm/Department.hbm.xml</value>
   </list>
  </property>
  <property name="hibernateProperties">
   <value>
    hibernate.hbm2ddl.auto=update
    
    hibernate.dialect=org.hibernate.dialect.MySQLDialect
    hibernate.show_sql=true
    hibernate.format_sql=true
    
    hibernate.connection.CharSet=utf8
    hibernate.connection.characterEncoding=utf8
    hibernate.connection.useUnicode=true
    
    hibernate.generate_statistics=true
    hibernate.cache.use_structured_entries=true
    hibernate.cache.use_second_level_cache=true
    hibernate.cache.use_query_cache=true   
    hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
    net.sf.ehcache.configurationResourceName=/ehcache.xml
   </value>
  </property>
 </bean>
 <!-- Spring Transaction Manager -->
 <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory"></property>
 </bean>
 <!-- Start Transaction Annotation -->
 <tx:annotation-driven transaction-manager="transactionManager"/>
 
 <!-- Service Beans -->
 <bean id="employeeService" class="com.gvace.service.impl.EmployeeService">
  <!-- try annotation @Resource instead of here -->
  <!-- <property name="sessionFactory" ref="sessionFactory"/> -->
 </bean>
 <!-- Action
  set name with the action->path configured in struts-config.xml
  then you can delete the type property configured in struts-config.xml for this Action
  because we already set the class here
 -->
 <bean name="/login" class="com.gvace.web.action.LoginAction">
  <!-- add dependency of employeeServiceInterface -->
  <!-- try annotation @Resource instead of here -->
  <!-- <property name="employeeService" ref="employeeService"></property> -->
 </bean>
</beans>









6. struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
       "http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
 <form-beans>
  <form-bean name="loginForm" type="com.gvace.web.form.LoginForm"></form-bean>
 </form-beans>
 <action-mappings>
  <!-- localhost:8080/webapp/login.do, action path is the requested url path -->
  <!-- form-bean connect to the action identified by name -->
  <action path="/login" parameter="r" scope="request" name="loginForm"><!-- deleted type property since we have spring -->
   <!-- action choose which forward to go by forward name -->
   <forward name="ok" path="/WEB-INF/main.jsp"></forward>
   <forward name="err" path="/WEB-INF/err.jsp"></forward>
  </action>
 </action-mappings>
 <!-- set Proxy for the request control: DelegatingRequestProcessor -->
 <controller>
  <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor"/>
 </controller>
</struts-config>


7. ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
    monitoring="autodetect" dynamicConfig="true">
 
    <diskStore path="java.io.tmpdir/ehcache" />
 
    <defaultCache maxEntriesLocalHeap="10000" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30"
        maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU" statistics="true">
        <persistence strategy="localTempSwap" />
    </defaultCache>
 <!-- 
    <cache name="employee" maxEntriesLocalHeap="10000" eternal="false"
        timeToIdleSeconds="5" timeToLiveSeconds="10">
        <persistence strategy="localTempSwap" />
    </cache>
  -->
    <cache name="org.hibernate.cache.internal.StandardQueryCache"
        maxEntriesLocalHeap="5" eternal="false" timeToLiveSeconds="120">
        <persistence strategy="localTempSwap" />
    </cache>
 
    <cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
        maxEntriesLocalHeap="5000" eternal="true">
        <persistence strategy="localTempSwap" />
    </cache>
</ehcache>


8. log4j.properties
# Root logger option
log4j.rootLogger=INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=/home/yushan/javalog/logging.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
 
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n





Without config To get spring application context(Useless):

WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServlet().getServletContext());

































































































































































Sunday, April 3, 2016

Spring 3 + Hibernate 4 config


I faced some dependency issue:

Could not load requested class : org.hibernate.cache.ehcache.EhCacheRegionFactory

Thanks to
http://stackoverflow.com/questions/11905722/java-lang-noclassdeffounderror-org-hibernate-cache-entityregion-configuring-ehc
and its reference
http://web.archive.org/web/20130117102553/http://www.javacraft.org/2012/03/migrate-to-hibernate-4-ehcache.html

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>myssh</groupId>
 <artifactId>myssh</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>war</packaging>
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.build.mainClass>com.gvace.main</project.build.mainClass>
  <java.version>1.7</java.version>
  <spring.version>3.2.16.RELEASE</spring.version>
  <hibernate.version>4.1.7.Final</hibernate.version>

 </properties>
 <dependencies>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-orm</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <!--@Transactional -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-tx</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
   <version>${hibernate.version}</version>
  </dependency>
  <!-- 
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-search</artifactId>
   <version>4.1.1.Final</version>
  </dependency>
   -->
     <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-ehcache</artifactId>
       <version>${hibernate.version}</version>
     </dependency>
  <!-- connection pooling with c3p0 -->
  <dependency>
   <groupId>c3p0</groupId>
   <artifactId>c3p0</artifactId>
   <version>0.9.1.2</version>
  </dependency>

  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
  </dependency>

  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.38</version>
  </dependency>

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
   <scope>test</scope>
  </dependency>

  <dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib</artifactId>
   <version>3.1</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>${spring.version}</version>
   <scope>test</scope>
  </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.20</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.20</version>
    </dependency>
 </dependencies>
</project>


applicationContext.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:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx"
 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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
 >
 <!-- Data Source -->
 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/myssh"/>
  <property name="username" value="root"/>
    <property name="password" value="root"/>
    <property name="initialSize" value="3"/>
    <property name="maxActive" value="500"/>
    <property name="maxIdle" value="2"/>
    <property name="minIdle" value="1"/>
 </bean>
 
 <!--Spring Cache--><!-- 
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" />
            </set>
        </property>
    </bean>
-->    
 <!-- Local Session Factory Bean -->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource"/>
  <property name="mappingResources">
   <list>
    <value>com/gvace/domain/Employee.hbm.xml</value>
   </list>
  </property>
  <property name="hibernateProperties">
   <value>
    hibernate.hbm2ddl.auto=update
    
    hibernate.dialect=org.hibernate.dialect.MySQLDialect
    hibernate.show_sql=true
    hibernate.format_sql=true
    
    hibernate.connection.CharSet=utf8
    hibernate.connection.characterEncoding=utf8
    hibernate.connection.useUnicode=true
    
    hibernate.generate_statistics=true
    hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
    hibernate.cache.use_structured_entries=true
    hibernate.cache.use_second_level_cache=true
    hibernate.cache.use_query_cache=true   
   </value>
  </property>
 </bean>
 <!-- Spring Transaction Manager -->
 <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory"></property>
 </bean>
 <!-- Start Transaction Annotation -->
 <tx:annotation-driven transaction-manager="transactionManager"/>
 
 <!-- Service Beans -->
 <bean id="employeeService" class="com.gvace.service.impl.EmployeeService">
  <property name="sessionFactory" ref="sessionFactory"/>
 </bean>
</beans>












































Friday, April 1, 2016

Spring Dynamic Proxy

When calling getBean("xxx");
What is the class of returned object?

If target Bean class implements any interface:
Spring uses jdk dynamic proxy, returns like com.sun.proxy.$Proxy2

If target Bean class does not implements any interface:
Spring uses CGLIB to return