티스토리 툴바


local 서버에서 remote 서버에 파일을 올리고 받을 때는 주로 FTP를 사용하지만, 시스템을 설정하고 테스트하고 잦은 파일 교환 작업을 할 때는 GUI툴을 사용하지 않고 local에서 파일을 복사하듯이 사용하고 싶을때가 종종 있습니다.

물론, 터머널에서 ftp 명령어로 파일을 올릴수도 있지요. 그런데 scp를 이용하면 조금더 직관적(?)입니다.
scp는 "Secure Copy"를 의미하고요, SSH를 통해서 이름처럼 안전하게 복사합니다.


Remote 서버에 파일을 올리기
$ scp -P 22 /home/myhome/test.tar tomcatuser@123.456.78.9:/home/tomcatuser/
이렇게 하면 test.tar 파일을 123.456.78.9 서버의 22번 포트로 SSH 접속하여 tomcatuser 사용자로 로그인 한 후 /home/tomcatuser/ 아래에 복사합니다.


Remote 서버에서 파일 받기
$ scp -P 22 root@123.456.78.9:/usr/local/tomcat/conf/server.xml /home/myhome/config/
이건 마찬가지로 remote 서버의 server.xml 파일을 local로 다운로드 받습니다.

SSH포트는 변경하는 경우가 많으므로 -P 옵션 사용했고, 서버 주소와 디렉토리의 구분은 콜론(:)을 사용합니다. 원격지의 home 주소는 "./"를 사용해도 됩니다. (root@123.456.78.9:./)


자주사용하는 옵션
  1. -P : 포트번호 지정
  2. -p : preserve의 약자로 원본 파일 시간의 수정시간, 사용시간, 권한을 유지합니다.
  3. -r : recursive의 약자로 하위 폴더/파일 모두 복사합니다.

저작자 표시 비영리
Posted by powerhan
MySQL 5.1

MySQL을 처음 설치하고나면, 그다지 되는게 별로 없죠?
가장 먼저 해줘야 하는 것이...
  1. 새로운 database 생성
  2. 새로운 user 생성 (일단은 admin 이겠죠!, root 말고)
  3. 생성한 admin user에게 database에 대한 전권(!) 주기

처음 mysql-server를 설치하고 나서 아래와 같이 mysql에 접속을 합니다. (-u 옵션하고 root는 붙여쓰는거 아시죠?)
$ mysql -uroot -p

내가 사용할 새로운 database를 생성합니다.

mysql> create database COKER character set utf8;
Query OK, 1 row affected (0.00 sec)

mysql> show databases; +--------------------+ | Database           | +--------------------+ | information_schema | | COKER              | | mysql              | +--------------------+ 3 rows in set (0.00 sec)

다음으로 COKER database의 관리자를 생성합니다. 사용자 정보는 mysql database의 user table에 있습니다.
한글을 쓰기위해 database 생성시 문자셋을 utf8로 지정해서 생성하면 편합니다. (나중에 바꾸면 전환작업을 해야해요).

mysql> create user cokeradmin;
Query OK, 0 rows affected (0.00 sec)

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select host, user from user;
+--------------+------------------+
| host         | user             |
+--------------+------------------+
| %            | cokeradmin       |
| 127.0.0.1    | root             |
| ANGEL-P-5310 | root             |
| localhost    | debian-sys-maint |
| localhost    | root             |
+--------------+------------------+
5 rows in set (0.00 sec)

이제 cokeradmin에 비밀번호를 지정하고, COKER database에 대한 모든 권한을 부여합니다.

위에서 host 칼럼은 어떤 host로부터의 접속 인지를 알려주는 것으로 위에서 root 사용자는 localhost에서 접속하는 것만 가능합니다. '%'는 모든 host를 의미하므로 cokeradmin유저는 원격에서 접속할 수 있겠네요.


mysql> set password for 'cokeradmin' = password('********');
Query OK, 0 rows affected (0.00 sec)

mysql> grant ALL on COKER to 'cokeradmin';

여기까지 해줘야,
외부 툴을 이용하거나 eclipse의 DTP 툴을 이용해서 접속을 할 수가 있습니다.

