리눅스 기본 인코딩이 utf-8 인 경우 euc-kr 문서 오픈 시 께질 수 있습니다.


:e ++enc=euc-kr

:set fileencoding=utf-8


위 명령어 실행 후 :wq 저장 하면 해결 된다.



최근에 서버 설치를 하면서 별도로 설치 하려고 하였으나, 패키지 설치 방법을 사용해 보았다.


Step 1.  OpenJDK Package 확인 하기

전체 패키지 목록에서 확인 한다.


[whitelife@whitelife library]$ yum list all | grep jdk

java-1.6.0-openjdk.x86_64           1:1.6.0.0-1.65.1.11.14.el6_4

java-1.6.0-openjdk.x86_64           1:1.6.0.0-1.66.1.13.0.el6

java-1.6.0-openjdk-demo.x86_64      1:1.6.0.0-1.66.1.13.0.el6

java-1.6.0-openjdk-devel.x86_64     1:1.6.0.0-1.66.1.13.0.el6

java-1.6.0-openjdk-javadoc.x86_64   1:1.6.0.0-1.66.1.13.0.el6

java-1.6.0-openjdk-src.x86_64       1:1.6.0.0-1.66.1.13.0.el6

java-1.7.0-openjdk.x86_64           1:1.7.0.45-2.4.3.4.el6_5

java-1.7.0-openjdk-demo.x86_64      1:1.7.0.45-2.4.3.4.el6_5

java-1.7.0-openjdk-devel.x86_64     1:1.7.0.45-2.4.3.4.el6_5

java-1.7.0-openjdk-javadoc.noarch   1:1.7.0.45-2.4.3.4.el6_5

java-1.7.0-openjdk-src.x86_64       1:1.7.0.45-2.4.3.4.el6_5

ldapjdk.x86_64                      4.18-6.el6             base

ldapjdk-javadoc.x86_64              4.18-6.el6             base


Step 2.  OpenJDK 설치 하기

java-1.6.0-openjdk, java-1.6.0-openjdk-devel 패키지를 설치 한다.


[whitelife@whitelife library]$ sudo yum install java-1.6.0-openjdk java-1.6.0-openjdk-devel

[sudo] password for game:

Loaded plugins: fastestmirror, refresh-packagekit, security

Loading mirror speeds from cached hostfile

 * PUIAS_6_computational: puias.math.ias.edu

 * base: mirror.premi.st

 * epel: mirror.premi.st

 * extras: mirror.premi.st

 * updates: mirror.premi.st

Setting up Install Process

Resolving Dependencies

--> Running transaction check

---> Package java-1.6.0-openjdk.x86_64 1:1.6.0.0-1.65.1.11.14.el6_4 will be updated

---> Package java-1.6.0-openjdk.x86_64 1:1.6.0.0-1.66.1.13.0.el6 will be an update

---> Package java-1.6.0-openjdk-devel.x86_64 1:1.6.0.0-1.66.1.13.0.el6 will be installed

--> Finished Dependency Resolution


// ...


Installed:

  java-1.6.0-openjdk-devel.x86_64 1:1.6.0.0-1.66.1.13.0.el6


Updated:

  java-1.6.0-openjdk.x86_64 1:1.6.0.0-1.66.1.13.0.el6


Complete!


Step 3.  설치 확인 하기

버전을 확인 한다.


[whitelife @whitelife library]$ javac -version

javac 1.6.0_28

[whitelife @whitelife library]$ java -version

java version "1.6.0_28"

OpenJDK Runtime Environment (IcedTea6 1.13.0pre) (rhel-1.66.1.13.0.el6-x86_64)

OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)


직접 환경 변수 설정을 하지 않아도 되지만, 환경 변수에 대한 생각은 하고 있어야 한다.


※ 참고 사이트: http://gauryan.blogspot.kr/2011/04/centos-jdk.html


'Server,Was' 카테고리의 다른 글

