everydayminder

learn something everyday

Archive for the ‘java’ Category

커맨드라인에서 Maven/java 웹 프로젝트를 Tomcat에 배포하려면?

leave a comment »

java 웹 애플리케이션을 Tomcat에 배포하려면 여러 가지 방법이 있다.

1. 웹 애플리케이션 디렉토리 전체를 webapps 밑에 직접 복사하거나,
2. 웹 애플리케이션 디렉토리를 압축한 WAR 파일을 webapps 밑에 직접 복사하거나,
3. Tomcat의 매니저 웹 GUI를 통해, WAR 파일을 배포할 수 있다.

그러나, 직접 특정 디렉토리에 복사하는 방법은 무엇보다 번거롭다.
Tomcat의 매니저 웹을 통해 배포하는 것은 쉽지만, 자동으로 배포를 하고자 한다면 매번
사용하기 어렵다.

다음과 같은 경우, Cargo라는 프로그램/ 플러그인을 사용하면 좋을 것 같다.
1. 커맨드라인으로부터 웹 애플리케이션을 배포하고 싶다.
2. WAS가 로컬/리모트로 접근 가능하다.
3. Ant/ Maven을 사용하고 있다.
4. WAS가 다른 것으로 대체될 가능성, 혹은 서로 다른 WAS가 내 웹 애플리케이션에 혼용될 수도 있다.
5. 그러나, 동일한 방법으로 웹 애플리케이션을 여전히 배포하고 싶다. (커맨드라인으로부터)