사용자를 추가하고 비밀번호를 부여하는 기본적인 방법은
mysql> create user 'cokeradmin'@'localhost' identified by '********';

이렇게 하면 password() 사용하지 않아도 적용됩니다.


뭐 간단한 거니까 위에서 굵은색 표시한 것은 좀 외워두면 좋겠죠.


참고)권한부여 예제 몇 가지
grant SELECT on COKER.* to cokeruser@'localhost' identified by 'asdf1234';
grant SELECT, INSERT, DELETE on COKER.* to cokeruser@'localhost' identified by 'asdf1234';
grant ALL on COKER to cokeruser@'%' identified by 'asdf1234';
grant ALL PRIVILEGES on COKER.ADDRESS to cokeruser@'%' identified by 'asdf1234';
flush privileges;

아래 각 표현식은 같은겁니다.
ALL, ALL PREVILEGES
COKER, COKER.*
cokeradmin, cokeradmin@'%'


추가
특정 사용자의 grant 목록을 보려면
mysql> show grant for 'root';
mysql> show grant for 'root'@'localhost';
mysql> show grant for 'root'@'123.456.78.9';




저작자 표시 비영리
Posted by powerhan
Spring과 Mybatis를 이용한 어플리케이션에서는 DAO 패턴과 함께 Spring의 의존성 삽입을 위해 인터페이스 클래서 + 구현 클래스 형태로 개발합니다.

DAO(Data Access Object)의 경우도 의존성 삽입을 위해 인터페이스와 그 구현 클래스가 필요한데, 대부분의 경우 DAO의 구현 클래스는 query ID와 파라메타만 전달하는 매우 단순한 구조를 가집니다. 그래서 가끔은 서비스 레이어와 DAO 레이어를 구분할 필요가 있는지, 또는 이 로직을 서비스 레이어에 넣어야 할지 아니면 DAO에 넣어야 할지 혼동되는 경우가 많습니다.

Mybatis-Spring은 이런 상황을 반영하여 MapperFactoryBean라는 proxy factory를 제공하니다.

Account를 조회/수정/추가/삭제하기 위한 기존의 방법은 기본적으로 4개의 java 클래스가 필요합니다.
AccountDao.java
AccountDaoImpl.java
AccountService.java
AccountServiceImpl.java

ApplicationContext.xml 에서는 bean 설정을 아래와 같이 합니다.

위의 설정에서 볼 수 있듯이 accountDao 빈을 생성하면서 AccountDaoImpl 구현 클래스를 정의하고 sqlSessionTemplate을 연결해 준 후 이를 accountService에 삽입하였습니다.

MapperFactoryBean을 사용하는 경우에는 아래와 같이 바뀝니다.

설정 어디에도 AccountDaoImpl을 정의하지 않았습니다. 실제로 구현 클래스를 만들 필요도 없지요. Context가 로딩될 때 MapperFactoryBean이 구현 클래스 프락시를 스스로 만들고 연결합니다.

테스트를 위해 별도로 AccountDaoImpl을 만들고 코드를 작성한 후 디버깅을 해보면 breakpoint 위치도 잡지도 못합니다. (로딩시 생성하는 proxy 객체를 타기 때문에 당연히 우리가 만들 클래스는 거치지도 않습니다.)


이렇게 MapperFactoryBean 사용할 경우의 이점은
  1. AccountDaoImpl.java를 아예 만들 필요가 없습니다.
  2. sqlSessionTemplate도 autowire로 자동으로 연결되므로 지정하지 않아도 됩니다.
  3. 비즈니스 로직을 서비스 레이어제 집중할 수 있습니다.

대신 몇 가지 제약사항도 있는데요,
  1. DAO 인터페이스의 메소드와 mapper XML 파일의 쿼리 ID의 이름이 같아야 합니다.
  2. 캐스팅 등 기존에 DAO에서 구현했던 로직을 서비스 객체에서 해줘야 합니다.