Nginx 1.6.0 설치 하기  (0) 2014.07.17
Tomcat HTTP Method 제한하기  (0) 2014.04.30
CentOS Gitlab 설치 시 Redis Port 변경 방법  (0) 2013.12.05
CentOS System Log 확인 하기  (0) 2013.09.06
CentOS 타임 서버 ntp 설정 하기  (0) 2013.09.06


CentOS에서 Gitlab 설치 시 기본 포트 변경을 위해 Redis 설정 파일을 수정 하였습니다.


config/resque.yml
development: redis://localhost:00000
test: redis://localhost:00000
production: redis://localhost:00000

위와 같이 변경 후 설치 시 Redis Port 가 수정 되지 않았습니다. 


해결을 위해서는 Ruby 소스를 직접 수정 해야 합니다.


config/initializers/session_store.rb

# Be sure to restart your server when you modify this file.

config_file = Rails.root.join('config', 'resque.yml')

resque_url = if File.exists?(config_file)
                 YAML.load_file(config_file)[Rails.env]
               else
                 "redis://localhost:00000"
               end

Gitlab::Application.config.session_store(
  :redis_store, # Using the cookie_store would enable session replay attacks.
  key: '_gitlab_session',
  secure: Gitlab::Application.config.force_ssl,
  httponly: true,
  path: (Rails.application.config.relative_url_root.nil?) ? '/' : Rails.application.config.relative_url_root,
  servers: resque_url
)

3 ~ 9, 17 라인을 추가 합니다.


추가가 끝나면 변경된 포트가 적용 되는 것을 볼 수 있습니다.


※ 참고 사이트: https://github.com/gitlabhq/gitlabhq/issues/5406



몇일 전에 Windows 8.1 로 업데이트 한 후 Backgroundcontroller.dll 파일을 찾을 수 없습니다. 라는 문구가 발생 했다.


레지스트리 편집기를 사용하여 해당 파일을 삭제 하였으나 같은 현상이 계속 발생 한다.



위 링크는 해당 내용에 대한 microsoft 에 질문한 글이다. 답변을 참고하면 Autoruns 라는 Tool 을 사용하여 제거 한다.


다운 받은 후 압축을 풀면 autoruns.exe 파일이 보인다. 실행 하자.



위 화면에서 Ctrl + F 한 후 Backgroundcontroller 를 검색하여 마우스 오른쪽 메뉴로 삭제를 한 후 재부팅 한다.


깔끔하게 사라지는 모습을 볼 수 있다.





Reflection 이란 단어는 반사, 방향, 거울 등에 비친 상 이라는 의미를 담고 있습니다.


개발 당시 많이 사용 하는 new 연산자는 Class의 규칙에 의해서 객체화 된 Instance를 생성 합니다.  


Test test = new Test();


Instance를 거울에 비추어 보면 반대로 Class의 정보를 얻을 수 있습니다. 

거울의 역할을 하는 메소드는 Object Class의 getClass 라고 볼 수 있습니다.


아래는 실제 사용 예 입니다.


public final native Class<?> getClass();


이제 반대로 확인이 가능합니다. Class의 구성 요소인 생성자, 메소드, 전역 변수 등 정보가 필요 할 떄 사용되는 패키지가 java.lang.reflect 입니다. 


패키지를 이용하면 변수의 값을 바꿀 수도 있고, 메소드를 실행도 할 수 있습니다. 막강한 기능인 패키지를 기반으로한 Instance 생성도 가능 합니다. 


Java Framework 중 하나인 Spring의 중요한 기능인 DI(Dependency Injection) 가 동작이 가능한 것도 java.lang.Class<T>, java.lang.reflect 가 존재하기 때문 입니다.


DI 추가 설명 - http://blog.whitelife.co.kr/13


Spring ApplicationContent.xml 중 일부

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

 <bean class="kr.whitelife.controller.Wcontroller">
  <constructor-arg ref="service"/>
 </bean>
 
 <bean id="service" class="kr.whitelife.service.Wservice">
  <property name="dao" ref="dao"></property>
 </bean>
 
 <bean id="dao" class="kr.whitelife.dao.Wdao"/>
 