Cargo에 대한 정확하고, 자세한 정보는 무엇보다 공식 홈페이지(http://cargo.codehaus.org)를 참조하는 것이
바람직하다.

홈페이지의 What is CARGO?란에서는 다음과 같이 Cargo를 소개하고 있다.
Cargo is a thin wrapper that allows you to manipulate various type of application containers
(Java EE and others) in a standard way.

주목할 만한 것은 결국, various type of application containers in a standard way라고 보면 될 듯 하다.

*  Cargo가 지원하는 Containers
– Geronimo 1.x ~ 3.x
– Glassfish 2.x ~ 4.x
– JBoss 3.x ~ 7.4.x
– Jetty 4.x ~ 9.x
– Jo! 1.x
– JOnAS 4.x ~ 5.x
– JRun 4.x
– Orion/OC4J 9.x ~ 10.x
– Resin 2.x ~ 4.x
– Tomcat 4.x ~ 8.x
– TomEE 1.x
– WebLogic 8.x ~ 12.1.x
– WebSphere 8.5.x
– WildFly 8.x

* Standard way = Cargo의 사용법 + container 별 설정
앞서 언급한 다양한 WAS들은 결국 몇몇 property를 선언하는 환경 설정의 문제로 국한된다.
본 글에서는 Maven 기반 웹 애플리케이션을 Tomcat7에 배포하는 설정을 간단하게 적어보고자 한다.

1. Tomcat 설정
Tomcat에는 기본적으로 권한 및 룰이 등록되어 있지 않기 때문에 Cargo를 사용하여 웹 애플리케이션을 배포하려면
그에 필요한 내용을 선언해야 한다.

Tomcat의 설치 디렉토리를 $CATALINA_HOME이라 할 때, $CATALINA_HOME/conf/tomcat-users.xml을 편집하여,
다음의 내용을 추가한다.

<role rolename="manager-script" />
<user username="deploy" password="deploy" roles="manager-script" />

GUI 기반이 아닌, CLI 기반으로 제어하기 위해, tomcat에 manager-script 롤을 선언한다.
배포에 사용할 계정 및 패스워드를 선언하고 (위의 예에서는 deploy/deploy), 이 계정에 앞서 선언한 manager-script 롤을
부여한다.

2. Maven 설정
Cargo 홈페이지상의 Downloads 탭으로부터 다운로드를 받을 수도 있으나,
Maven 기반으로 설정할 경우는, 본문에 표기된 바와 같이
If you want to use Cargo from Maven 2 or Maven 3, you don’t need to install anything at all as Maven will automatically download the required jars when you first use the plugin.

저절로 복사가 된다고 하였으나, 저절로 복사가 되도록 설정을 해줘야 한다.

http://repo1.maven.org/maven2/org/codehaus/cargo/cargo-maven2-plugin
에 접속하여 확인하면,

2014/7/28에 배포된 1.4.9가 이 글을 작성하는 시점 기준으로 가장 최신버전이다.
본 글은, 예전에 1.2.4로 테스트 환경을 구축한 것을 바탕으로 작성하였기에, 아래
설정에는 1.2.4로 기록하였다. (1.4.9로 적어도 동일하게 동작할 것이라 예상한다.)

pom.xml에 cargo-maven2-plugin 설정을 하자.

<plugin>
	<groupId>org.codehaus.cargo</groupId>
	<artifactId>cargo-maven2-plugin</artifactId>
	<version>1.2.4</version>
	<configuration>
		<container>
			<containerId>tomcat7x</containerId>
			<type>remote</type>
		</container>

		<configuration>
			<type>runtime</type>
			<properties>
				<cargo.remote.uri>http://tomcat_ip:tomcat_port/manager/text</cargo.remote.uri>
				<cargo.remote.username>username</cargo.remote.username>
				<cargo.remote.password>password</cargo.remote.password>
			</properties>
		</configuration>
	
		<deployer>
			<type>remote</type>
			<deployables>
				<deployable>
					<groupId>com.luran</groupId>
					<artifactId>jsweb</artifactId>
					<type>war</type>
					<properties>
						<context>/jsweb</context>
					</properties>
				</deployable>
			</deployables>
		</deployer>
	</configuration>
</plugin>

– cargo.remote.uri 에 Tomcat manager 주소를 http://ip:port/manager/text로 기록
– cargo.remote.username에 배포를 위한 계정 기록
– cargo.remote.password에 배포를 위한 계정의 비밀번호 기록
– deployable이하 내용에는 어떤 war로 배포할 것인지 (maven 형식) 기록
– properties~context에는, servlet context 명 기록 (본 예제에서는, http://ip:port/jsweb으로 배포함)

3. Maven을 통한, 웹 애플리케이션 관리
– deploy

mvn cargo:deploy 

또는

mvn cargo:deployer-deploy

– undeploy

mvn cargo:undeploy

또는

mvn cargo:deployer-undeploy

– redeploy

mvn cargo:redeploy

또는

mvn cargo:deployer-redploy

4. 자동 배포 응용 (빌드 서버 또는 스크립트 상)

mvn clean install package cargo:redploy

이와 같은 식으로 작성한다면, 빌드까지 모두 한 후 Cargo를 통해 Tomcat으로 웹 애플리케이션을
자동 배포할 수 있다.

Written by everydayminder

February 22, 2015 at 23:38

Posted in deploy, java, maven, tomcat

Tagged with

Eclipse/STS에서 maven 프로젝트 UTF-8, JDK 버전을 매번 해줘야 하나?

leave a comment »

Eclipse/STS에 사용중인 maven project로부터

1. 프로젝트를 새로 import할 때
2. Disable Maven Nature + Configure > Convert to Maven Project를 할 때

인코딩이 MS949로 자꾸 바뀌어서 수동으로 UTF-8로 바꿔줘야 했다면?
또 JDK 버전이 자꾸 1.5로 바뀌어서 수동으로 JDK 버전을 상위 버전으로 바꿔줘야 했다면?

다음의 옵션을 pom.xml에 추가해 보자.

pom.xml 파일 윗쪽에

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

와 같이 이 프로젝트는 UTF-8 인코딩이라고 선언해 주자.

pom.xml의 build 부분에 (없다면 추가로 써주면 된다)
아래와 같이 maven-compiler-plugin 선언을 하고, 사용하고자 하는 JDK 버전을 명시한다.

<build>
	<plugins>
		<plugin>
			<artifactId>maven-compiler-plugin</artifactId>
			<configuration>
				<source>1.7</source>
				<target>1.7</target>
			</configuration>
			<version>2.3.2</version>
			<executions>
				<execution>
					<id>default-testCompile</id>
					<phase>test-compile</phase>
					<goals>
						<goal>testCompile</goal>
					</goals>
				</execution>
				<execution>
					<id>default-compile</id>
					<phase>compile</phase>
					<goals>
						<goal>compile</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

이렇게 해서, SCM에 commit 하면, 새로 프로젝트를 import 할 경우와,
Maven Feature를 껐다 켤 때에도 인코딩과 JDK 버전이 설정한 대로 유지된다.

Written by everydayminder

November 27, 2014 at 23:24

Posted in java

Sonar + Jenkins 설정

leave a comment »

현재 Jenkins를 통해 CI(Continuouse Integration)를 하고 있고,
코드의 정적 분석을 FindBugs, PMD, CheckStyle을 써서 리포트를 보고 있긴 하지만,
Sonar를 접하고 설치/ 사용해보고자 한다.

Sonar는 http://www.sonarqube.org에서 세부 정보를 확인할 수 있다.
Installation Guide 링크를 따라 가보니, Confluence를 사용하여 위키를 꾸며놨다.

“Get Started in Two Minutes”의 설명에 따르면,
설치하고, 실행하는 방법은 무척이나 단순해 보인다.

1. SonarQube 배포판을 압축풀고, 실행시킨다.
2. SonarQube Runner 배포판을 압축풀고, 실행시킨다.
3. 샘플 프로젝트를 압축풀고, sonar-runner를 실행시켜서 분석시킨다.
4. 결과를 화면에서 확인한다. (http://localhost:9000)

여기까지 사실로부터 유추할 수 있는 사실은,
– SonarQube는 서버 프로그램이다.
– SonarQube는 클라이언트 프로그램이다. (소스 분석을 위해 실행시켜야 함)
– 별도의 웹서버/DB 설정이 필요없다.

정도이다.

Sonar에 대한 소개/분석 자료를 통해 좀더 알아보면,

Sonar가 지원하는 DBMS는

Apache Derby (내장)
mySQL
Oracle
PostgreSQL
MS-SQL Server

등이다.

설치에 앞서 JDK가 1.5+으로 설치되어 있어야 하며,
Runner(소스 분석을 위해 실행시키는 프로그램)로는
– SonarQube Runner
– Maven
– Ant
를 지원한다고 한다.

따라서, 앞서 언급한 Installation guide는 최소한의 설정으로 가장 빨리
한 번 실행시켜보기 위한 설정이라 할 수 있다.

0. 설치/테스트 환경
OS : Windows7 (64)
JDK : JDK1.6
DB : –

1. 설치
압축을 풀고 (c:\dev\sonarqube-4.0, 이하 $SONAR_HOME), $SONAR_HOME\bin\windows-x86-64\bin에
있는 SartSonar.bat를 실행시킨다.

wrapper | --> Wrapper Started as Console
wrapper | Launching a JVM...
jvm 1 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
jvm 1 |
jvm 1 | 2013.12.18 11:02:42 INFO Web server is started

와 같은 메시지가 보이면서 시작되었다.
브라우저를 통해, localhost:9000으로 접속해봐도 화면이 휑하다.
Sonar의 기본 관리자 계정 정보는 admin:admin이니 접속해 보자.

2. 환경설정 확인
$SONAR_HOME\conf\sonar.properties 파일을 확인해 보자.
별도 DB 설정을 하지 않았기에, Apache Derby 내장 DBMS를 사용하도록 설정된 채이다.

sonar.jdbc.username=sonar
sonar.jdbc.password=sonar

#—– Embedded database H2
# Note: it does not accept connections from remote hosts, so the
# SonarQube server and the maven plugin must be executed on the same host.

# Comment the following line to deactivate the default embedded database.
sonar.jdbc.url=jdbc:h2:tcp://localhost:9092/sonar

와 같은 문구가 보이고,
그 밑으로는 Sonar가 지원하는 여러 다른 종류의 DBMS의 configuration들이 주석처리 되어 있다.
해당 DBMS를 사용할 경우, 변경하여 사용하면 될 것 같다.

3. 프로젝트 분석은 어떻게?
Sonar는 분석 결과를 보여주는 웹 애플리케이션이고, 결국 분석은 다른 프로그램들이 도와줘야 한다.
http://docs.codehaus.org/display/SONAR/Analyzing+Source+Code
에 안내된 바에 따르면,

프로젝트 분석은 아래의 방법중 하나를 택하면 된다.
Analyzing with SonarQube Runner (recommended analyzer)
Analyzing with SonarQube Ant Task
Analyzing with Maven
Analyzing with Gradle
CI Engines

Sonar에 안내된 2분안에 시작하기 튜토리얼에서도 샘플 프로젝트 디렉토리로부터, SonarQube Runner를
실행시키는 것으로 프로젝트 등록/분석을 시도하였다.

결국, Runner 등과 같은 프로그램이 분석 결과를 DBMS에 기록을 하면, Sonar 웹은 그 데이터를 DB로부터 읽어서
보여줄 뿐일 것이다.

프로젝트 등록을 위한 UI도 존재하지 않는 것 같은데, 공식 도움말에서도 이런 문구를 발견할 수 있다.
Adding a project to SonarQube is not done through the web interface, but automatically when the project is analyzed for the first time.

어쨌든, 프로젝트를 등록하기 위해서는 일단 분석을 한 번 시도하면 된다는 이야기이다.

4. Jenkins + Sonar 설정
나는 Jenkins를 이미 사용하고 있으므로, Jenkins에 Sonar 설정을 하는 방법에 대해 살펴보고자 한다.
Jenkins에 Maven 관련 설정이 되어있다고 가정한다.

Jenkins 관리 > 플러그인관리 > Sonar 관련 플러그인들을 찾아 설치한다. (Jenkins Sonar Plugin, Sonargraph Plugin)
이후, Jenkins를 재시작하고, Jenkins의 global 설정으로부터 Sonar 환경설정을 하자.

Jenkins 관리 > 시스템설정 > Sonar (고급 메뉴) 관련 항목을 지정한다.
Apache Derby 사용 및 기본 설정으로 그대로 사용한다면, 아마 다음과 같이 입력하게 될 것이다.

Server URL : http://localhost:9000
Sonar account login : admin
Sonar acocun password : admin
Database URL : jdbc:h2:tcp://localhost:9092/sonar
Database login : sonar
Database password : sonar

Sonar Runner에 대한 설정은 별도로 수행하지 않았다.
프로젝트 설정의 Post-build Actions로부터 Sonar를 선택하고, jdk 설치 정보만 변경하고 저장하였다.
(다른 설정은 디폴트 사용)

이후, 빌드를 수행하면, 해당프로젝트의 대시보드에도 Sonar 아이콘이 생겨있고, 링크도 클릭가능하다.
해당 링크를 클릭하면, 결국 처음에 설정한 바와 같이 http://localhost:9000으로 리다이렉션 될 것이다.
그리고, 이전에 비어있던 화면에 무언가 정보가 채워져 있는 것을 발견할 수 있다.
당연히, Jenkins를 통하지 않고도, 브라우저에서 직접 http://localhost:9000을 접속하면 동일한 화면을 볼 수 있다.
(DB에 분석 데이터가 있으니까)

볼 수 있는 내용들은 다음과 같다.
Lines of code
Documentation
Duplications
Complexity
Issues
Package tangle index
Unit Tests Coverage

해당 항목들을 클릭하면, 상세 내용을 볼 수 있다.
이슈들을 클릭하면, 어떤 부분이 문제가 되고, 어떻게 해결하면 좋을지도 조언해 주기 때문에
코드의 퀄리티를 높이는데 큰 도움이 될 것 같다.

Jenkins에 이미 SCM 관련 설정을 해두어, 소스코드 변동에 따른 폴링/자동 빌드를 설정해 두었기 때문에
소스 변동시마다 Sonar도 분석을 자동으로 업데이트 하게 되었다.

5. Maven 단독
Maven으로 소스 분석을 하려면, maven 관련 설정을 변경해줘야 한다.
Sonar에 공식적으로 안내된, maven 설정은

<settings>
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!– Example for MySQL–>
<sonar.jdbc.url>
jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;characterEncoding=utf8
</sonar.jdbc.url>
<sonar.jdbc.username>sonar</sonar.jdbc.username>
<sonar.jdbc.password>sonar</sonar.jdbc.password>

<!– Optional URL to server. Default value is http://localhost:9000 –>
<sonar.host.url>
http://myserver:9000
</sonar.host.url>
</properties>
</profile>
</profiles>
</settings>

실행은,
mvn clean install -DskipTests=true
mvn sonar:sonar
와 같이 실행하면 된다.

그런데, 위의 설정만으로는 실제 사용시 번거로울 것 같다.

위의 설정에서 언급한 바와 같이, 분석을 어떻게 수행하느냐의 문제에 대해 생각해 보자.
Jenkins에 설정한 경우,
– Who : Jenkins
– How : Maven 또는 Runner
– When : 소스 변경이 되었을 때
로 생각할 수 있는데 비해,

Maven으로 단독 설정할 경우,
– Who : 사용자
– How : Maven
– When : 사용자가 명령어를 실행할 경우
가 되어 버린다. 결국, 소스를 사용자가 직접 최신 버전으로 업데이트 한 후, maven 명령어를 돌려야 의미가 있을 것이다.

즉, 소스 변경과 함께 자동으로 최신 소스를 검사할 수 있도록 설정하지 않고서는 별도의 maven 실행을 통한 소스 검사만으로는
활용도가 낮아진다.

6. 요약
– Jenkins와 같은 CI tool과 연계해서 Sonar 검사를 하도록 하거나
– 열심히 알아서 소스 갱신/ 검사 돌리자.

* SCM Activity라는 플러그인이 있는 것을 확인했으나, 주기적으로 폴링하여 소스를 가져오고 검사하는 용도가 아닌
SCM blame 정보를 출력해주기 위한 용도인 듯하다. (http://docs.codehaus.org/display/SONAR/SCM+Activity+Plugin)

*  소스 정적 검사 및 해결책 제시가 제법 괜찮다. 쓸만 한 것 같다.

Written by everydayminder

December 26, 2013 at 23:01

Posted in java, tools, Uncategorized

Tomcat Web Application 모니터링 툴 – javamelody 설정 방법

leave a comment »

Tomcat Web Application을 모니터링하거나, profiiling하기 위한 괜찮은 툴을 소개한다.

Javamelody(https://code.google.com/p/javamelody)를 설정하는 방법은 무척 간단하다.

1. Jar 설정
WEB-INF/lib 내 javamedloy.zip내의 javamelody.jar와 jrobin-x.jar를 복사한다.
내 경우는 maven 을 사용하므로, 기존의 pom.xml에 다음과 같이 dependency를 추가하였다.

 <dependency>
 <groupId>net.bull.javamelody</groupId>
 <artifactId>javamelody-core</artifactId>
 <version>1.43.0</version>
 </dependency>
 

2. web.xml 설정
기존에 실행하던 웹 애플리케이션을 모니터링/분석해야 하므로, web.xml의 내용을 편집한다.
보통 web.xml에서는 선언된 순서로 우선순위를 지니므로, 다른 서블릿 선언보다 위쪽에 다음의
설정을 추가로 기록한다.

 <filter>
 <filter-name>monitoring</filter-name>
 <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
 </filter>
 <filter-mapping>
 <filter-name>monitoring</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>
 <listener>
 <listener-class>net.bull.javamelody.SessionListener</listener-class>
 </listener>
 

3. 동작 확인
기본 설정은 이것으로 일단 끝!
이제 web application을 실행시키자.

 http://<host>/<context>/monitoring
 

과 같이 실행시키면, 기존 사이트에 대한 모니터링 페이지가 정상 적으로 보일 것이다.
대략 다음과 같은 화면이 뜬다.
http://javamelody.googlecode.com/svn/trunk/javamelody-core/src/site/resources/screenshots/graphs.png

4. 보안설정(ID/Password 기반)
role 기반으로 간략하게 보안 설정을 해보자. web.xml에 다음의 내용을 추가한다.

 <login-config>
 <auth-method>BASIC</auth-method>
 <realm-name>Monitoring</realm-name>
 </login-config>

<security-role>
 <role-name>monitoring</role-name>
 </security-role>

<security-constraint>
 <web-resource-collection>
 <web-resource-name>Monitoring</web-resource-name>
 <url-pattern>/monitoring</url-pattern>
 </web-resource-collection>
 <auth-constraint>
 <role-name>monitoring</role-name>
 </auth-constraint>
 </security-constraint>
 

만약, 이대로 tomcat을 restart하고, /monitoring으로 접근한다면, HTTP BASIC Authentication으로 인증 요청을 할 것이다.

5. tomcat-user 추가
위의 인증창에 접근할 수 있는 사용자를 추가하자.
tomcat-users.xml을 찾아 다음과 같이 사용자 정보를 추가한다.

 <tomcat-users>
 ..
 <role rolename="monitoring"/>
 <user username="monitoring" password="monitoring" roles="monitoring" />
 ..
 </tomcat-users>
 

이제 Tomcat을 재시작하고, BASIC authentication popup window가 뜨면, 위의 정보로 인증하고, 처음에 본 모니터링 페이지가 정상적으로 뜨는지 확인한다.

Written by everydayminder

August 1, 2013 at 02:20

Posted in Apache/Tomcat, java, tools

jasypt 사용중 org.jasypt.exceptions.EncryptionOperationNotPossibleException가 발생한다면?

leave a comment »

먼저, encrypt에 사용한 설정이 decrypt에 사용한 설정과 동일한지 확인하자.
그리고, DB의 필드가 충분히 긴지 확인하자.

나의 경우는, 위의 두 경우와 다른 경우였다.
output type을 default인 Base64에서 Hexadecimal로 변경하니, 위의 문제가 해결되었다.

이에 대한, jasypt의 공식 FAQ는 다음과 같다.

I keep on receiving EncryptionOperationNotPossibleException exceptions when trying to decrypt my data.
EncryptionOperationNotPossibleException is a very general exception which jasypt raises whenever there is a problem with encryption or decryption operations. It does not provide any further information to prevent the encryption infrastructure from showing too much information about what is going on (we wouldn’t want an attacker to get any algorithm-specific errors…)

When you get that error while decrypting, most of the times it will simply mean that the encrypted string you input was not adequate for the algorithm/password/keyObtentionIterations configuration you provided. Check that your encryptor is configured in exactly the same way as the one with which you originally encrypted the data.

Also, if you are storing your encrypted data into a database, check that the table columns that you use to store it are big enough to host the encrypted data (which is always bigger than the original data). If you are transmitting your encrypted data via HTTP, check that you are not having problems with the transmission of BASE64-encoded data as URL parameters (BASE64 uses characters which are forbidden in URL parameters, like “=”). For these uses, try using hexadecimal output.

Written by everydayminder

July 24, 2013 at 08:55

Posted in Hibernate, java

jasypt + BouncyCastle AES 설정

leave a comment »

Sun의 JCE에서도 AES를 지원하지만, Password Based Encryption방식으로 보다 많은 종류의 암호화 알고리즘을 지원하는 BouncyCastle 라이브러리를
설치하고, jasypt에서도 BouncyCastle을 사용한 AES 암/복호화를 사용하도록 설정해 보았다.

친근한 이름(어린 아이들이 좋아할)과는 다르게, 보안라이브러리이다.

1. BouncyCastle 다운로드
BouncyCastle의 공식 사이트는 http://www.bouncycastle.org이다.
본인이 사용하는 jvm 버전에 맞는 것으로 다운로드한다.
내 경우, jdk 1.6을 사용하고 있어 bcprov-jdk16-146.jar를 받았다.
maven을 사용하고 있다면, pom.xml에 아래와 같이 추가하여 다운로드 할 수도 있다.

 <dependency>
 <groupId>org.bouncycastle</groupId>
 <artifactId>bcprov-jdk16</artifactId>
 <version>1.46</version>
 </dependency>
 

2. BouncyCastle 설치
jar 파일이므로 임의의 디렉토리에 복사 후, classpath에 추가하거나,
$JAVA_HOME/jre/lib/ext에 복사하여 자동으로 classpath가 인식하도록 한다.

maven을 사용한다면, 위의 dependency 설정으로도 충분할 것이다.
라이브러리 설치 자체는 이것으로 끝났으나, 추가 환경설정이 필요하다.

3. BouncyCastle을 사용하기 위한 환경설정
BouncyCastle을 JCE Provider로 인식시키기 위해 추가 설정이 필요하다.
$JAVA_HOME/jre/lib/security/java.security 파일에 BouncyCastle을 등록하자.

4. jasypt에 BouncyCastle AES 사용설정
(1) application-context.xml에 hibernate.cfg.xml 설정

 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
 <property name="dataSource" ref="dataSource" />
 <property name="packagesToScan" value="com.luran" />
 <property name="configLocation" value="classpath:hibernate.cfg.xml" />
 </bean>
 

(2) hibernate.cfg.xml에 mapping.hbm.xml 지정 (type 선언 내용 포함)

 <hibernate-configuration>
 <session-factory>
 ...
 <mapping resource="META-INF/mapping.hbm.xml"/>
 ...
 </session-factory>
 </hibernate-configuration>
 

(3) mapping.hbm.xml내 타입 선언부 중, 알고리즘 변경 (PBEWITHSHA256AND128BITAES-CBC-BC)

 <hibernate-mapping package="com.luran.jasypt_test">
 <typedef name="encryptedString" class="org.jasypt.hibernate3.type.EncryptedStringType">
 <param name="algorithm">PBEWITHSHA256AND128BITAES-CBC-BC</param>
 <!-- <param name="providerName">BC</param> -->
 <param name="password">jasypt</param>
 <param name="keyObtentionIterations">1000</param>
 <!-- <param name="stringOutputType">hexadecimal</param> -->
 </typedef>
 </hibernate-mapping>
 

Written by everydayminder

July 17, 2013 at 05:08

Posted in java, Uncategorized

jasypt 1.9용 pom.xml 설정

leave a comment »

사실 잘 찾아보니(google), jasypt의 pom.xml 의존성 파일도
이미 mvn repository내 존재했다.

 <!-- Jasypt -->
 <dependency>
 <groupId>org.jasypt</groupId>
 <artifactId>jasypt</artifactId>
 <version>1.9.0</version>
 </dependency>
 <dependency>
 <groupId>org.jasypt</groupId>
 <artifactId>jasypt-hibernate3</artifactId>
 <version>1.9.0</version>
 </dependency>
 <dependency>
 <groupId>org.jasypt</groupId>
 <artifactId>jasypt-spring3</artifactId>
 <version>1.9.0</version>
 </dependency>

Written by everydayminder

July 15, 2013 at 08:35

Posted in java

jasypt의 type 선언 : annotation에서 xml로 변경해보기

leave a comment »

annotation 방식의 특성상, 정밀한 설정에는 용이하나 jasypt를 적용하면서 사용할 model 클래스에 매번 적어줘야 한다면,

역시 “불편”할 것이다.

그럴 때는, 역시 xml의 선언이 훨씬 편리할 것이다.

1. annotation 방식


@TypeDef (name="encryptedString", typeClass=EncryptedStringType.class,
 parameters={@Parameter(name="encryptorRegisteredName", value="strongHibernateStringEncryptor")})

2. XML 방식

XML로 객체를 만들지 않고, annotation을 사용하여 만든 상황에서 hbm.xml을 만들어 사용하는 식으로 연결을 해보았다.

hibernate-configuration과 hibernate-mapping은 다른 dtd를 사용하기에 별도의 파일로 만들었다.

 <?xml version="1.0"?>
 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.luran.jasypt_test">
 <typedef name="encryptedString" class="org.jasypt.hibernate.type.EncryptedStringType">
 <param name="algorithm">PBEWithMD5AndTripleDES</param>
 <param name="password">jasypt</param>
 <param name="keyObtentionIterations">1000</param>
 </typedef>
 </hibernate-mapping>
 

현재 jasypt.org에 안내된 가이드는 1.9 기준이기 때문에, 해당 클래스가

org.jasypt.hibernate4.type.EncryptedStringType

로 되어있다.  본 테스트에서 사용한 버전은 1.8이기에 위와 같이 변경해줘야 제대로 인식이 된다. (namespace가 변경된 것 같음)

이제 기존에 작성한 hibernate.cfg.xml에서 이 mapping.hbm.xml을 읽어들이도록 변경해주자.

hibernate-configuration.dtd에 보면, mapping attribute가 있다. 이 attribute에 방금 작성한 파일을 지정한다.

 <hibernate-configuration>
 <session-factory>
 ...
 <mapping resource="META-INF/mapping.hbm.xml"/>
 ...
 </session-factory>
 </hibernate-configuration>
 

앞서 작성한 annotation 방식 typedef를 주석처리하고, 이제 다시 실행시켜 보자.
동일하게 동작하는 것을 확인할 수 있다.

Written by everydayminder

July 11, 2013 at 08:30

Posted in Hibernate, java

Spring3.1 + Hibernate3 + jasypt1.8 연동테스트

leave a comment »

기존에 Spring 3.1과 Hibernate 3을 사용중이었는데,
DB에 저장된 데이터를 암호화해야 할 일이 생겼다.

Hibernate를 사용한 목적에 맞도록, 암호화도 DBMS에 transparent한 솔루션으로 적용하고 싶다.
조사해보니, jasypt라는 라이브러리를 사용하면 이를 비교적 적은 비용으로 구현이 가능한 것 같아 설치 테스트해 보았다.

jasypt.는 (Java Simplified Encryption)이라는 뜻이며, 공식 사이트는 http://www.jasypt.org 이다.
2013/7/11 현재 최신 버전은 1.9.0이지만, 중앙 maven repository에 올라와 있는 버전으로는 1.8이고,
Hibernate 관련 라이브러리가 1.8에는 동봉되어 있으나, 1.9.0에는 별도 관리되고 있는 것 같다.
(결국, maven 테스트의 편리성 때문에 그냥 1.8로 테스트를 진행했다.)

1. Maven Dependency 추가
pom.xml에 다음의 내용을 추가하였다.

<!-- Jasypt -->
<dependency>
    <groupId>org.jasypt</groupId>
    <artifactId>jasypt</artifactId>
    <version>1.8</version>
</dependency>

2. Spring bean 등록 (application-context.xml에 등록)

<bean id="strongEncryptor" class="org.jasypt.encryption.pbe.PooledPBEStringEncryptor">
    <property name="algorithm">
        <value>PBEWithMD5AndTripleDES</value>
    </property>
    <property name="password">
        <value>cUst0mP@sswOrd</value>
	<!-- Put whatever you want, it must be unique and strong -->
    </property>
    <property name="poolSize">
<value>4</value>
	<!-- to be optimal, put the number of cores of your processor-->
    </property>
</bean>

<bean id="hibernateStringEncryptor" class="org.jasypt.hibernate.encryptor.HibernatePBEStringEncryptor">
    <property name="registeredName">
        <value>strongHibernateStringEncryptor</value>
    </property>
    <property name="encryptor">
        <ref bean="strongEncryptor"/>
    </property>
</bean>

3. Type 정의

http://www.jasypt.org에는 hibernate.cfg.xml에 환경 설정을 등록하는 방법과, Spring내에서 annotation으로 등록하는 방법을 가이드하고 있는데,

어차피 Spring에서 annotation을 사용하고 있으므로, 그냥 model 클래스에 선언하여 사용해 보았다.

해당 model(entity) 클래스에 다음과 같이 적어준다.


@TypeDef (name="encryptedString", typeClass=EncryptedStringType.class,
 parameters={@Parameter(name="encryptorRegisteredName", value="strongHibernateStringEncryptor")})

4. 코드내 적용

이제 암호화를 원하는 필드에 위의 타입을 annotation으로 적용하자.

@Type(type="encryptedString")
public String getName() {
    return name;
}

별도의 decryption 옵션을 지정하지 않아도, 이제 model 객체는 자동으로 encrypt/decrypt를 수행하며,

해당 model을 사용하는 DAO들은 별도의 수정작업이 없이도 해당 model의 일부 필드를 암호화할 수 있게 되었다.

5.  기타 : JCE 설정

jasypt를 설치/테스트하는 도중, JVM내 JCE가 설치되어 있지 않은 것 같다는 에러 메시지가 떴었다.

오라클 공식 홈페이지에서 JCE 관련 파일을 받아서 설치하자.

Java SE Downloads 메뉴로부터 스크롤하여, Additional Resources부분을 살펴보면,

Java Cryptography Extension(JCE) Unlimited Strength jurisdiction Policy Files를 발견할 수 있을 것이다.

이 파일을 다운로드하여, 파일내 들어있는 jar파일들을 $JAVA_HOME/jre/lib/security에 풀어넣자. (기존에 있던 동일 이름의 파일들은

다른 곳에 복사해두자.)

이제 다시 실행시켜보면, 기존에 발생하던 JCE 라이브러리가 없다는 에러가 발생하지 않을 것이다.

6. 기타 : Hibernate 검색 관련

잠시만 생각해보면 당연하겠지만, 기존에 Hibernate의 criteria등을 써서 검색에 사용하던 필드가 암호화 대상 필드가 되었다면?

검색이 되지 않는다. 기본적으로 random salt를 사용하기 때문에 같은 값이라 하더라도, 다른 암호화 값으로 변화할 것이다.

동일한 ‘test’라는 문자열을 암호화했으나, salt가 달라서  다음과 같이 다르게 암호화 문자열이 생성된다.


Jq4AjAaYAjgM7oTJHySLZw==
bjMPhCbaL3fxgg+3KquOoA==

Random이 아닌 Fixed Salt Generator를 사용한다면? 같은 암호 문자열은 얻을 수 있을지 모르지만, 덜 안전한 데이터 관리방안이 될 것이다.

게다가, == 연산 이외의 >,< 등의 연산이나 like 와 같은 연산은 사용할 수 없게 될테니 주의하자. (= 설계부터 잘 하자.)

Written by everydayminder

July 11, 2013 at 07:06

Posted in Hibernate, java

Eclipse내 jUnit static import를 위한 설정

leave a comment »

jUnit4 이상을 사용하면서, hamcrest의 도움 없이는 온전한(가독성이 좋은) test case들을 작성하기 어렵다.

그런데, 이 jar들을 매번 import하자니 어렵고, 겨우 import해 놓으면 ctrl + shift + o를 누르는 순간 증발하기 일쑤다.

많은 개발자들도 이러한 점을 힘들어하여, 각 블로그에 여기저기 많이 남겨놓으셨다.

나도 이참에 기록을 남긴다.

1. static import할 라이브러리 등록하기

– Windows > Preferences >Java > Editor > Content Assist > Favorites 메뉴로 간다.

– New Type을 클릭하고 다음과 같은 라이브러리를 등록한다.


org.hamcrest.CoreMatchers.*

org.hamcrest.Matchers.*

org.junit.Assert.*

2. *로 대체하기 기능 설정

– Windows > Preferences > Java > Code Style > Organize Imports 메뉴로 간다.

– Number of static imports needed for .* (몇 번 이상 겹치면 *로 처리해줄까?) 의 숫자를 변경한다. (예 : 99 -> 1)

Written by everydayminder

July 10, 2013 at 10:45

Posted in java, TIPs, tools