예를 들어, 서비스 클래스에서 dao.insertAccount(account) 라는 메서드가 있는 경우 mapper XML에서 실행 될 쿼리 ID는 <insert id="registerAccount" ...> 면 안됩니다. 똑같이 insertAccount라야 합니다.

DAO 구현 클래스에 아래와 같은 로직이 있다면 서비스 클래스로 옮겨야 합니다.
int rowCnt = getSqlSession().insert(query, account);
return rowCnt == 1 ? true : false;


DAO 레이어에서 반드시 구현해야 하는 로직이 아닌 단순 CRUD의 경우 이 방법을 사용하면 도움이 될 것 같습니다.






저작자 표시 비영리
Posted by powerhan
아직도 윈도우XP를 사용중입니다.
어느날 부턴가 윈도우 탐색기의 폴더트리 말고 우측 파일목록에서 폴더를 더블클릭하면 별도창에서 폴더가 열렸습니다.

수많은 구글링의 결과....

아래 레지스트리 파일을 실행하여 초기화 하고 나니까 해결이 되었습니다.




실행하는 방법은, 파일을 다운 받아 마우스 우클릭하면 나타나는 '병합' 메뉴를 클릭하고 탐색기를 다시 실행하면 됩니다.


출처 및 참고 자료
http://windowsxp.mvps.org/samewindow.htm
http://www.vistax64.com/tutorials/91587-open-folder-same-separate-new-window.html
저작자 표시 비영리
Posted by powerhan
탐색기에서 Ctrl+F 또는 찾기 버튼으로 파일을 찾을려고 하는데, 언제부턴가 이상한 검색창이 나옵니다. 예전 방식으로 바꾸려고 해도 도통 기능을 찾을 수가 없네요.

이게 Windows Desktop Search 라는 것을 알아내는 데도 긴 시간이 필요했습니다.



마치 통합 검색 기능처럼 보이는데요, 구글 데스크톱 통합 검색처럼 로컬 PC에서 통합 검색을 해주는 것 같지만 막상 실행해보면, Service가 떠있지 않다는 얘기를 비롯하여, 검색 시간도 길고, 저만 그런건지 모르지만 여간 거슬리는 기능일 수 없었습니다.

문제는, 지울수가 없다는 겁니다. 하루종일 구글링 해본 결과....
포기했습니다.

대신 무력화 하는 방법을 찾았습니다.

HKEY_CURRENT_USER\Software\Microsoft\Windows Desktop Search\DS\ShowStartSearchBand
값을 DWORD "0" 으로 수정

한가지 더..
윈도우 탐색기의 파일 검색은 등록된 확장자에 대해서만 내용 검색을 합니다. 이것도 옵션 조정으로 모든 파일을 검색할 수 있는데요, 아래와 같이 하면 됩니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ContentIndex\FilterFilesWithUnknownExtensions
값을 DWORD "1" 으로 수정


Window Desktop Search를 완전히 제거하는 방법을 빨리 찾았으면 좋겠네요.


추가내용
이 짓(?)을 하고나서 윈도우 탐색기에서 폴더가 새창으로 열리는 문제가 발생한 것으로 추측됩니다.
해결방법은 여기



저작자 표시 비영리
Posted by powerhan

Spring MVC에는 총 13개의 컨트롤러 클래스가 제공되고 있는데요, 그 계층구조를 보면 아래 그림과 같습니다. 모든 컨트롤러 클래스는 AbstractController를 상속받는 구조를 띄고 있고 이 추상클래스는 '템플릿 메서드 패턴'이 적용되어 있어 모든 하위 클래스들은 handleRequestInternal() 메서드를 구현하도록 규정하고 있습니다.


하나의 웹 요청이 처리되는 과정은 서블릿 컨테이너(예. 톰캣의 web.xml 파일)에서 SpringMVC를 사용하기 위해 설정한 DispatcherServlet이 지정된 컨트롤러의 인터페이스를 통해 handleRequest()메소드를 호출하고 몇 가지 검사한 후 handleRequestInternal()메서드를 호출하는 것으로 시작됩니다.



대부분의 컨트롤러 클래스는 org.springframework.web.servlet.mvc 패키지 안에 위치하지만 MultiActionController (그림에서 파란색)는 이 패키지의 하위 패키지인 ...mvc.action 패키지에 있습니다.