</beans>


<bean> 태그의 class 속성에 들어가 있는 정보를 가지고 package 기반의 Instance 생성을 할 수 있습니다.


간단한 예제 입니다.

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

public class Reflective {

  public void message(String choice) throws NoSuchMethodException, NullPointerException, SecurityException, IllegalAccessException, InvocationTargetException {
    this.getClass().getDeclaredMethod(choice, (Class<?>[]) null).invoke(this);
  }

  public void hello() {
    System.out.println("hello");
  }

  public static void main(String[] args) {
    try {
      Reflective r = (Reflective) Class.forName("Reflective").newInstance();
      r.message("hello");
    } catch (NoSuchMethodException e) {
      System.out.println(e);
    } catch (NullPointerException e) {
      System.out.println(e);
    } catch (ClassNotFoundException e) {
      System.out.println(e);
    } catch (SecurityException e) {
      System.out.println(e);
    } catch (InstantiationException e) {
      System.out.println(e);
    } catch (IllegalAccessException e) {
      System.out.println(e);
    } catch (InvocationTargetException e) {
      System.out.println(e);
    }
  }
}

위 기능은 Package를 이용한 객체 생성, method 정보를 찾아서 실행 까지 합니다.  기존에 new 연산자를 이용해서 Instance 생성을 했다면 reflect 패키지 활용 시 문자열을 활용하여 동적으로 Instance 제어가 된다.


Java의 상속, 인터페이스와 더불어 reflection과 결합하게 된다면 훨씬 개발이 요구사항에 따른 대응이 수월해지고, Class 단위의 분기를 했다면, Method 단위의 분기도 수월하게 처리가 가능 합니다.


※ 참고 사이트

  Java API - http://docs.oracle.com/javase/6/docs/api/

  이미지 URL - http://www.clker.com/cliparts/e/K/g/G/i/j/blue-stick-man-reflect-hi.png


'Java' 카테고리의 다른 글

Java HashMap Key 정렬 하기  (0) 2014.09.24
Google Guava 라이브러리 사용하기  (0) 2014.07.24
Java Console 게시판 만들기 - 4  (4) 2013.11.13
Java Console 게시판 만들기 - 3  (0) 2013.11.12
Java Console 게시판 만들기 - 2  (0) 2013.11.11


[Java Console 게시판 만들기 - 3] - http://blog.whitelife.co.kr/165


윗 글의 게시판 소스 개선 입니다.


-  Java API 사용

  - List<E>

  - ArrayList<E>


기존 방식은 String 2차원 배열을 사용 했기 때문에 수동으로 Array가 꽉 찼을 경우 재 할당을 해야 했습니다. 개선 방안으로는 Java API 중 List가 있습니다. 내부적으로 배열을 증가 시키는 로직이 있습니다.


Bbs.java

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

public class Bbs {
  
	private Scanner s;
	private List<String[]> bbsList;

	private int seq;
	
	public Bbs() {
		this.s = new Scanner(System.in);
		this.bbsList = new ArrayList<String[]>();

		this.seq = 1;
	}

	public void readme() {
		System.out.println("1. 등록, 2. 상세보기, 3. 수정, 4. 삭제, 5. 목록, x. 종료");
	}

	public void exit() {
		System.out.println("프로그램을 종료 합니다.");
	}

	public String getInput() {
		return this.s.next();
	}

	public void create() {
		String no = String.valueOf(seq);
		
		System.out.println("input title...");
		String title = getInput();

		System.out.println("input content...");
		String content = getInput();

		String[] bbs = new String[3];
		bbs[0] = no;
		bbs[1] = title;
		bbs[2] = content;
		
		this.bbsList.add(bbs);

		this.seq++;

		System.out.println("등록이 완료 되었습니다.");
	}
	
	private String[] getSearch(String no) {
		for (String[] bbs : this.bbsList) {
			if (bbs != null && bbs[0].equals(no)) {
				return bbs;			
			}
		}

		return null;
	}

