Tuesday, December 11, 2012

Mybatis integration with Spring 3.1 Framework.

Hi All,

I have configured new web project with mybatis and springframework several times. due to several project and being asked from team member to set up another project springframework skeleton. There are many advantage to start up from scratch. then you will know what it all means. But, When you need a quick start up, it would be good to have a project template.

As I have configured it several times. I improved of understanding of these framework setting then I made simple optimized web project template for share with others.

This sample will show the result of Json String.

I recommend you to look through below source roughly and download attached sample source to test running and understanding. it will run fine on tomcat I have tested. you will not need any db connection for sample code. below sample is running based on memory DB Hsql.

Sample Source is attached.
you can download from below link
Download

To integrate mybatis with Spring framework I recommend you to follow below step :

1. create java web project.
2. get all dependencies and configure classpath ( I am going to use maven )
2. configure springframework.
3. configure mybatis
4. create classes and xml ( Mapper interface, Mapper xml, Spring controller, create beans)
5. run it on tomcat or any WAS
6. check result


Directory Structure, you can refer below



Dependency Overview :




Maven Dependency : pom.xml
Springframework 3.1.3, Jackson Mapper 1.9.11, Hsql 2.2.8
I have excluded mybatis spring dependency which depends on old verion of springframework

<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>com.devtrigger</groupId>
 <artifactId>web-template</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>war</packaging>

 <name>Web Template Project, you can copy this and use for new project set up quickly</name>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <spring-version>3.1.3.RELEASE</spring-version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-orm</artifactId>
   <version>${spring-version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc-portlet</artifactId>
   <version>${spring-version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-oxm</artifactId>
   <version>${spring-version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>${spring-version}</version>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis-spring</artifactId>
   <version>1.1.1</version>
   <exclusions>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
    </exclusion>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-core</artifactId>
    </exclusion>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
    </exclusion>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-test</artifactId>
    </exclusion>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-tx</artifactId>
    </exclusion>
   </exclusions>
  </dependency>
  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
  </dependency>
  <dependency>
   <groupId>org.codehaus.jackson</groupId>
   <artifactId>jackson-mapper-asl</artifactId>
   <version>1.9.11</version>
  </dependency>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>javax</groupId>
   <artifactId>javaee-web-api</artifactId>
   <version>6.0</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>org.hsqldb</groupId>
   <artifactId>hsqldb</artifactId>
   <version>2.2.8</version>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
     <source>1.6</source>
     <target>1.6</target>
     <encoding>utf-8</encoding>
    </configuration>
   </plugin>
   <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.2</version>
   </plugin>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-eclipse-plugin</artifactId>
    <version>2.8</version>
    <configuration>
     <additionalProjectFacets>
      <jst.web>2.5</jst.web>
     </additionalProjectFacets>
     <downloadJavadocs>true</downloadJavadocs>
     <downloadSources>true</downloadSources>
     <wtpContextName>/</wtpContextName>
     <wtpdefaultserver>${eclipse.wtpdefaultserver}</wtpdefaultserver>
     <wtpversion>2.0</wtpversion>
    </configuration>
   </plugin>
  </plugins>
 </build>
</project>


Mybatis configuration : mybatis-context.xml
If you comment out or in, you can change datasource.
I have prepared sample for JDNI, JDBC and Hsql datasources which are all tested. Currently, It is running on Hsql for simple sample running on your memory based DB.
<?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:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/jdbc
        http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">

 <!-- JNDI datasource -->
 <!-- 
 <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> 
  <property name="jndiName" value="jdbc/oraclePool"/>
  <property name="resourceRef" value="true" />
 </bean> 
  -->
 
 <!-- Hsql datasource -->
 <!--
 -->
 <jdbc:embedded-database id="dataSource" >
  <jdbc:script location="classpath:hsql/schema.sql"/>
  <jdbc:script location="classpath:hsql/data.sql"/>
 </jdbc:embedded-database>

 <!-- JDBC datasource -->
 <!--
 <bean id="dataSource"
  class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
  <property name="driverClass" value="oracle.jdbc.OracleDriver" />
  <property name="url" value="jdbc:oracle:thin:@HOST:1111:ORA" />
  <property name="username" value="ID" />
  <property name="password" value="PASSWORD" />
 </bean>
 -->

 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="typeAliasesPackage" value="com.devtrigger.model" />
  <property name="mapperLocations" value="classpath*:dao/**/*.xml" />
 </bean>

 <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  <constructor-arg index="0" ref="sqlSessionFactory" />
 </bean>

 <!-- scan for mapper interface files and let them be autowired -->
 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="com.devtrigger.dao" />
 </bean>

 <bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource" />
 </bean>

</beans>



XML Mapper : JobMapper.xml
You need to write your actual sql queries. value will be replace by "#{property}"
"<property name="typeAliasesPackage" value="com.devtrigger.model" />" is configured on mybatis-context.xml to make it short to write of bean name. You would need to write "com.devtrigger.model.JobInfo" for using a java bean or need to be used typeAlias. Please aware that "jobInfo" is id of result map, "JobInfo" is a java bean.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.devtrigger.dao.JobMapper">

 <cache />

 <resultMap type="JobInfo" id="jobInfo">
  <result property="id" column="id" />
  <result property="panNumber" column="pan_number" />
  <result property="address" column="address" />
  <result property="city" column="city" />
  <result property="state" column="state" />
  <result property="pincode" column="pincode" />
 </resultMap>

 <select id="selectAll" resultMap="jobInfo">
  <![CDATA[
  select id, pan_number, address, city, state, pincode
  from JBT_MEM
  ]]>
 </select>

 <insert id="insert" parameterType="JobInfo">
  <![CDATA[
  insert into JBT_MEM values(#{id}, #{pan_number}, #{address}, #{city}, #{state}, #{pincode})
  ]]>  
 </insert>

 <update id="update" parameterType="JobInfo">
  <![CDATA[
  ]]> 
 </update>


 <delete id="delete" parameterType="JobInfo">
  <![CDATA[
  ]]> 
 </delete>
</mapper>


Mapper Interface : JobInfo.java
you need to have interface for mapping with Mapper xml file. the method name id must mapped with ID of SQL described in the mapper xml.
package com.devtrigger.dao;

import java.util.List;

import com.devtrigger.model.JobInfo;

public interface JobMapper {

 List<JobInfo> selectAll();
 int insert(JobInfo sampleInfo);
 int update(JobInfo sampleInfo);
 int delete(JobInfo sampleInfo);
}


Spring Controller : IndexController.java

package com.devtrigger.controller;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.devtrigger.model.JobInfo;
import com.devtrigger.service.JobService;

@Controller
public class IndexController {

 private final Log log = LogFactory.getLog(this.getClass());

 @Autowired
 private JobService jobService;
 
 @RequestMapping(value = "/index")
 @ResponseBody
 public List<JobInfo> requestIndex(){
  
  log.debug("controller is called");
  return jobService.getSampleInfo();
 }
 
}



type URL "http://localhost:8080/index.do" on your browser then you will see Json String returns. The reason I show Json result instead of jsp servlet result is, because you will find many sample on internet for jsp servlet result return
BTW, you need to put your jsp file under "/WEB-INF/jsp/" if you need.

[{"id":"1","panNumber":"AABBAABB","address":"Address","city":"NY","state":"AB","pincode":23500},{"id":"2","panNumber":"BGDBCBDB","address":"Address","city":"LA","state":"St","pincode":23500}]



Friday, November 23, 2012

Sample http/https connection with Apache HttpComponents in java

Hi All
While I am building common project for our team. I think it would be worth it to share with others. even it just started to build though.

I remember few times that url connection's destination server has been down for few hours and our service also effected due to the destination server down. because, we didn't set any time out for url connection. which consumed all of JVM thread and the result was, Stuck Thread occured, no thread from thread pool.

For building url connection. better set time out.

There are few things more consider to make a URL connection.
- stable, stable, stable
- in case of no response from destination server for long time, it should close connection
- http connection pooling
- https connection
- connection via proxy
- via credential access


The reason to make this source is, Apache httpclient is very powerful for making url connection, but without looking into detail, it is difficult to use right a way.



Source code structure :

Maven Dependency : pom.xml file
<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.devtrigger</groupId>
 <artifactId>sample</artifactId>
 <packaging>jar</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>sample</name>
 <url>http://maven.apache.org</url>
 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.10</version>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.2.2</version>
  </dependency>
  <dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-lang3</artifactId>
   <version>3.1</version>
  </dependency>
  <dependency>
   <groupId>commons-configuration</groupId>
   <artifactId>commons-configuration</artifactId>
   <version>1.9</version>
  </dependency> 
  <dependency>
   <groupId>org.codehaus.jackson</groupId>
   <artifactId>jackson-mapper-asl</artifactId>
   <version>1.9.11</version>
  </dependency>   
 </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-eclipse-plugin</artifactId>
    <version>2.8</version>
    <configuration>
     <downloadJavadocs>true</downloadJavadocs>
     <downloadSources>true</downloadSources>
    </configuration>
   </plugin>            
        </plugins>
    </build>  
</project>
Configuration : conf.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<sample>
 <proxyServer>
  192.168.1.1
 </proxyServer>
 <proxyPort>
  8080
 </proxyPort>
</sample>
HttpClientService.java
package com.devtrigger;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

public class HttpClientService {

 private static XMLConfiguration config;

 private static final int CONNECTION_TIMEOUT = 10000;
 private static final int SOCKET_TIMEOUT = 60000;

 private static HttpClientService httpClientService = new HttpClientService(); 
 
 private HttpClientService() {
  try {
   config = new XMLConfiguration("config.xml");
  } catch (ConfigurationException e) {
   e.printStackTrace();
  }
 }
 
 public static HttpClientService getInstance(){
  return httpClientService;
 }
 
 /**
  * @return
  */
 DefaultHttpClient getHttpClient() {
  return getHttpClient(CONNECTION_TIMEOUT, SOCKET_TIMEOUT);
 }

 /**
  * @param domain
  * @param userName
  * @param password
  * @return
  */
 DefaultHttpClient getHttpClient(String domain, String userName, String password){
  
  DefaultHttpClient httpClient = getHttpClient();
  
  httpClient.getCredentialsProvider().setCredentials(
                new AuthScope(domain, 443),
                new UsernamePasswordCredentials(userName, password));
  
  return httpClient;
 }
 /**
  * @param connectionTimeOut
  * @param sockeTimeOut
  * @return
  */
 private DefaultHttpClient getHttpClient(int connectionTimeOut, int sockeTimeOut) {
  try {

   HttpParams httpParams = new BasicHttpParams();
   
   setParams(httpParams, connectionTimeOut, sockeTimeOut);
   
   SSLSocketFactory sf = new SSLSocketFactory(new TrustStrategy() {
    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
     return true;
    }
   }, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
   
   SchemeRegistry registry = new SchemeRegistry();
   registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
   registry.register(new Scheme("https", 443, sf));

   ClientConnectionManager ccm = new PoolingClientConnectionManager(registry);
   
   return new DefaultHttpClient(ccm, httpParams);
  } catch (Exception e) {
   return new DefaultHttpClient();
  }
 } 
 
 /**
  * @param httpParams
  * @param connectionTimeOut
  * @param sockeTimeOut
  */
 private void setParams(HttpParams httpParams, int connectionTimeOut, int sockeTimeOut){
  
  setHttpProxy(httpParams);
  setHttpProtocolParams(httpParams);
  setHttpConnectionParams(httpParams, connectionTimeOut, sockeTimeOut);
  
  httpParams.setBooleanParameter("http.protocol.expect-continue", false);
 }
 
 /**
  * @param httpParams
  */
 private void setHttpProxy(HttpParams httpParams) {
  
  String proxyHost = config.getString("proxyServer");

  if (!StringUtils.isEmpty(proxyHost)) {
   int proxyPort = Integer.parseInt(config.getString("proxyPort"));
   HttpHost proxy = new HttpHost(proxyHost, proxyPort);
   httpParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
  }  
  
 }

 /**
  * @param httpParams
  */
 private void setHttpProtocolParams(HttpParams httpParams){
  HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
  HttpProtocolParams.setContentCharset(httpParams, "utf-8");
 }
 
 /**
  * @param httpParams
  * @param connectionTimeOut
  * @param sockeTimeOut
  */
 private void setHttpConnectionParams(HttpParams httpParams, int connectionTimeOut, int sockeTimeOut){
  HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeOut);
  HttpConnectionParams.setSoTimeout(httpParams, sockeTimeOut);
 }
  
}


HttpRequestService.java

package com.devtrigger;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

public class HttpRequestService {

 HttpClientService httpClientService = HttpClientService.getInstance();
 
 private final Log log = LogFactory.getLog(this.getClass());

 ObjectMapper objectMapper = new ObjectMapper();
 
 private boolean useCredential = false; 
 
 private String domain;
 
 private String userName;
 
 private String password;
 
 
 private boolean isUseCredential() {
  return useCredential;
 }

 private void setUseCredential(boolean useCredential) {
  this.useCredential = useCredential;
 }

 private String getDomain() {
  return domain;
 }

 private void setDomain(String domain) {
  this.domain = domain;
 }

 private String getUserName() {
  return userName;
 }

 private void setUserName(String userName) {
  this.userName = userName;
 }

 private String getPassword() {
  return password;
 }

 private void setPassword(String password) {
  this.password = password;
 }

 public void enableUseCredential(String domain, String userName, String password){
  
  setDomain(domain);
  setUserName(userName);
  setPassword(password);
  setUseCredential(true);
 }
 
 public String doGetRequestNgetResponseBody(String url) {
  return doGetRequestNgetResponseBody(url, new ArrayList
()); } /** * @param context * @param url * @param headerList * @return */ public String doGetRequestNgetResponseBody(String url, List
headerList) { URI uri = null; try { uri = new URI(url); } catch (URISyntaxException e) { e.printStackTrace(); } HttpGet get = new HttpGet(uri); for (Header header : headerList) { get.addHeader(header); } return getResponseBody(get); } /** * @param context * @param url * @param headerList * @return */ public HttpResponse doGetRequestNgetResponse(String url, List
headerList) { URI uri = null; try { uri = new URI(url); } catch (URISyntaxException e) { e.printStackTrace(); } HttpGet get = new HttpGet(uri); for (Header header : headerList) { get.addHeader(header); } return getResponse(get); } /** * @param context * @param url * @return */ public HttpResponse doGetRequestNgetResponse(String url) { URI uri = null; try { uri = new URI(url); } catch (URISyntaxException e) { e.printStackTrace(); } HttpGet get = new HttpGet(uri); return getResponse(get); } /** * @param context * @param url * @param params * @return */ public String doPostRequestNgetResponseBody(String url, List params) { HttpPost post = new HttpPost(url); UrlEncodedFormEntity ent = null; try { ent = new UrlEncodedFormEntity(params); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponseBody(post); } /** * @param context * @param url * @param params * @return */ public HttpResponse doPostRequestNgetResponse(String url, List params) { HttpPost post = new HttpPost(url); UrlEncodedFormEntity ent = null; try { ent = new UrlEncodedFormEntity(params); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponse(post); } /** * @param context * @param url * @param jsonParams * @return */ public String doPostRequestNgetResponseBody(String url, Object jsonObject) { HttpPost post = new HttpPost(url); StringEntity ent = null; try { log.debug(objectMapper.writeValueAsString(jsonObject)); ent = new StringEntity(objectMapper.writeValueAsString(jsonObject)); ent.setContentType("application/json"); } catch (JsonGenerationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JsonMappingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponseBody(post); } /** * @param context * @param httpRequest * @return */ private String getResponseBody(HttpRequestBase httpRequest) { HttpResponse response = getResponse(httpRequest); return getResponseBody(response); } /** * It returns response body string * * @param response * @return */ public String getResponseBody(HttpResponse response) { HttpEntity resEntity = null; if (response != null) resEntity = response.getEntity(); if (resEntity != null) { try { return EntityUtils.toString(resEntity); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return ""; } public boolean saveResponseBodyStream(HttpResponse response, String filePath) { boolean result = false; HttpEntity resEntity = null; if (response != null) resEntity = response.getEntity(); if (resEntity != null) { BufferedInputStream bis; try { bis = new BufferedInputStream(resEntity.getContent()); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(filePath))); int inByte; while ((inByte = bis.read()) != -1) bos.write(inByte); bis.close(); bos.close(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return result; } /** * @param context * @param url * @param headerList * @return */ public HashMap doGetRequestNgetResponseHeader(String url, List
headerList) { URI uri = null; try { uri = new URI(url); } catch (URISyntaxException e) { e.printStackTrace(); } HttpGet get = new HttpGet(uri); for (Header header : headerList) { get.addHeader(header); } return getResponseHeader(get); } /** * @param context * @param url * @param params * @return */ public HashMap doPostRequestNgetResponseHeader(String url, List params) { HttpPost post = new HttpPost(url); UrlEncodedFormEntity ent = null; try { ent = new UrlEncodedFormEntity(params); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponseHeader(post); } /** * @param context * @param httpRequest * @return */ private HashMap getResponseHeader(HttpRequestBase httpRequest) { HttpResponse response = getResponse(httpRequest); return getResponseHeader(response); } /** * @param response * @param headerName * @return */ public String getResponseHeaderValue(HttpResponse response, String headerName) { HashMap header = getResponseHeader(response); return (String) header.get(headerName); } /** * @param response * @return */ public HashMap getResponseHeader(HttpResponse response) { if (response != null) { Header[] headers = response.getAllHeaders(); return converHeaders2Map(headers); } else { return new HashMap(); } } /** * when response parameter is null, it will return 410 Gone status. * * @param response * @return */ public int getResponseCode(HttpResponse response) { if (response != null) { return response.getStatusLine().getStatusCode(); } else { return HttpStatus.SC_GONE; } } /** * @param headers * @return */ private HashMap converHeaders2Map(Header[] headers) { HashMap hashMap = new HashMap(); for (Header header : headers) { hashMap.put(header.getName(), header.getValue()); } return hashMap; } /** * @param context * @param httpRequest * @return */ public HttpResponse getResponse(HttpRequestBase httpRequest) { HttpClient httpClient = null; if(!isUseCredential()){ httpClient = httpClientService.getHttpClient(); }else{ httpClient = httpClientService.getHttpClient(getDomain(), getUserName(), getPassword()); setUseCredential(false); } HttpResponse response = null; try { response = httpClient.execute(httpRequest); } catch (ClientProtocolException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } return response; } }



HttpRequestTest.java for Junit test run.
package com.devtrigger;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Assert;
import org.junit.Test;

public class HttpRequestTest {

  private final Log logger = LogFactory.getLog(this.getClass());
 
 @Test
 public void testRequest(){
 
  HttpRequestService service = new HttpRequestService();
  String response = service.doGetRequestNgetResponseBody("http://www.google.com/");
  
  logger.debug("response : " + response);
  
  Assert.assertTrue(response.substring(0, 20).matches(".*(?i)(HtMl).*"));
  
 }
 
}


Test Success

In the end, you can just use like this on your source code.
HttpRequestService service = new HttpRequestService();
String response = service.doGetRequestNgetResponseBody("http://www.google.com/");
further more, you can do post request with header vales or json http body request so on. probably you would need to extend more method.

I hope it helps :) even though, it is not optimized and refactored.



@Add Dec 4th 2012
I have simply looped the test cases 1000 times to my local server.
It worked well and look into regarding to if it is threadsafe and concurrent. It is thread safe. I need to look into more, it's not easy for me to follow up this. you can get more detail info below
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html
"HttpClient assumes complete control over the process of connection initialization and termination as well as I/O operations on active connections. However various aspects of connection operations can be influenced using a number of parameters."

http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/PoolingClientConnectionManager.html
"PoolingConnectionManager maintains a maximum limit of connection on a per route basis and in total. Per default this implementation will create no more than than 2 concurrent connections per given route and no more 20 connections in total. For many real-world applications these limits may prove too constraining, especially if they use HTTP as a transport protocol for their services. Connection limits, however, can be adjusted using HTTP parameters."

Monday, November 5, 2012

How to use Maven Module, Example from Spring Batch


I have tried to use maven module for related project set up in once. but, I was not able to find good sample or answer for me. So I opened up well known open source project source files who uses maven. I found one from Spring Batch.

Benefit for using maven module :
I can manage related dependencies version number in once
Several projects can be setup once in your IDE.
Your IDE (ex: eclipse ) will look the module project which applies your latest changes between the projects.
My team member will get all these benefit. Also I can save time to help team member.

It is little long to follow, so, I will explain as simple as possible for easy understanding.

Directory Structure

/juno_workspace/SpringSource-spring-batch-326da17$ find ./ -name 'pom.xml'
./pom.xml
./spring-batch-parent/pom.xml
./spring-batch-core/pom.xml
./spring-batch-infrastructure/pom.xml


./pom.xml file


The point from this file is, "packaging" is set to "pom" and defines "modules"
<?xml version="1.0" encoding="UTF-8"?>
<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>org.springframework.batch</groupId>
 <artifactId>spring-batch</artifactId>
 <name>Spring Batch</name>
 <description>Spring Batch provides tools for enterprise batch or bulk processing. It can be used to wire up jobs, and track
 their execution, or simply as an optimization for repetitive processing in a transactional environment. Spring Batch is part of the Spring Portfolio.</description>
 <version>2.2.0.BUILD-SNAPSHOT</version>
 <packaging>pom</packaging>
 <modules>
  <module>spring-batch-parent</module>
  <module>spring-batch-infrastructure</module>
  <module>spring-batch-core</module>
  <module>spring-batch-test</module>
 </modules>


./spring-batch-parent/pom.xml file


The point from this file is, "packaging" is set to "pom" and defines "dependencyManagement"
<?xml version="1.0" encoding="UTF-8"?>
<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>org.springframework.batch</groupId>
 <artifactId>spring-batch-parent</artifactId>
 <version>2.2.0.BUILD-SNAPSHOT</version>
 <name>Spring Batch Parent</name>
 <description>Spring Batch parent project.  Defines dependencies and common configuration for the build process.</description>
 <url>http://static.springframework.org/spring-batch/${project.artifactId}</url>
 <packaging>pom</packaging>
...

 <dependencyManagement>
  <dependencies>
...
   <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.5.4</version>
   </dependency>
...



./spring-batch-core/pom.xml file


The point from this file is, "packaging" is set to "jar" and defines parent
<?xml version="1.0" encoding="UTF-8"?>
<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>
 <artifactId>spring-batch-infrastructure</artifactId>
 <packaging>jar</packaging>
 <name>Infrastructure</name>
 <description><![CDATA[The Spring Batch Infrastructure is a set of 
 low-level components, interfaces and tools for batch processing 
 applications and optimisations.]]>
 </description>
 <url>http://static.springframework.org/spring-batch/${project.artifactId}</url>
 <parent>
  <groupId>org.springframework.batch</groupId>
  <artifactId>spring-batch-parent</artifactId>
  <version>2.2.0.BUILD-SNAPSHOT</version>
  <relativePath>../spring-batch-parent</relativePath>
 </parent>
...
 <dependencies>
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <optional>true</optional>
  </dependency>
...


./spring-batch-infrastructure/pom.xml file


The point from this file is, "packaging" is set to "jar" and defines parent
<?xml version="1.0" encoding="UTF-8"?>
<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>
 <artifactId>spring-batch-core</artifactId>
 <packaging>jar</packaging>
 <name>Core</name>
 <description>Core domain for batch processing, expressing a domain of Jobs, Steps, Chunks, etc.</description>
 <url>http://static.springframework.org/spring-batch/${project.artifactId}</url>
 <parent>
  <groupId>org.springframework.batch</groupId>
  <artifactId>spring-batch-parent</artifactId>
  <version>2.2.0.BUILD-SNAPSHOT</version>
  <relativePath>../spring-batch-parent</relativePath>
 </parent>
...
 <dependencies>
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <optional>true</optional>
  </dependency>
...


Additionally,


You can see, there is no version number described for "aspectjweaver" on "./spring-batch-core/pom.xml" and "./spring-batch-infrastructure/pom.xml" file. because the version number is described on "./spring-batch-parent/pom.xml" file in "dependencyManagement". That you can manage version number in once. It will be great to manage version number like Junit or common libraries

you can run mvn eclipse:eclipse and import the project on your eclipse. I will post detail how to import project for the next.

Saturday, September 29, 2012

customized log4j.property location by adding system property

I put log4j.properties in classpath, but it is not located classpath root directory. I put all properties into properties directory to keep root classpath organized clean structure. Since I moved the log4j.properties file, log4j makes error when process start up. I had to put below line which add system property.
-Dlog4j.configuration="properties/log4j.properties" then it works well now.

LIB_HOME=/home01/batch/batch/common_lib
JAVA_HOME=/home02/bea10/jdk160_24

CLASSPATH=${LIB_HOME}/activation-1.1.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/api.services-50.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/axis-1.4.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/axis-jaxrpc-1.4.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/axis-saaj-1.4.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/axis-wsdl4j-1.5.1.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/commons-beanutils-1.8.3.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/commons-digester-1.8.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/commons-discovery-0.2.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/commons-lang-2.6.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/commons-logging-1.0.4.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/commons-net-3.1.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/commons-validator-1.4.0.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/ibatis-sqlmap-2.3.4.726.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/log4j-1.2.16.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/mail-1.4.5.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/server.service-1.0.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/servlet-api-2.5.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/ojdbc6.jar
CLASSPATH=${CLASSPATH}:${LIB_HOME}/uk_batch.jar

export CLASSPATH 
sdate=`date +'%Y%m%d'`
stime=`date +'%H%M%S'`

${JAVA_HOME}/bin/java -Dlog4j.configuration="properties/log4j.properties" -cp ${CLASSPATH} batch.Run


Android http/https connection sample code

Http/Https connection is necessary to build a Android application for interact with web server. To make http connection, I made 2 simple java classes.
It is working well and tested on android SDK 15 version and it will probably work the other version as well. I hope it can save your time.

You can call "doPostRequestNgetResponseBody" method or similar in your android Activity class. you can find more method from "HttpClientUtil" class.

String url = "https://yoursite";
ArrayList<BasicNameValuePair> arrayList = new ArrayList<BasicNameValuePair>();
  
arrayList.add(new BasicNameValuePair("your param name", "your param value"));

String responseBody = HttpRequestUtil.doPostRequestNgetResponseBody(context, url, arrayList);


To call the method, you need to have below 2 classes. HttpClientUtil.java : return http/https connection client.
package com.jackapps.http;

import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

import android.content.Context;
import android.net.SSLCertificateSocketFactory;
import android.net.SSLSessionCache;

public class HttpClientUtil {

 private static final int CONNECTION_TIMEOUT = 5000;
 private static final int SOCKET_TIMEOUT = 20000;
 

 /**
  * @param context
  * @return
  */
 static HttpClient getHttpClient(Context context) {
  return getHttpClient(context, CONNECTION_TIMEOUT, SOCKET_TIMEOUT);
 }
 
 /**
  * @param context
  * @param connectionTimeOut
  * @param sockeTimeOut
  * @return
  */
 static synchronized HttpClient getHttpClient(Context context, int connectionTimeOut, int sockeTimeOut) {
  
  // Use a session cache for SSL sockets
  SSLSessionCache sessionCache = context == null ? null : new SSLSessionCache(context);

  // sets up parameters
  HttpParams httpParams = new BasicHttpParams();
  
  setHttpProtocolParams(httpParams);
  setHttpConnectionParams(httpParams, connectionTimeOut, sockeTimeOut);
  
  httpParams.setBooleanParameter("http.protocol.expect-continue", false);

  // registers schemes for both http and https
  SchemeRegistry registry = new SchemeRegistry();
  registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
  
  final SSLSocketFactory sslSocketFactory = SSLCertificateSocketFactory.getHttpSocketFactory(sockeTimeOut,
    sessionCache);

  // sslSocketFactory.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
  sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

  registry.register(new Scheme("https", sslSocketFactory, 443));

  ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(httpParams, registry);
  
  return new DefaultHttpClient(manager, httpParams);
 }
 
 /**
  * @param httpParams
  */
 private static void setHttpProtocolParams(HttpParams httpParams){
  HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
  HttpProtocolParams.setContentCharset(httpParams, "utf-8");
 }
 
 /**
  * @param httpParams
  * @param connectionTimeOut
  * @param sockeTimeOut
  */
 private static void setHttpConnectionParams(HttpParams httpParams, int connectionTimeOut, int sockeTimeOut){
  HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeOut);
  HttpConnectionParams.setSoTimeout(httpParams, sockeTimeOut);
 }
 
}


HttpRequestUtil.java : return response body, headers
package com.jackapps.http;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import android.content.Context;

import com.jackapps.model.AccessTokenInfo;

public class HttpRequestUtil {

 /**
  * @param context
  * @param url
  * @param headerList
  * @return
  */
 public static String doGetRequestNgetResponseBody(Context context, String url, List
headerList) { URI uri = null; try { uri = new URI(url); } catch (URISyntaxException e) { e.printStackTrace(); } HttpGet get = new HttpGet(uri); for (Header header : headerList) { get.addHeader(header); } return getResponseBody(context, get); } /** * @param context * @param url * @param headerList * @return */ public static HttpResponse doGetRequestNgetResponse(Context context, String url, List
headerList) { URI uri = null; try { uri = new URI(url); } catch (URISyntaxException e) { e.printStackTrace(); } HttpGet get = new HttpGet(uri); for (Header header : headerList) { get.addHeader(header); } return getResponse(context, get); } /** * @param context * @param url * @param params * @return */ public static String doPostRequestNgetResponseBody(Context context, String url, List params) { HttpPost post = new HttpPost(url); UrlEncodedFormEntity ent = null; try { ent = new UrlEncodedFormEntity(params, HTTP.UTF_8); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponseBody(context, post); } /** * @param context * @param url * @param params * @return */ public static HttpResponse doPostRequestNgetResponse(Context context, String url, List params) { HttpPost post = new HttpPost(url); UrlEncodedFormEntity ent = null; try { ent = new UrlEncodedFormEntity(params, HTTP.UTF_8); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponse(context, post); } /** * @param context * @param url * @param jsonParams * @return */ public static String doPostRequestNgetResponseBody(Context context, String url, JSONObject jsonParams) { HttpPost post = new HttpPost(url); StringEntity ent = null; try { ent = new StringEntity(jsonParams.toString(), HTTP.UTF_8); ent.setContentType("application/json"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponseBody(context, post); } /** * @param context * @param url * @param jsonParams * @return */ public static HttpResponse doPostRequestNgetResponse(Context context, String url, JSONObject jsonParams) { HttpPost post = new HttpPost(url); StringEntity ent = null; try { ent = new StringEntity(jsonParams.toString(), HTTP.UTF_8); ent.setContentType("application/json"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponse(context, post); } /** * @param context * @param httpRequest * @return */ private static String getResponseBody(Context context, HttpRequestBase httpRequest) { HttpResponse response = getResponse( context, httpRequest); return getResponseBody(response); } /** * It returns response body string * @param response * @return */ public static String getResponseBody(HttpResponse response) { HttpEntity resEntity = null; if (response != null) resEntity = response.getEntity(); if (resEntity != null) { try { return EntityUtils.toString(resEntity); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return ""; } /** * @param context * @param url * @param headerList * @return */ public static HashMap doGetRequestNgetResponseHeader(Context context, String url, List
headerList) { URI uri = null; try { uri = new URI(url); } catch (URISyntaxException e) { e.printStackTrace(); } HttpGet get = new HttpGet(uri); for (Header header : headerList) { get.addHeader(header); } return getResponseHeader(context, get); } /** * @param context * @param url * @param params * @return */ public static HashMap doPostRequestNgetResponseHeader(Context context, String url, List params) { HttpPost post = new HttpPost(url); UrlEncodedFormEntity ent = null; try { ent = new UrlEncodedFormEntity(params, HTTP.UTF_8); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponseHeader(context, post); } /** * @param context * @param url * @param jsonParams * @return */ public static HashMap doPostRequestNgetResponseHeader(Context context, String url, JSONObject jsonParams) { HttpPost post = new HttpPost(url); StringEntity ent = null; try { ent = new StringEntity(jsonParams.toString(), HTTP.UTF_8); ent.setContentType("application/json"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (ent != null) post.setEntity(ent); return getResponseHeader(context, post); } /** * @param context * @param httpRequest * @return */ private static HashMap getResponseHeader(Context context, HttpRequestBase httpRequest) { HttpResponse response = getResponse( context, httpRequest); return getResponseHeader(response); } /** * @param response * @param headerName * @return */ public static String getResponseHeaderValue(HttpResponse response, String headerName){ HashMap header = getResponseHeader(response); return (String)header.get(headerName); } /** * @param response * @return */ public static HashMap getResponseHeader(HttpResponse response) { if (response != null){ Header[] headers = response.getAllHeaders(); return converHeaders2Map(headers); }else{ return new HashMap(); } } /** * when response parameter is null, it will return 410 Gone status. * @param response * @return */ public static int getResponseCode(HttpResponse response) { if (response != null){ return response.getStatusLine().getStatusCode(); }else{ return HttpStatus.SC_GONE; } } /** * @param headers * @return */ private static HashMap converHeaders2Map(Header[] headers){ HashMap hashMap = new HashMap(); for(Header header: headers){ hashMap.put(header.getName(), header.getValue()); } return hashMap; } /** * @param context * @param httpRequest * @return */ public static HttpResponse getResponse(Context context, HttpRequestBase httpRequest) { HttpClient httpClient = HttpClientUtil.getHttpClient(context); HttpResponse response = null; try { response = httpClient.execute(httpRequest); } catch (ClientProtocolException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } return response; } }

Thursday, August 30, 2012

SVN backup on Unix or Solaris


I made a simple script to backup SVN shell script. It is working on ssh terminal on my session well. but when it run by crontab. it is not running and leave no error message. It was difficult to solve this issue if there is no error message.

My colleague who is expert Unix system gave me an advice, check email on Unix. I have searched how to check email on Unix. time by time I am noticed that there is new email. I didn't know I can read that from the server.

'mailx' this is the command to check email. then you can select number to read email. I found the log from crontab, it seems few library and command it not found. I copy PATH, LD_LIBRARY_PATH, LD_RUN_PATH variables to shell script. you can get the variable definition when you type 'env'

In the end, it's running.

#!/bin/ksh
datum=`/bin/date +%Y%m%d`
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/sfw/lib:/usr/local/lib:/usr/dt/lib:/usr/share/lib:/usr/ccs/lib:/
usr/local/ssl/lib:/usr/local/instantclient10_1_32bit:/opt/coolstack/apache2/lib:/usr/local/apr/lib

PATH=/usr/sbin:/usr/bin:/usr/ucb:/opt/sunstudio12.1/bin:/opt/csw/bin/:/opt/csw/mysql51/bin/sparcv8:
/opt/coolstack/bin:/usr/local/bin:/usr/sbin:/usr/ccs/bin:/usr/sfw/bin:/usr/local/php/bin:/usr/ucb:/
opt/sunstudio12.1/bin:/opt/csw/bin/:/opt/csw/mysql51/bin/sparcv8:/opt/coolstack/bin:/usr/local/bin:
/usr/sbin:/usr/ccs/bin:/usr/sfw/bin:/usr/local/php/bin

LD_RUN_PATH=:usr/local/BerkeleyDB.4.8/lib

export LD_LIBRARY_PATH
export PATH
export LD_RUN_PATH

/usr/local/bin/svnadmin dump /home/svn/sfc > /home/backup_nas/svn/sfc_$datum.dump



- SVN Backup
nohup svnadmin dump /home/svn/sfc > /home/backup_all/svn/sfc.dump &


- SVN incremental Backup
$ svnadmin dump myrepos --revision 0:1000 > dumpfile1
$ svnadmin dump myrepos --revision 1001:2000 --incremental > dumpfile2
$ svnadmin dump myrepos --revision 2001:3000 --incremental > dumpfile3
svnadmin dump  -r 58:HEAD --deltify >  


- SVN recovery
svnadmin load < ~/repos-0-1000.svn_dump
svnadmin load < ~/repos-1000-2000.svn_dump
svnadmin load < ~/repos-2000-3000.svn_dump


- SVN revision pack per 1000 revision
svnadmin pack /home/svn/sfc


- SVN repository create
/usr/local/bin/svnadmin create path/to/repos


- SVN daemon shutdown
pkill -KILL svnserve


- SVN daemon start
svnserve -d -r /home/svn/

Thursday, July 19, 2012

Maven java project archetype


If you use maven, you like to use archetype to get all benefits of maven.
To create maven java project, you can use below command below.

It's an example to create sample archetype.

mvn archetype:generate -DgroupId=com.example -DartifactId=test -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false




Then you can simply go under test directory and run below command
mvn eclipse:eclipse


After that, simply import this project into eclipse



Monday, June 18, 2012

how to find byte code class file JDK compiled java version

you can find out the byte code class version.

On Linux, Mac OS X or Windows with Cygwin installed, the file(1) command knows the class version. Extract a class from a jar and use file to identify it:

$ jar xf log4j-1.2.15.jar
$ file ./org/apache/log4j/Appender.class
./org/apache/log4j/Appender.class: compiled Java class data, version 45.3

A different class version, for example:

root@mypc:/merchant-sample/classes/com/paypal/core$ file SSLUtil.class 
SSLUtil.class: compiled Java class data, version 50.0 (Java 1.6)


The class version major number corresponds to the following Java JDK versions:

46 = Java 1.2
47 = Java 1.3
48 = Java 1.4
49 = Java 5
50 = Java 6
51 = Java 7

Alternatively, you can make a simple test class that can identify class version.
import java.io.*;
 
public class Test {
    public static void main(String[] args) throws IOException {
        checkClassVersion("Class path you want to know");
    }                      
 
    private static void checkClassVersion(String filename)
        throws IOException
    {
        DataInputStream in = new DataInputStream
         (new FileInputStream(filename));
 
        int magic = in.readInt();
        if(magic != 0xcafebabe) {
          System.out.println(filename + " is not a valid class!");;
        }
        int minor = in.readUnsignedShort();
        int major = in.readUnsignedShort();
        System.out.println(filename + ": " + major + " . " + minor);
        in.close();
    }
}


Thursday, June 14, 2012

Configure Proxy server bypass or pass

When you work in enterprise environment, you will most likely need to use proxy server either you like or not.

I have suffered for long time because proxy setting and I had to have customized proxy bypass script due to development.

I would like to share my snippet. I hope it helps.

Ubuntu apt-get Proxy configuration. For more detail




Maven test proxy setting



Eclipse proxy set up for JRE/JDK



Eclipse Network Proxy configuration for installing new sofware or update plugins



Eclipse Tomcat proxy set up
add below text
 -Dhttp.proxyHost="106.101.91.4" -Dhttp.proxyPort="8080" -Dhttps.proxyHost="106.101.91.4" -Dhttps.proxyPort="8080"



Internet Explorer Proxy configuration



Eclipse Java application Proxy configuration



Ubuntu Proxy for chrome browser



Firefox Proxy configuration



Proxy Automate Script(PAC) sample

/*************************
Configuration Example path

For IE on Windows
file://d:\proxy.pac

For FF on Windows
file:///d://proxy.pac

For FF on Ubuntu
file:///home/proxy.pac
*************************/
var PROXY1 = "PROXY 123.123.123.1:8080";
var PROXYY2 = "PROXY 123.123.123.2:8080";

var DIRECT = "DIRECT";
var regexpr_facebook = /^[.a-zA-Z0-9-]*.facebook.com/;
var myip = myIpAddress();

//url = http://www.yahoo.com/dkdkd/allld.jpg
//host = www.yahoo.com
function FindProxyForURL(url, host){

 //For Home AP access ( If Source IP starts with 192.168.x.x) bypass Proxy
 if (isInNet(myip, "192.168.0.0", "255.255.0.0")) {
  return DIRECT;
 //your local computer bypass Proxy
 }else if (isInNet(host, "127.0.0.1", "255.255.255.0") || host=="localhost") {
  return DIRECT;
 //C class subnet mask by pass Proxy(it means all IPs starts with 111.111.111 will bypass
 }else if (isInNet(host, "111.111.111.xxx", "255.255.255.0") ) {
  return DIRECT;
 //When you need to access from host file definition IPs
 }else if (host=="devsite"|| host=="mytest") {
  return DIRECT;
 //if you need proxy for specific ip ranges ( Domain will be resolved by DNS ang get IP)
 }else if (isInNet(myip, "106.101.7.93", "255.255.255.0") ) {
  return PROXY1;
 //if you need proxy for specific domain address
 }else if (regexpr_facebook.test(host)){
  return PROXYY2;
 }else{
  return PROXY1;
 }
}

Wednesday, May 30, 2012

Set System property on Maven pom.xml for test

Hi, I made maven test class that makes internet connection like Soap, http connection so on that verifies all test is successful. but, my local internet connection requires Proxy server configuration. If I run it on my computer, it won't run because I get connection refused error. If I set system property on my java source, it is not pretty and I might need to change source code when I deploy on production level.

There is the solution :
I need to add maven-surefire-plugin for setting system property on pom.xml file. That is only applies for test classes system property. You can set skip test if you change value of skipTests element true/false below

<project ...>
 <dependencies>
 ...
 </dependencies>

 <build>
    <plugins>
       <plugin> ....      </plugin>

       <plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.12</version>
  <configuration>
    <skipTests>true</skipTests>
    <systemPropertyVariables>
      <http.proxyHost>106.101.5.61</http.proxyHost>
      <http.proxyPort>8080</http.proxyPort>
    </systemPropertyVariables>
  </configuration>
       </plugin>
     </plugins>  
 </build>
</project>


For more detail please refer maven surefire plugin document

Friday, May 4, 2012

Spring 3 Task Execution and Scheduling


I have downloaded Spring3 and Quartz and Spring batch Framework.
After running a simple example, It was not easy, not working well with autowired annotation and many things to learn before use giant functions. currently, Spring batch depend on spring 2.5 that I am not sure, it will work well with Spring 3.1
It is also causing to make big packaging jar/war file

I just wanted to make a very simple batch program that I can use based on SpringFramwork which can autowire beans and DB resources.
I decide to use Spring Task. It just need Spring framework, nothing else
It is extreamly simple and works perfect as I expected.

Just type 3 more line on you spring xml file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">


<context:component-scan base-package="monitor"/>

<mvc:annotation-driven />

<!--  Omit all the WEB MVC Handler and View Resolver Configuration -->


<!--  Scheduler define start -->
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>

<task:executor id="myExecutor" pool-size="5"/>

<task:scheduler id="myScheduler" pool-size="10"/>
<!--  Scheduler define End -->

</beans>

Make one Class that is Component annotated. The Class must be in base-package or sub package.
and make method that is Scheduled annotated with Cron Expression.
That's it. that it will run every 5 minutes from 2 min of the hour.
You can autowire beasn which you like.

package monitor.batch;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class HarvestHttpStatusJob {

 private final Log logger = LogFactory.getLog(this.getClass());

 //To-do  @Autowired beans as usual you need.

 @Scheduled(cron = "0 2/5 * * * *")
 public void harvestStatus() {

  logger.info(this.getClass().getName() + " Start");

  //To do Implement your code

  logger.info(this.getClass().getName() + " Finish");
 }

}

For more Detail Information. Please refer below document from SpringFramwork.
http://static.springsource.org/spring/docs/3.1.1.RELEASE/spring-framework-reference/html/scheduling.html

If you are interested in Spring batch and quartz, Please refer below link
Spring batch and quartz



Use of Apache commons configuration in Spring framework

I can get benefit if I use Apache commons configuration.
The reason is

I can choose plain text property file or xml based property file. but, mostly better to use xml based property
I can use UTF-8 Encoding, so that I can type most of language characters.
I can set same key name to get list or array or collection so on. So, I can simply get it and run looping clause.
I can get property value based on hierarchy.

I wanted to use on Spring framework. I just set one Spring bean
※ it worked in Spring3, I guess it will work lower version of Spring as well.

 <bean id="xmlConfig" class="org.apache.commons.configuration.XMLConfiguration">
  <constructor-arg type="java.lang.String">
   <value>commons-config.xml</value>
  </constructor-arg>
 </bean>


commons-config.xml file, you can change root element "configuration" as you like

<?xml version="1.0" encoding="ISO-8859-1" ?>
<configuration>
 <countries>
  <country>
   <code>gbr</code>
  </country>
  <country>
   <code>ger</code>
  </country>
  <country>
   <code>ita</code>
  </country>
  <country>
   <code>aut</code>
  </country>
  <country>
   <code>che</code>
  </country>
  <country>
   <code>chfr</code>
  </country>
  <country>
   <code>swe</code>
  </country>
  <country>
   <code>esp</code>
  </country>  
 </countries>
</configuration>

Make a Spring controller and getStringArray from property
package monitor.controller;

import java.util.List;

import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {

 private final Log logger = LogFactory.getLog(this.getClass());

 @Autowired private XMLConfiguration config;

 @RequestMapping(value = { "/", "/index" })
 public ModelAndView index() {

  ModelAndView mnv = new ModelAndView();
  String[] countries = config.getStringArray("countries.country.code");
  mnv.addObject("countries", countries);

  mnv.setViewName("index");

  return mnv;
 }

}

Thursday, May 3, 2012

How to configure apt-get command to let work behind proxy on Ubuntu 11

apt-get doesn't send packet via system proxy which you might have set in system setting, you need to put it manually.It require to create one file on "/etc/apt/apt.conf" You just create file and type 3 lines and save it, that's it.
/etc/apt$ sudo vi apt.conf

1.type in below
Acquire::http::proxy "http://[[user][:pass]@]host[:port]/";
Acquire::ftp::proxy "ftp://[[user][:pass]@]host[:port]/";
Acquire::https::proxy "https://[[user][:pass]@]host[:port]/";

Actual example from my configuration
Acquire::http::proxy "http://192.168.0.1:8080/";
Acquire::ftp::proxy "ftp://192.168.0.1:8080/";  
Acquire::https::proxy "https://192.168.0.1:8080/";

2.save it, if you don't feel comfortable to use vi, you can use any text editor.
:wq!

※More detail information
man apt.conf

Saturday, April 21, 2012

SSH tunneling on Ubuntu


ssh -L 15401:IP/HOST:1521 -L 15301:IP/HOST:1521 -L 15300:IP/HOST:1521 userid@serverhost

For building a tunneling easier, better make a simple shell script and add it into path. and run with simple command.
I simply made "db" command to establish tunneling simply way
--- Check connection
netstat -an | grep 15

SSH client configuration on Ubuntu

SSH client configuration on Ubuntu

put your open ssh private key on below

/home/UserID/.ssh/id_rsa

set permission 700

Done

Wednesday, April 18, 2012

Usage of Maven J2EE archetype instead of using Eclipse dynamic web project.

Eclipse Dynamic Web project is not suitable for a maven based project to locate jsp, java, properties and test sources.
If you use that, you will start to configure complicated configuration build path, war destination target, test source location and packaging issues so on. I strongly recommend you to use maven archetype that follows maven directory convention.

It's appeared that "maven-archetype-webapp" archetype is little outdated to use for latest project.
The best way so far is, use codehaus webapp archetype.

For JDK5 based project
mvn archetype:generate -DgroupId=<your group> -DartifactId=<your artifact> -DarchetypeArtifactId=webapp-jee5 -DarchetypeVersion=1.3 -DarchetypeGroupId=org.codehaus.mojo.archetypes

For JDK6 based project
mvn archetype:generate -DgroupId=<your group> -DartifactId=<your artifact> -DarchetypeArtifactId=webapp-javaee6 -DarchetypeGroupId=org.codehaus.mojo.archetypes


I tried to generate without "-DarchetypeGroupId=org.codehaus.mojo.archetypes" option. then it will show error message.
"The desired archetype does not exist (org.apache.maven.archetypes:webapp-jee5-1.3:1.0)". the reason is the "org.codehaus.mojo.archetypes" archetype group is not maven default archetype group id. For more detail, please refer below link
http://docs.codehaus.org/display/MAVENUSER/Archetypes+List

After that, simply import this project into eclipse




Update manager Google Chrome update error "Requires Installation of Untrusted Packages" on Ubuntu

I have tried to update Chrome browser. but, It keep showing this error message "Requires Installation of Untrusted Packages"

After Google, nothing really worked what they said.

I just typed apt-get command instead of using update manager.
You just need to type 'sudo apt-get upgrade google-chrome-stable' and 'Y' two times. that's it.
and restart your computer. then you can use latest Chrome version.

$ sudo apt-get upgrade google-chrome-stable
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be upgraded:
  google-chrome-stable
1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 27.2 MB of archives.
After this operation, 2,556 kB of additional disk space will be used.
Do you want to continue [Y/n]? Y
WARNING: The following packages cannot be authenticated!
  google-chrome-stable
Install these packages without verification [y/N]? Y
Get:1 http://dl.google.com/linux/chrome/deb/ stable/main google-chrome-stable amd64 18.0.1025.162-r131933 [27.2 MB]
Fetched 27.2 MB in 12s (2,249 kB/s)                                            
(Reading database ... 262166 files and directories currently installed.)
Preparing to replace google-chrome-stable 17.0.963.78-r125577 (using .../google-chrome-stable_18.0.1025.162-r131933_amd64.deb) ...
Unpacking replacement google-chrome-stable ...
Processing triggers for man-db ...
Processing triggers for bamfdaemon ...
Rebuilding /usr/share/applications/bamf.index...
Processing triggers for desktop-file-utils ...
Processing triggers for gnome-menus ...
Setting up google-chrome-stable (18.0.1025.162-r131933) ...

Sunday, April 15, 2012

Email Send Via telnet

Once you have some local users registered, try sending mail to one of them with SMTP (port 25).

$ telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 172.16.1.131 SMTP Server (JAMES SMTP Server 3.0-beta3) ready Sat, 6 Nov 2010 17:31:33 +0100 (CET)
ehlo test
250-172.16.1.131 Hello test (aoscommunity.com [127.0.0.1])
250-PIPELINING
250-ENHANCEDSTATUSCODES
250 8BITMIME
mail from:<YOUR_NAME@YOUR_DOMAIN>
250 2.1.0 Sender <YOUR_NAME@YOUR_DOMAIN> OK
rcpt to:<YOUR_NAME@YOUR_DOMAIN>
250 2.1.5 Recipient <YOUR_NAME@YOUR_DOMAIN> OK
data
354 Ok Send data ending with <CRLF>.<CRLF>
subject: test

this is a test
.
250 2.6.0 Message received
quit
Connection closed by foreign host.
Try now to retrieve that mail using POP3 (port 110) or IMAP (port 143).

Now, I got a test email via telnet.


If you need to tls connection with athentication. you will need to follow this. first you need base64 encoded username and password
$ echo -n "username@aaabb.com" | base64
dXNlcm5hbWVAYWFhYmIuY29t=
$ echo -n "password" | base64
cGFzc3dvcmQ=

openssl s_client -host <mx.mail.server> -port 587 -starttls smtp

AUTH LOGIN
334 VXNlcm5hbWU
<base64 encoded id>
334 UGFzc3dvcmQ6
<base64 encoded password>
235 2.7.0 Authentication successful
mail from:<YOUR_NAME@YOUR_DOMAIN>
250 2.1.0 Ok
rcpt to:<YOUR_NAME@YOUR_DOMAIN>
250 2.1.5 Recipient <YOUR_NAME@YOUR_DOMAIN> OK
data
From: "Name" <YOUR_NAME@YOUR_DOMAIN>
To: "Name" <YOUR_NAME@YOUR_DOMAIN>
subject: test

this is a test

.


250 2.0.0 Ok: queued as C71F02BC0B1
quit
221 2.0.0 Bye
closed


http://www.samlogic.net/articles/smtp-commands-reference.htm
https://www.heise.de/security/artikel/StartTLS-785453.html
http://base64-encoder-online.waraxe.us/

Saturday, March 24, 2012

Install Printer on Ubuntu 11

Install Printer on Ubuntu 11

Download linux printer driver.

extract the driver file

it must contain *.ppd files those are printer driver

Go System setting - Printer - click Add button

Find network printer.

Type in IP

put driver location

done

Spingframework MVC set up servlet.xml

This is springframework MVC servlet.xml for WEB developers.

I hope it helps you, it is brief though.

It is tested in Spring 3.1 and 3.1.1 version.

context:component-scan : It will scan your java class package. which is coded in spring annotation based.

It has several ViewResolver as you see.

ContentNegotiatingViewResolver : It will show json result.if you want you can put xml,rss result view in ContentNegotiatingViewResolver.

InternalResourceViewResolver: It will show your jsp page.

SimpleUrlHandlerMapping : It will be handle if spring doesn't find any RequestMapping from Controller, the request will get to UrlFilenameViewController. it will resolve jsp file that is under /WEB-INF/jsp directory. so you don't have to make empty controller for each request mapping that doesn't have any logic.

I am sure it will trigger more curiosity if you are interested.

<context:component-scan base-package="yourpackage"/>

 <bean
  class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
  <property name="order" value="1" />
  <property name="mediaTypes">
   <map>
    <entry key="json" value="application/json" />
   </map>
  </property>

  <property name="defaultViews">
   <list>
    <!-- JSON View -->
    <bean
     class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
    </bean>
   </list>
  </property>
  <property name="ignoreAcceptHeader" value="true" />

 </bean>

 <!-- If no extension matched, use JSP view -->
 <bean id="viewResolver"
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="order" value="2" />
  <property name="viewClass"
   value="org.springframework.web.servlet.view.JstlView" />
  <property name="prefix" value="/WEB-INF/jsp/" />
  <property name="suffix" value=".jsp" />
 </bean>
 
 <bean name="myController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
 
 <!-- If no view matched -->
 <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
     <property name="mappings">
         <value>
             /**/*.do=myController
         </value>
     </property>
  <property name="order" value="3" />    
 </bean> 

 <!-- Configure the multipart resolver for file upload request -->
 <bean id="multipartResolver"
  class="org.springframework.web.multipart.support.StandardServletMultipartResolver" />

 <!-- for rest url pattern support -->
 <mvc:default-servlet-handler />

 <mvc:annotation-driven />

Thursday, March 22, 2012

Jqgrid client side sorting

I have been searching how to sort Jqgrid in front end.

Someone was explaining it to make send a request to back-end,then sort it in database then return the result.
it doesn't make a sense to use grid framework then.

Finally, I have found it.
just add one more option "loadonce: true"

$(function(){ 
  $("#list").jqGrid({
    url:'Json Return URL',
    datatype: 'json',
    mtype: 'GET',
    colNames:['Model', 'Banner', 'Highlights'],
    colModel :[ 
      {name:'model', index:'model', width:120, key:true}, 
      {name:'banner', index:'banner', sorttype: 'number', align:'right', width:100}, 
      {name:'highLight', index:'highLight', sorttype: 'number', align:'right', width:100}],
    rowNum:20,
    height: 300,
    sortorder: 'desc',
    loadonce: true,
    viewrecords: true,
    gridview: true,
    jsonReader : {
  repeatitems: false,
  userdata: "userdata"
 }    
  }); 
}); 

that's it :)

FYI, when you set an attribute on colModel "sorttype: 'number'", it will sort as number.
if you don't, 2 will be top place when you sort it, even there is 11 or 10 so on..

Monday, March 19, 2012

How to play DVD that is locked for copy on Ubuntu 11.

How to play DVD that has copy protection on Ubuntu 11.

I just got a present, that is original DVD, but, it doesn't run on my Ubuntu.

※ Higher than Ubuntu 9.10, you need to do follow instruction

1. install medibuntu
sudo wget http://www.medibuntu.org/sources.list.d/karmic.list –output document=/etc/apt/sources.list.d/medibuntu.list
2. Add key medibuntu-keyring
sudo apt-get update && sudo apt-get install medibuntu-keyring && sudo apt-get update
3. install "libdvdcss2" pakage
sudo apt-get install libdvdcss2
4. enjoy dvd


I don't know what that it is detail. nevertheless it runs well now.
for more detail please check medibuntu click here

install nabi on Ubuntu

sudo apt-get install nabi
im-switch -c

reboot or log out and login

Wednesday, March 14, 2012

Install JDK 6 on Ubuntu 11

Install JDK 6 on Ubuntu 11

sudo add-apt-repository ppa:ferramroberto/java
sudo apt-get update
sudo apt-get install sun-java6-jdk sun-java6-jre sun-java6-plugin

Saturday, March 3, 2012

Mybatis mapper xml file location in Maven project.

mybatis, Spring, Maven, Glassfish are well harmonized.
Development on my local computer was cruising well.

It's almost ready to finish project.

before launching it on production server.
we just fished to set up development server.
As it should be, I deployed it on to development server.

"mvn package" and get the war file.
deploy the war file to glassfish.

Errors occurred, Mybatis Mapper is missing?
"Mapped Statements collection does not contain value for ..."
What? why? I see all mapper xml/ class file. All files are placed right.
and working well on my local PC.

No clue.. for a while and while.
As new at maven, I had no idea that could happen.

Maven won't package except class files.
I knew that, so I located properties, conf files in resource directories.
but, I forgot that xml will be exculded as well.
xml mapper files are located under same mybatis mapper interface directories.
I have opened up the war file, As my guess, there was no mapper xml files on classpath directories.


Development local src directory file. there are mapper xml files are located.



But, Under maven target directory. xml mapper files are missing.



Solution, just re-located xml mapper files under resource directory in same directory hierarchy.
so, I will be packaged under same directory or you can change mapper location and put it.
as you know, you need to reconfigure the mapper location on spring then.

curiosity of Jquery "$(document).ready()" or "$()" what's different?

Just wondered. what's the difference and what it is.

I found out that is same either anyway.

$(document).ready(function() {
  // Handler for .ready() called.
});

Which is equivalent to calling:

$(function() {
 // Handler for .ready() called.
});

so, I will use shorter one.

Applied to the Hello Jquery!.

$(function() {
    $("a").click(function() {
    alert("Hello Jquery!");
    });
});

refer from : http://api.jquery.com/ready/

Friday, February 24, 2012

Install expect on Ubuntu 11

I missed auto log in to remote ssh server or doing automation that I often do. like access ftp server and download file, log in ssh server, push file to FTP server and open a turnelling so on.
There is a way to do very easily.

You need to install 'expect' command.
"expect" command is simply expecting a text from terminal, and send it when it meets expectation.
sudo apt-get install expect
Installation is done.

Sample usage.

Let's make simple shell program
vi abc.sh

Type into shell shell program.
#!/usr/bin/expect -f
set timeout 100
spawn ssh userid@servername 
expect "/home/devtrigger/.ssh/id_rsa" 
send "password\r"
expect "servername:"
send "bash\r"
interact
you should not omit first line "#!/usr/bin/expect -f" it indicate that it will run by expect.
you can ommit "timeout 100" which is waiting for response from server. I used the timeout option for using long process like copy a big file from ftp or etc.
of course, you need to replace certain text like "devtrigger", "password"
save it.

let's make the file executable and run it
chmod 755 abc.sh
./abc.sh

Host name change on Ubuntu 11

I had long long disliked host name on my terminal when I installed.
First thing, I wanted to do after installed Ubuntu.

Host name change on Ubuntu 11

Open up the text file that shows your Ubuntu local host name.
sudo gedit /etc/hostname

change to new name you want
Save it.
Done.

hosts file modify on Ubuntu

Hosts file modify on Ubuntu

sudo vi /etc/hosts

modify it and save it.

I have done it on Ubuntu 11.
I am quite sure most of Ubuntu version has same file location.

Oracle JDK 7 install on Ubuntu 11

For some reason, I guess because of license reason. Oracle doesn't have Ubuntu software repository.
so you need to install it manually, you can't use apt-get inatall command.
Let's see how to install Oracle(Sun) JDK 7 install on Ubuntu

Download jdk7 for linux, don't download rpm package.
rpm package is for Rad hat linux. just download tz , tar file extension

1.Extract files.

2.fire up the terminal and type:

Move the extracted jdk folder to the default installation folder for java.
and make a link.
sudo mv jdk1.7.0 /usr/lib/jvm
ln jdk1.7.0_02 java-7-sun
sudo update-alternatives --config java

Next, type this command and count the number of java version you have.
sudo update-alternatives --config java

Once you have that number enter this command and change the number on the end of it to the number you just found plus one.

this command mean is, you add one more java command on system.
later on, you can switch to another java easily, like open jdk or another version of jdk.
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-7-sun/jre/bin/java 3

Finally, run this command and type the number of the new installation then hit enter.

sudo update-alternatives --config java

To make sure everything worked, run this command. It should output your version to be 1.7.0.

java -version

And that's it! Let me know if you have problems with anything.


you can have sevral jdk, if you made a link and used update-alternatives command.
you can switch jdk very easily
java-1.6.0-openjdk java-6-sun java-7-sun

java-6-openjdk java-6-sun-1.6.0.26 jdk1.7.0_02


# Set JAVA_HOME, PATH
open profile file
#sudo gedit /etc/profile 

type it in
JAVA_HOME=/usr/lib/jvm/java-7-sun/ 
export JAVA_HOME
export PATH=$PATH:/usr/lib/jvm/java-7-sun/bin

Thursday, February 16, 2012

Web server request and response via telnet

How to see web server response via telnet command.

As you know, most of network connection you can see via telnet.
Mail server, Web server, FTP server so on.

Now, I will show you how to access WEB Server via telnet.
There are many tool to see it better.
But, when you need only for simple reason to check, telnet is the good option to check.

telnet www.google.com 80
GET / HTTP/1.0
Host: www.google.com
'type enter 2 times'

When you are behind of proxy server. you should go through proxy. You need to telnet to your proxy server and connect.
Please see below example.
192.168.1.4 is the proxy server ip and 8080 is the port number
telnet 192.168.1.4 8080
CONNECT www.google.com:80 HTTP/1.0
'type enter 2 times'
GET / HTTP/1.0
Host: www.google.com
'type enter 2 times'

you can replace '/' character which is located after 'GET' to your demand like '/index.php', 'index.do' so on.
most of server use virtual host. so "Host" header is necessary to configure.
It should be basically same as host address with out any query string.

If you are interested more about header list
Please check this link
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields

now, you can make your own script for regular check or application for performance test so on.

Wednesday, February 15, 2012

mybatis-spring 1.0.2 crash with springframework 3.1? introduce maven dependency exclusions

As a new in maven, after setting up maven dependency with springframework 3.1 and mybatis-spring 1.0.2 .
It crashed. It worked before I set up maven.
why it is not working with maven. Should I dump maven?

I was looking into it.
the reason was mybatis has dependency to spring 3.0.6. WTH
and bring spring 3.1 jars from my configurations and 3.0.6 jars from mybatis.

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis-spring</artifactId>
   <version>1.0.2</version>
   <exclusions>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
    </exclusion>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-core</artifactId>
    </exclusion>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
    </exclusion>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-test</artifactId>
    </exclusion>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>spring-tx</artifactId>
    </exclusion>
   </exclusions>
  </dependency>


That's the solution to bring only spring 3.1 jars.

By they way, I had to type it all on by one. I was wonder if there is any smarter way with wild card.
like this. would it be working? it would be so great if it works.

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis-spring</artifactId>
   <version>1.0.2</version>
   <exclusions>
    <exclusion>
     <groupId>org.springframework</groupId>
     <artifactId>*</artifactId>
    </exclusion>
   </exclusions>
  </dependency>


But, It is not working, I hope it works soon.
Maven team is working on this.  there is already the same issue in maven jira
http://jira.codehaus.org/browse/MNG-3832