AbstractController
SpringMVC 컨트롤러의 최상위 추상클래스 입니다. 추상클래스이기 때문에 직접 사용할 수는 없고 자체 컨트롤러를 만드는 경우에 이 클래스를 상속받거나 이 클래스를 상속받은 다른 하위 클래스를 반드시 상속받게 됩니다.


AbstractUrlViewController, UrlFilenameViewController
URL, 즉 패스구조에 따라 적절한 화면을 석택하여 전달해주는 컨트롤러 입니다. UrlFilenameViewController의 경우 기능이 좀금 더 확장되어 패스의 접두어/접미어를 설정해 놓고 URL과 화면을 연결해줄 수 있습니다.


ParameterizableViewController
아주 단순한 컨트롤러 입니다. 미리 정의된 화면명과 요청주소 매핑 정보를 가지고 특정 URL을 가진 요청이 들어오면 준비된 화면을 전송하는 컨트롤러 입니다.


BaseCommandController
웹페이지의 폼객체와 같이 사용자 정보가 많은 요청을 처리할 수 있는 컨트롤러입니다. 이 클래스 역시 추상클래스로 직접 사용하지 않고 이를 상속받은 하위 클래스를 사용합니다. 이 컨트롤러는 요청이 들어오는 즉시 명령객체(Command class)를 생성하여 이를 자바빈 등의 객체와 연결시켜 줍니다. 추가로, Validator라는 일종의 도우미 클래스로 입력값에 대한 검증을 수행할 수 있습니다. 그런데, Spring 3에서부터는 annotated controller로 인해 이 계통의 클래스 들은 모두 사용이 중지 되었습니다.
하위 클래스 (AbstractCommandController, AbstractFormController, SimpleFormController, AbstractWizardFormController, CancellableFormController)


ServletForwardingController, ServletWrappingController
이 두 컨트롤러는 기존에 작성된 서블릿을 스프링의 DispatcherServlet 구조로 편입시키는데 용이합니다.


MultiActionController
다양한 형태의 요청을 컨트롤러 클래스로 처리하는데 적합한 컨트롤러 입니다. 가장 큰 특징 중 하나는 MethodNameResolver라는 것인데, 이름에서도 알 수 있듯이 특정 요청을 컨트롤러 내에 정의한 메서드 이름과 매치하는 것입니다. 장점이라면 빠른 개발이 가능하다는 것인 반면, 자동으로 오류를 찾아내는 것이 다소 어렵습니다.




저작자 표시 비영리
Posted by powerhan
우분투 10.10에서 11.04로 업그레이드 중에 "인증 오류 : 네트워크에 문제가 있을 수 있습니다..." 뭐 이런 내용의 오류가 발생했습니다.

한참동안 헤딩을 하다가 파일 권한에 문제가 있다는 것을 알게 되었습니다.

업데이트 메니저가 사용하는 설정파일들은 /etc/apt/ 아래에 있습니다.
이 파일들이 어떠한 이유에서인지 권한이 변경되어 버렸나 봅니다.

전체 파일들이 읽기 권한이 필요합니다.

chmod 명령어로 읽기 상태로 바꿔주니 잘 되네요.


ps. update-manager는 su 권한으로 실행이 될텐데 파일 권한 문제로 인증 오류를 내는 것이 좀 이상하네요.
저작자 표시 비영리
Posted by powerhan
가끔 이클립스를 실행할 때 메모리가 부족(OutOfMemoryError)해서 못띄우겠다던지 내지는 자바 버전이 낮다던지 하는 오류가 나오면서 정상적으로 실행이 안되는 경우가 있습니다. 이클립스는 실행될 때 eclipse.ini를 읽거나 뒤에 추가하는 명령행 인자 옵션을 가지고 시작하게 되는데 자신의 개발환경에 맞게 옵션을 조정하면 많은 문제를 해결할 수 있습니다. 본 게시물에서는 기본적인 옵션들을 설명할까 합니다.