	public void read(String no) {
		if (no == null || no == "") {
			System.out.println("잘못 입력 하셨습니다.");
			return;
		}
	
		String[] bbs = this.getSearch(no);
		
		if (bbs == null) {
			System.out.println("게시글이 없습니다.");
			return;
		}
		
		System.out.println("no: " + bbs[0]);
		System.out.println("title: " + bbs[1]);
		System.out.println("content: " + bbs[2]);
	}

	public void update(String no) {
		if (no == null || no == "") {
			System.out.println("잘못 입력 하셨습니다.");
			return;
		}
	
		String[] bbs = this.getSearch(no);
		
		if (bbs == null) {
			System.out.println("게시글이 없습니다.");
			return;
		}

		System.out.println("input title...");
		String title = this.getInput();

		System.out.println("input content...");
		String content = this.getInput();

		bbs[1] = title;
		bbs[2] = content;

		System.out.println("수정이 완료 되었습니다.");
	}
	
	public void delete(String no) {
		if (no == null || no == "") {
			System.out.println("잘못 입력 하셨습니다.");
			return;
		}

		String[] bbs = this.getSearch(no);
		
		if (bbs == null) {
			System.out.println("게시글이 없습니다.");
			return;
		}
		
		this.bbsList.remove(bbs);

		System.out.println("삭제가 완료 되었습니다.");
	}

	public void getList() {
		for (String[] bbs : this.bbsList) {
			if (bbs != null) {
				System.out.println("no: " + bbs[0]);
				System.out.println("title: " + bbs[1]);
				System.out.println("content: " + bbs[2]);
			}
		}
	}

  public static void main(String[] args) {

	Bbs bbs = new Bbs(); 

	while(true) {
	        bbs.readme();		

		String choice = bbs.getInput();

		if (choice.equals("1")) {
			bbs.create();
		} else if (choice.equals("2")) {
			System.out.println("번호를 입력해 주십시오.");
			bbs.read(bbs.getInput());
		} else if (choice.equals("3")) {
			System.out.println("번호를 입력해 주십시오.");
			bbs.update(bbs.getInput());
		} else if (choice.equals("4")) {
			System.out.println("번호를 입력해 주십시오.");
			bbs.delete(bbs.getInput());
		} else if (choice.equals("5")) {
			bbs.getList();
		} else if (choice.equals("x")) {
			bbs.exit();
			break;
		} else {
			System.out.println("잘못 입력 하셨습니다.\n다시 입력해 주십시오.");
		}
    }   
  }
}

'Java' 카테고리의 다른 글

Google Guava 라이브러리 사용하기  (0) 2014.07.24
Java Reflection 활용하기  (0) 2013.11.18
Java Console 게시판 만들기 - 3  (0) 2013.11.12
Java Console 게시판 만들기 - 2  (0) 2013.11.11
Java Console 게시판 만들기  (1) 2013.11.10


Express middleware는 Java 진영의 Springframework의 interceptor, aop 와 비슷한 성향을 가지고 있습니다.



위 그림을 참고 해보자.


서버로 요청이 들어오면 middleware 는 route / 모든 주소에 대해서 처리하라는 지시를 받습니다. 그 후 특정 url 에 대해서 처리를 한 후 응답을 하게 됩니다.


실제로 log를 확인해 봤습니다.


app object 중 stack

  stack: 
   [ { route: '', handle: [Function: query] },
     { route: '', handle: [Function: expressInit] },
     { route: '', handle: [Function: logger] },
     { route: '', handle: [Function: cookieParser] },
     { route: '', handle: [Function: bodyParser] },
     { route: '', handle: [Function: methodOverride] },
     { route: '', handle: [Function: test] },
     { route: '', handle: [Function: session] },
     { route: '', handle: [Function] },
     { route: '', handle: [Function] },
     { route: '', handle: [Function: router] },
     { route: '', handle: [Function: errorHandler] } ]


app object 중 router