이클립스 실행시 전달되는 정보는 크게 두 가지가 있습니다.
  • 이클립스에 절달되는 정보
  • 이클립스를 띄워주는 자바 가상머신에 전달되는 정보


정보를 전달하는 방법은 이클립스를 실행할 때 명령어 뒤에 옵션을 써주는 방법이 있고 별도의 eclipse.ini 파일에 기술할 수도 있습니다. 둘다 같은 결과를 보여주지만 eclipse.ini 파일에 기술할 때는 옵션과 전달 값을 각각 다른 줄에 써줘야 하는 규칙이 있습니다.

한 가지 주의 할 것은, 자바 가상머신에 전달될 정보들이 뒤에 와야 한다는 것입니다. 즉, 자바 가상머신으로 절달하는 인자임을 알려주는 -vmargs 와 그 뒤의 내용들이 이클립스에 절달될 옵션들보다 항상 뒤쪽에 와야 합니다.

자바 가상머신 옵션 목록 "java -X"를 실행하면 됩니다. 참고로, 자세한 이클립스 3.6 런타임 옵션 목록여기에서 확인할 수 있고, 자바 가상머신(HotSpot JVM)의 옵션 목록여기에 있습니다.


1. 주어진 자바 가상머신으로 이클립스 실행하기
$ eclipse -vm /opt/sun-jdk-1.6.0.02/bin/java


2. 힙메모리 사이즈를 조정하는 방법 (OutOfMemoryErrors 발생시)
$ eclipse -vmargs -Xmx256M


3. 이클립스 객체 생성용 메모리 최대크기 조정 방법 (java.lang.OutOfMemoryError: PermGen space 발생시)
$ eclipse -vmargs -XX:PermSize=64M -XX:MaxPermSize=128M
또는 eclipse.ini에 아래와 같이 추가
--launcher.XXMaxPermSize
256m

4. 이클립스 사용자 이름 변경
$ eclipse -Duser.name=Alex

5. 주어진 작업공간에서 시작하기
$ eclipse -data <작업공간 경로>


참고자료
  • http://wiki.eclipse.org/FAQ_How_do_I_run_Eclipse%3F
  • http://wiki.eclipse.org/Eclipse.ini

저작자 표시 비영리
Posted by powerhan
VirtualBox는 원래 Sun사에서 개발한 오픈소스 가상화 솔루션인데요, Sun이 Oracle에 인수되면서 4.x 버전부터는 Oracle의 이름이 붙어서 나오네요. 근데, 이름만 바뀐게 아니고 패키지 저장소까지 바뀌었습니다. 그래서 아무리 업데이트를 해도 계속 3.x 버전대만 남아 있는데, 이전 버전은 타 가상이미지를 불러올 때 문제가 좀 있는 듯합니다.

추가 : 11.04 Natty가 나오면서 기본적으로 VirtualBox 4가 설치됩니다. 하지만 최신버전을 원하신다면 역시 아래와 같은 방법으로 다른 저장소를 지정해줘야 합니다.

우분투의 패키지 저장소 목록 파일을 열고...
$ sudo vim /etc/apt/sources.list

설정에 한두 줄을 추가해 줍니다.
# VirtualBox 4.x Repo
deb http://download.virtualbox.org/virtualbox/debian maverick contrib non-free
※ 우분투 10.10인 경우만 maverick이고 10.04면 lucid 겠죠.

추가 : 11.04 Natty 용
deb http://download.virtualbox.org/virtualbox/debian natty contrib

저장소를 등록했으면 저장소 접근 키를 받아야 합니다.
$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -

그러면 저장소에서 패키지를 받을 수 있는 상태가 되겠죠. 로칼 저장소를 갱신하고 설치합니다.
$ sudo apt-get update
$ sudo apt-get install virtualbox-4.0

이렇게 설치가 끝나고 나면 기존에 설치되어 있던 3.x 대 VirtualBox는 자동으로 삭제가 됩니다. 엄연히 따지면 덮어쓰는 거겠죠.


참고자료
  • http://www.virtualbox.org/wiki/Linux_Downloads




저작자 표시 비영리
Posted by powerhan

Java enum class 사용법

Java 2011/02/18 09:19
Java의 enum class는 enumeration 즉, '열거형 타입'을 의미하는 특수한 클래스 입니다. 개발에 필요한 열거형 상수들을 적절히 모아서 조금더 객체지향적으로 사용할 수 있는 고급 기술(?)이고, 소스코드에서 하드코딩 요소를 제거하는데 큰 도움이 됩니다.

Java enum 사용법 1 - 기본 형태
원소들간의 구분은 콤마(,)로 합니다. 그리고 enum 객체 역시 클래스이기 때문에 기본생성자가 있어야합니다. 물론, 아래와 같은 경우에는 생성자를 생략해도 Java가 디폴트 생성자를 만들어줍니다.

더 간단하게 인라인 클래스로 배열 선언하듯 사용할 수 있습니다. public으로 설정되어 있기 때문에 SampleClass의 인스턴스를 sample이라고 할 때 sample.FontStyle.NORMAL 처럼 접근할 수 있습니다.


Java enum 사용법 2 - 추가 속성을 부여한 형태
아래는 enum 클래스의 각 원소에 별도 설명을 부여한 형태입니다. 사람이 이해하기 좋은 추가 속성을 지정했습니다. 각 원소 뒤에 괄호를 열고 primitive 속성으로 값을 지정하면 되고, 한개 이상의 경우 콤마로 구분하면됩니다. 단, 이경우에는 설명을 저자할 수 있는 필드가 하나 추가되고 생성자가 이 필드에 값을 설정할 수 있도록 인자가 있습니다.


Java enum 사용법 3 - 에러코드/에러설명을 정의한 사례
단순히 에러코드만 반환하는 환경이 아니라 사용자 친숙한 코드/설명 쌍으로 결과를 반환하는경우 또는 로깅을 조금더 보기 좋게 하는 경우 사용법2를 응용해서 속성이 2개인 원소들로 구성된 enum을 만들 수 있습니다.

실제로 사용할 때는 그때 그때 다르지만 MYException으로 래핑하기 위해 아래와 같이 throw new를 이용하고 MYException 객체는 인자로 enum 클래스를 받게 했습니다.


Java enum을 사용하지 않는 경우
enum을 사용하지 않고 위의 폰트 스타일 예를 분기하는 경우, 가장 쉽운 방법은 아래와 같을 겁니다.

이걸 조금 더 구조화해서 개발을 한다면 아래와 같이 별도의 static 클래스를 만들고 int 값으로 비교를 하는 것도 좋은 방법이 되겠죠. 실제로 가장 일반적인 방법이기도 하고요. SWT에서도 UI위젯의 style 속성 정의를 이런 식으로 합니다.



기존 방법의 문제점
enum은 아래와 같은 문제점들을 해결하기 위해 만들어졌다고 합니다.
  • 형검사를 하지 않으므로 오류발생 소지가 있다.
  • 네임스페이스를 따르지 않으므로 중복의 소지가 있다.
  • 순서 변경, 새로운 원소 추가에 취약합니다.
  • 알아보기가 어렵습니다.

제가 생각하는 enum의 가장 큰 장점은 소스코드 속에서 사용자가 직접 입력한 String을 제거할 수 있다는 것과, 자동 형 검사를 통해 오류를 줄일 수 있다는데 있는것 같습니다. 게다가 enum 클래스는 Java VM 1.5에서 지원하지 시작한 기능으로 아무 추가 작업없이 그냥 쓸 수 있죠.

C로 개발을 할 때도 코드에서 사용할 데이터 구조체와 상수값을 별도의 헤더파일로 뽑아내어 소스코드의 하드코딩 요소들을 제거 했었습니다. enum 클래스 헤더파일을 별도의 클래스로 분리한 겁니다. 형검사라는 강력한 기능이 추가되어서 말이죠.


TODO 다음 번에는 iBatis에서 enum 지원 방법에 대해 작성을 해보려고 합니다.




참고자료
http://download.oracle.com/javase/1.5.0/docs/guide/language/enums.html



저작자 표시 비영리
Posted by powerhan