_router: 
   { map: 
      { get: 
         [ { path: '/test/test',
             method: 'get',
             callbacks: [ [Function] ],
             keys: [],
             regexp: /^\/test\/test\/?$/i },
            ....
         ],
         post: 
         [ { path: '/test/test',
             method: 'get',
             callbacks: [ [Function] ],
             keys: [],
             regexp: /^\/test\/test\/?$/i },
            ....
         ]
      }
   }


서버로 request가 들어오는 이벤트가 발생할 경우 stack 을 통과하게 됩니다. 

개발자가 직접 정의 하는 middleware 는 test 라는 함수이고, 모든 url 처리는 stack 를 통과하고 특정 url은 router 에게 처리를 위임 하게 됩니다. 실제 code를 보도록 하자.


./express/lib/application.js 중 일부 입니다.

/** * Proxy `connect#use()` to apply settings to * mounted applications. * * @param {String|Function|Server} route * @param {Function|Server} fn * @return {app} for chaining * @api public */ app.use = function(route, fn){ var app; // default route to '/' if ('string' != typeof route) fn = route, route = '/'; // express app if (fn.handle && fn.set) app = fn; // restore .app property on req and res if (app) { app.route = route; fn = function(req, res, next) { var orig = req.app; app.handle(req, res, function(err){ req.app = res.app = orig; req.__proto__ = orig.request; res.__proto__ = orig.response; next(err); }); }; } connect.proto.use.call(this, route, fn); // mounted an app if (app) { app.parent = this; app.emit('mount', this); } return this; };

"default route to '/'" 내부적으로 기본 값으로 설정이 되는 것을 확인 할 수 있습니다. 


이제 실제 사용법을 알아보도록 하자.



http://expressjs.com/api.html#app.use 공식 홈페이지 Reference 자료 입니다.

두번째 인자로 function 이 사용 됩니다.


위 자료를 참고 하여 Sample Code 작성 해보자.

함수형으로 return 하자.

function test() {
  return function test(req, res, next) {
    console.log('test');   

    next();
  }
}

next() 는 stack 의 다음 주소로 가라는 함수 입니다. 실제로 next() 를 호출 하지 않는 경우 응답을 하지 못하고 서버에서 멈춰버리게 됩니다.


app.js 설정의 일부 입니다. 실제로 적용 하자.

function setting() {
  app.configure(function(){
    app.set('port', process.env.PORT);
    app.use(express.logger('dev'));
    app.use(express.cookieParser());
    app.use(express.bodyParser());
    app.use(express.methodOverride());

    // user middleware
    app.use(test());
    
    // session config
    app.use(express.session({
      secret: config.redis.secret,
      store: new RedisStore(config.options),
      cookie: config.cookie
    }));

    app.use(passport.initialize());
    app.use(passport.session());

    // router
    app.use(app.router);
  });  
}

use 함수 호출 하는 부분을 볼 수 있는데, 해당 행위는 모든 요청에 대해서 처리를 하겠다는 말입니다. 

위와 같이 적용 하면 모든 요청에 대해서 test 함수가 호출 되는 것을 확인 할 수 있습니다.


※ 참고 사이트: http://expressjs.com/



[Java Console 게시판 만들기 - 2] - http://blog.whitelife.co.kr/163


윗 글의 게시판 소스 개선 입니다.


-  Object 형태로 변경

-  게시판 Array가 꽉 찼을 경우 동적 Array 생성


이제는 게시글을 제한 없이 입력이 가능 합니다.


Bbs.java

import java.util.Scanner;

public class Bbs {
  
	private Scanner s;
	
	private String[][] bbses;
	private int seq;
	private int gindex;
	
	public Bbs() {
		this.s = new Scanner(System.in);

		this.bbses = new String[9][];
		this.seq = 1;
		this.gindex = 0;
	}

	public void addArray() {
		String[][] temp = this.bbses;
		
		this.bbses = new String[(int)temp.length + 10][];
		System.arraycopy(temp, 0, this.bbses, 0, temp.length);
	}

	public void readme() {
		System.out.println("1. 등록, 2. 상세보기, 3. 수정, 4. 삭제, 5. 목록, x. 종료");
	}

	public void exit() {
		System.out.println("프로그램을 종료 합니다.");
	}

	public String getInput() {
		return this.s.next();
	}

	public void create() {
		if (gindex == bbses.length) {
			this.addArray();
		}

		String no = String.valueOf(seq);
		
		System.out.println("input title...");
		String title = getInput();

		System.out.println("input content...");
		String content = getInput();

		String[] bbs = new String[3];
		bbs[0] = no;
		bbs[1] = title;
		bbs[2] = content;

		this.bbses[this.gindex++] = bbs;
		this.seq++;

		System.out.println("등록이 완료 되었습니다.");
	}
	
	private String[] getSearch(String no) {
		for (String[] bbs : this.bbses) {
			if (bbs != null && bbs[0].equals(no)) {
				return bbs;			
			}
		}

		return null;
	}

	private int getIndex(String no) {
		for (int i=0; i<this.bbses.length; i++) {
			String[] bbs = this.bbses[i];
			
			if (bbs != null && bbs[0].equals(no)) {
				return i;
			}
		}
		
		return -1;
	}

	public void read(String no) {
		if (no == null || no == "") {
			System.out.println("잘못 입력 하셨습니다.");
			return;
		}
	
		String[] bbs = getSearch(no);
		
		if (bbs == null) {
			System.out.println("게시글이 없습니다.");
			return;
		}
		
		System.out.println("no: " + bbs[0]);
		System.out.println("title: " + bbs[1]);
		System.out.println("content: " + bbs[2]);
	}

	public void update(String no) {
		if (no == null || no == "") {
			System.out.println("잘못 입력 하셨습니다.");
			return;
		}
	
		String[] bbs = this.getSearch(no);
		
		if (bbs == null) {
			System.out.println("게시글이 없습니다.");
			return;
		}

		System.out.println("input title...");
		String title = this.getInput();

		System.out.println("input content...");
		String content = this.getInput();

		bbs[1] = title;
		bbs[2] = content;

		System.out.println("수정이 완료 되었습니다.");
	}
	
	public void delete(String no) {
		if (no == null || no == "") {
			System.out.println("잘못 입력 하셨습니다.");
			return;
		}

		int index = this.getIndex(no);

		if (index == -1) {
			System.out.println("게시글이 없습니다.");
			return;
		}

		this.bbses[index] = null;
		this.gindex--;

		int length = this.bbses.length;				

		for (int i=0; i<length; i++) {
			
			if (index == 0) {
				break;
			}

			if (index == length-1) {
				break;
			}					

			if (i > index) {
				if (i < length) {
					this.bbses[i-1] = this.bbses[i];
					this.bbses[i] = null;
				}
			}
		}

		System.out.println("삭제가 완료 되었습니다.");
	}

	public void getList() {
		for (int i=0; i<this.bbses.length; i++) {
			if (this.bbses[i] == null) continue;				

			System.out.println("index: " + i);
			System.out.println("no: " + this.bbses[i][0]);
			System.out.println("title: " + this.bbses[i][1]);
			System.out.println("content: " + this.bbses[i][2]);
		}			
	}

    public static void main(String[] args) {

		Bbs bbs = new Bbs(); 

		while(true) {
			bbs.readme();		

			String choice = bbs.getInput();

			if (choice.equals("1")) {
				bbs.create();
			} else if (choice.equals("2")) {
				System.out.println("번호를 입력해 주십시오.");
				bbs.read(bbs.getInput());
			} else if (choice.equals("3")) {
				System.out.println("번호를 입력해 주십시오.");
				bbs.update(bbs.getInput());
			} else if (choice.equals("4")) {
				System.out.println("번호를 입력해 주십시오.");
				bbs.delete(bbs.getInput());
			} else if (choice.equals("5")) {
				bbs.getList();
			} else if (choice.equals("x")) {
				bbs.exit();
				break;
			} else {
				System.out.println("잘못 입력 하셨습니다.\n다시 입력해 주십시오.");
			}
        }	
    }
}


+ Recent posts