'소프트웨어개발/Java'에 해당되는 글 48건

  1. Java, 리소스(Resource) 파일 로드하기
  2. Java, 아스키코드(ASCII), 유니코드(Unicode), UTF-8 설명
  3. MyBatis, Dynamic SQL 기본식 알아보기
  4. Java, BCrypt 해쉬 알고리즘으로 비밀번호 암호화하기
  5. Java, WebSocket 클라이언트 구현하기
  6. Java, 랜덤 난수, 문자열 생성하기
  7. Java, StrSubstitutor로 간단한 텍스트 템플릿 구현하기
  8. Java, Thumbnailator를 이용하여 이미지 썸네일 생성(변환)하기
  9. Java에서 User-Agent 파써 사용하기
  10. Gradle 기반의 Java 프로젝트에서 로컬 .JAR 라이브러리 추가하기

Java, 리소스(Resource) 파일 로드하기

개요

Java 기반의 프로젝트는 크게 2개로 파일의 성격을 구분할 수 있다. 첫째는 .java로 끝나는(빌드시 .class로 컴파일될) Source 파일이고 둘째는 소스가 아닌(컴파일의 대상이 아닌) Resource 파일이다. 흔히 작성하게 되는 각종 .xml 파일부터 .html, .js, .css 파일까지 모두 이 리소스 파일에 해당한다. 이번 글에서는 이러한 리소스 파일을 획득하는 방법을 설명하고자 한다.

리소스 파일 획득하기

// /src/main/resources/something.txt 파일을 읽어 온다.
String something = IOUtils.toString(getClass().getResourceAsStream("/something.txt"), "UTF-8");
  • Maven 또는 Gradle 기반 프로젝트는 /src/main/resources 디렉토리에 리소스 파일을 저장하도록 되어 있다. 이 디렉토리에 위치한 파일들은 .jar 파일로 빌드시 최상위인 루트 디렉토리에 위치하게 되는데 이 말은 런타임시 해당 파일들이 ROOT CLASSPATH에 위치한다는 것을 의미한다.

  • CLASSPATHROOT에 위치하므로 위와 같이 절대 경로인 /를 앞에 명시함으로서 리소스 파일을 로드할 수 있다. 상대 경로를 명시할 경우 명령을 호출한 클래스의 위치에 따라 경로가 달라진다.

  • getClass().getResourceAsStream() 메써드는 InputStream 오브젝트를 반환환다. 대상 리소스 파일이 텍스트일 경우 Apache Commons IO가 제공하는 IOUtils.toString()를 이용하여 대상 리소스 파일을 간편하게 문자열로 획득할 수 있다.

  • 만약 대상 리소스 파일이 존재하지 않을 경우 java.lang.NullPointerException을 발생시킨다.

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고

Java, 아스키코드(ASCII), 유니코드(Unicode), UTF-8 설명

아스키코드? 유니코드가 뭐지?

  • 컴퓨터가 처음 발명되었을 때 표현 가능한 문자는 128개였다. 이를 ASCII 코드라고 한다. 영어 알파벳과 통화를 포함한 여러 기호를 표현할 수 있었기에 미국을 중심으로 한 영어권에서는 사용하는데 아무 문제가 없었다.

  • 컴퓨터가 보다 대중화되면서 대부분의 서유럽 언어의 알파벳을 추가하여 256개의 문자를 표현할 수 있게 되었다. 이를 ISO-8859-1 코드라고 한다. 유명한 오픈 소스 서블릿 컨테이너인 Apache Tomcat의 기본 언어 코드가 바로 ISO-8859-1이다. 이 문제로 쿼리 스트링에 포함된 한글 문자열이 깨지는 것을 누구나 경험해봤을 것이다. 초창기 HTML의 표준 언어 코드였기 때문에 아직도 서유럽의 적지 않은 웹사이트들이 이 코드로 제공된다.

  • 초창기 컴퓨터 산업은 미국을 비롯한 서유럽이 이끌었기에 아무 문제 없었다. 문제는 그 외의 다른 언어를 사용하는 지역이다. 결국 독자적인 코드를 만들어 사용하게 된다. 한국의 경우 KSC5601-1987을 사용하였다.

  • Unicode(유니코드)는 파편화된 전세계의 언어 코드를 하나의 코드로 통일하기 위해 나왔다. 유니코드는 총 1,114,112개의 문자를 표현할 수 있다. Plane이라 불리는 17개의 영역이 각각 65535개의 문자를 표현할 수 있다.

\uAC00이 뭐지?

  • 유니코드(와 모든 언어 코드)의 각 문자는 식별 가능한 Code Point라는 숫자를 가진다.(데이터베이스의 PK를 생각하면 된다.) 예를 들어 유니코드의 0번째 문자는 0번째 Code Point라고 부른다. 유니코드에서는 아래 형식으로 표현한다.
// 한글 문자인 '가'를 가리키는 유니코드의 Code Point 문자열이다.
U+AC00
  • 첫번째 문자 U는 이 문자열이 유니코드의 Code Point임을 알려준다. + 이후의 4개 문자는 Code Point를 16진수로 표현한 것이다. AC00은 44032를 의미하는 16진수이다.

  • 전세계가 모두 유니코드를 사용한다면 아무런 문제가 없을 것이다. 하지만 때때로 과거에 개발되어 운영 중인 시스템이나 프로토콜 등의 호환성 문제로 유니코드를 ASCII로 표현해야 하는 상황이 생길 수 있다. 이런 문자열을 Unicode Escape Sequence라고 부른다. 형식은 아래와 같다.
// 한글 문자인 '가'를 의미하는 Unicode Escape Sequence이다.
\uAC00

  • Java에서는 아래와 같이 Unicode 문자열과 Unicode Escape Sequence 문자열을 손쉽게 상호 변환할 수 있다. (StringEscapeUtils을 사용하기 위해서는 Apache Commons Lang, ObjectMapper를 사용하기 위해서는 Jackson 라이브러리가 필요하다.)
// Unicode Escape Sequence는 char 타입의 변수에 바로 저장할 수 있다.
char gaChar = '\uAC00';

// 문자의 최소값인 '\u0000'을 저장한다.
char charMin = Character.MIN_VALUE;

// 문자의 최대값인 '\uFFFF'를 저장한다.
char charMax = Character.MIN_VALUE;

// "\uAC00\uB098\uB2E4\uB77C\uB9C8\uBC14\uC0AC"를 출력한다.
StringEscapeUtils.escapeJava("가나다라마바사");

// "가나다라마바사"를 출력한다.
StringEscapeUtils.unescapeJava("\uAC00\uB098\uB2E4\uB77C\uB9C8\uBC14\uC0AC");

// Jackson 라이브러리 사용시 Unicode Escape Sequence로 표현된 JSON 문자열로 변환할 수 있다.
ObjectMapper mapper = new ObjectMapper();
mapper.getFactory().configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
  • 앞서 언급했듯이 유니코드는 1,114,112개의 문자를 표현할 수 있으며 Code Point 범위는 U+0000부터 U+10FFFF가 된다. 하지만 Java는 유니코드의 0번 Plane의 65535개 문자 만을 지원한다. 따라서 출력 가능한 Unicode Escape Sequence의 범위는 \u0000부터 \uFFFF가 된다.

UTF-8은 뭐지?

  • UnicodeCode Point는 국제적인 표준 언어 코드를 설명하는 논리적 단위일 뿐이다. 같은 유니코드라도 실제로 컴퓨터에 어떻게 저장하느냐에 따라 여러가지 방식으로 나뉘어 진다. 이를 인코딩(Encoding) 또는 캐릭터셋(Charset)이라고 부르며 UTF-8, UTF-16 등 다양한 인코딩 방식이 존재한다. 인터넷 세계에서는 1999년 HTML4 표준이 등장한 이래 UTF-8을 표준 인코딩 방식으로 권장하고 있으며 오늘날 대부분의 텍스트는 UTF-8로 저장되고 있다. UTF-8 인코딩은 1개 문자를 Code Point에 따라 1~4 바이트로 가변적으로 저장하는 방식이다.

  • Java에서는 아래와 같이 UTF-8 인코딩을 사용할 수 있다.
// "가나다" 문자열을 UTF-8 인코딩의 바이트 배열로 저장한다.
byte[] bytes = "가나다".getBytes(StandardCharsets.UTF_8);

// UTF-8 인코딩된 바이트 배열을 문자열로 저장한다.
String text = new String(bytes, StandardCharsets.UTF_8);

// 문자열을 UTF-8 인코딩된 파일로 저장한다. Apache Commons IO 라이브러리를 사용하였다.
FileUtils.writeStringToFile(new File("C:\\utf8.txt"), "가나다라마바사", StandardCharsets.UTF_8);

참고글

저작자 표시 비영리 동일 조건 변경 허락
신고

MyBatis, Dynamic SQL 기본식 알아보기

개요

MyBatisXML 기반의 매우 유연하고 강력한 동적 SQL(Dynamic SQL) 작성 기능을 제공한다. 본 글에서는 Java 기본 타입에 대한 기본식 작성 방법을 소개하고자 한다.

먼저 읽어볼만한 글

bool

bool은 기본 타입으로 기본 값은 false이다.

<!-- true일 때 -->
<if test="value"></if>

<!-- false일 때 -->
<if test="!value"></if>

Boolean

Boolean은 기본 타입인 bool의 랩퍼 클래스로 기본 값은 null이다.

<!-- true일 때 -->
<if test="value"></if>

<!-- true가 아닐 때 (null 또는 false) -->
<if test="!value"></if>

<!-- null일 때 -->
<if test="value == null"></if>

<!-- null이 아닐 때 (true 또는 false) -->
<if test="value != null"></if>

int

int는 기본 타입으로 기본 값은 0이다.

<!-- 특정 값일 때 -->
<if test="value == 1"></if>

<!-- 특정 값보다 작을 때 -->
<if test="value lt 1"></if>

<!-- 특정 값보다 작거나 같을 때 -->
<if test="value lte 1"></if>

<!-- 특정 값보다 클 때 -->
<if test="value gt 1"></if>

<!-- 특정 값보다 크거나 같을 때 -->
<if test="value gte 1"></if>

Integer

Integer은 기본 타입인 int의 랩퍼 클래스로 기본 값은 null이다. 앞서 int 타입의 모든 조건을 가지면서 아래 조건을 추가로 가진다.

<!-- null일 때 -->
<if test="value == null"></if>

<!-- null이 아닐 때 (값을 가질 때) -->
<if test="value != null"></if>

String

String은 기본 문자열 타입 클래스로 기본 값은 null이다.

<!-- 특정 문자와 일치할 때 -->
<if test="value == 'H'.toString()"></if>

<!-- 특정 문자와 일치하지 않을 때 -->
<if test="value != 'H'.toString()"></if>

<!-- 특정 문자열과 일치할 때 -->
<if test="value == 'Hello'"></if>

<!-- 특정 문자열과 일치하지 않을 때 -->
<if test="value != 'Hello'"></if>

<!-- null일 때 -->
<if test="value == null"></if>

<!-- null이 아닐 때 (문자열을 가질 때) -->
<if test="value != null"></if>
저작자 표시 비영리 동일 조건 변경 허락
신고

Java, BCrypt 해쉬 알고리즘으로 비밀번호 암호화하기

개요

과거 전산실 근무 시절 인하우스 개발된 시스템을 유지보수하다가 놀란 것은 생각보다 많은 비율로 사용자의 비밀번호를 암호화하지 않은채 그대로 데이터베이스에 저장한다는 것이다. 비밀번호는 반드시 해쉬 알고리즘을 이용하여 암호화하여 저장해야 한다. 데이터베이스가 MySQL이라면 간단하게 MD5() 함수를 이용할 수 있을 것이다. 하지만 MD5 또는 SHA-1과 같은 단방향 해쉬 알고리즘은 해커의 공격으로부터 자유롭지 못하다. 현재까지 가장 안전한 해쉬 알고리즘은 BCrypt이다. 비밀번호 암호화에 특화되어 고안된 알고리즘이다. 본 글에서는 Java에서 BCrypt 해쉬 알고리즘을 이용하여 비밀번호를 보호하는 방법을 간단히 설명하고자 한다.

라이브러리 의존성 추가

/build.gradle 파일에 아래 내용을 추가한다.

dependencies {
    compile group: 'de.svenkubiak', name: 'jBCrypt', version: '0.4.1'
}
  • Java 진영의 BCrypt 해쉬 알고리즘 구현체인 jBCrypt 아티팩트를 추가하였다. 만약 Spring Boot 기반의 프로젝트라면 spring-boot-starter-security 아티팩트의 추가 만으로 BCrypt 해쉬 알고리즘을 사용할 수 있다.

BCrypt 사용 예

BCrypt의 사용 예는 아래와 같다.

// 사용자의 비밀번호
String password = "!@#$password1234";

// 위 비밀번호의 BCrypt 알고리즘 해쉬 생성, passwordHashed 변수는 실제 데이터베이스에 저장될 60바이트의 문자열이 된다.
String passwordHashed = BCrypt.hashpw(password, BCrypt.gensalt());

// 위 문장은 아래와 같다. 숫자가 높아질수록 해쉬를 생성하고 검증하는 시간은 느려진다. 즉, 보안이 우수해진다. 하지만 그만큼 응답 시간이 느려지기 때문에 적절한 숫자를 선정해야 한다. 기본값은 10이다.
String passwordHashed = BCrypt.hashpw(password, BCrypt.gensalt(10));

// 생성된 해쉬를 원래 비밀번호로 검증한다. 맞을 경우 true를 반환한다. 주로 회원 로그인 로직에서 사용된다.
boolean isValidPassword = BCrypt.checkpw(password, passwordHashed);

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고

Java, WebSocket 클라이언트 구현하기

라이브러리 종속성 추가

dependencies {
    compile group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.3.0'
}
  • WebSocket 서버에 연결하기 위해 Java-WebSocket를 추가하였다. Java-WebSocketWebSocket 서버 및 클라이언트 기능을 모두 제공하는 100% 순수 Java로 개발된 라이브러리이다.

WebSocket 서버 연결 후 메시지 발송 예제

// https://websocket.org/echo.html가 제공하는 WebSocket 에코 서버에서 기능 테스트
WebSocketClient webSocketClient = new WebSocketClient(new URI("ws://echo.websocket.org"), new Draft_10()) {

    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        // WebSocket 서버 연결 후 동작 정의, 아래는 Hello 메시지 발송
        this.send("Hello");
    }

    @Override
    public void onMessage(String message) {
        // WebSocket 서버에서 메시지 수신시 동작 정의, 아래는 Hello 메시지 수신시 연결 종료
        if (message.equals("Hello")) {
            this.close();
        }
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        // 서버 연결 종료 후 동작 정의
    }

    @Override
    public void onError(Exception ex) {
        // 예외 발생시 동작 정의
    }

};
// 앞서 정의한 WebSocket 서버에 연결한다.
webSocketClient.connect();

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고

Java, 랜덤 난수, 문자열 생성하기

라이브러리 종속성 추가

dependencies {
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'
}
  • 랜덤 난수, 문자열을 생성하기 위해 Apache Commons LangRandomUtils, RandomStringUtils를 사용할 것이다.

랜덤 난수, 문자열 생성 예제

// 1~100 사이의 수를 무작위로 뽑아 출력
int random = RandomUtils.nextInt(1, 100);

// 위를 응용하여 1%, 9%, 90%의 확률로 서로 다른 문자열을 출력
int PERCENT_1 = 1;
int PERCENT_9 = PERCENT_1 + 9;
int PERCENT_90 = PERCENT_9 + 90;

int random = RandomUtils.nextInt(1, 100);
if (random <= PERCENT_1) {
    System.out.println("1%");

} else if (random <= PERCENT_9) {
    System.out.println("9%");

} else if (random <= PERCENT_90) {
    System.out.println("90%");
}

// 10개의 영대소문자로 무작위 구성된 문자열을 반환
String random = RandomStringUtils.randomAlphabetic(10);
// LpYwErgEsx

// 10개의 아라비아 숫자(0~9)로 무작위 구성된 문자열을 반환
String random = RandomStringUtils.randomNumeric(10);
// 0930862746

// 10개의 영대소문자, 아라비아 숫자로 무작위 구성된 문자열을 반환
String ramdom = RandomStringUtils.randomAlphanumeric(10);
// wR56vTKN3N

// 10개의 한글 문자로 무작위 구성된 문자열을 반환
// 44032는 유니코드에서 한글의 시작 번지수, 55203은 종료 번지수
String ramdom = RandomStringUtils.random(10, 44032, 55203, false, false);
// 용섯둭꽁즪띑둎쭱컕켓
저작자 표시 비영리 동일 조건 변경 허락
신고

Java, StrSubstitutor로 간단한 텍스트 템플릿 구현하기

개요

Java 진영에는 많은 텍스트 템플릿 엔진이 존재한다. 대표적으로 FreeMarker가 있다. 강력하지만 간단한 텍스트 템플릿을 처리하기에는 무겁다. 닭 잡는데 소 잡는 칼을 사용하는 격이다. 짧고 단순한 텍스트 템플릿을 처리하기에는 Apache Commons Lang이 제공하는 StrSubstitutor가 적당하다. 이번 글에서는 이를 이용하여 간단한 텍스트 템플릿을 처리하는 방법을 소개하고자 한다.

라이브러리 종속성 추가

/build.gradle 파일에 아래와 같이 라이브러리를 추가한다.

dependencies {
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'
    compile group: 'com.google.guava', name: 'guava', version: '19.0'
}
  • StrSubstitutorApache Commons Lang에 속하기 때문에 해당 의존성을 추가한다.
  • Google Guava는 옵션이다. 소스 코드의 가독성을 위해 ImmutableMap을 사용할 수 있다. 자세한 예는 아래를 참고한다.

템플릿 적용하기

StrSubstitutor의 템플릿 기능을 적용하는 방법은 아래와 같이 매우 간단하다.

// 가장 일반적이고 원시적인 방법, 소스 코드 가독성이 떨어지며 추후 유지보수가 힘들다.
String boardId = "forum";
int postId = 65535;
String output = "/boards/" + boardId + "/posts/" + postId;

// StrSubstitutor의 템플릿 기능을 이용한 방법, 추후 유지보수가 편리하지만 소스 코드 가독성은 여전히 떨어진다.
String template = "/boards/${boardId}/posts/${postId}";
Map<String, Object> valueMap = new HashMap<String, Object>();
valueMap.put("boardId", "forum");
valueMap.put("postId", 65535);
String output = StrSubstitutor.replace(template, valueMap);

// Guava의 ImmutableMap을 이용하면 소스 코드 가독성이 좋아진다. 이 방법을 추천한다.
String template = "/boards/${boardId}/posts/${postId}";
String output = StrSubstitutor.replace(template, ImmutableMap.of("boardId", "forum", "postId", 65535));

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고

Java, Thumbnailator를 이용하여 이미지 썸네일 생성(변환)하기

개요

Java 진영은 javax.imageio 패키지명으로 제공되는 Java Image I/O API를 이용하여 리사이즈, 크롭 등의 이미지 처리를 할 수 있다. 이를 이용하여 Java 6 이상의 경우 웹에서 가장 많이 사용되는 JPEG, PNG, GIF(BMP 포함) 이미지를 자유롭게 처리할 수 있다. 하지만 단순히 이미지에 대한 썸네일만 하고 싶다면? Image IO의 사용법은 너무 번거롭다. 이번 글에서는 블로그 글로 쓰기 민망할 정도로 사용법이 쉬운 이미지 썸네일 생성 라이브러리인 Thumbnailator를 소개하고자 한다.

라이브러리 의존성 추가

Gradle 빌드 환경이라면 /build.gradle 파일에 아래와 같이 Thumbnailator 라이브러리를 추가한다.

dependencies {
    compile group: 'net.coobird', name: 'thumbnailator', version: '0.4.8'
}

Maven 빌드 환경이라면 /pom.xml 파일에 아래와 같이 추가한다.

<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.8</version>
</dependency>

이미지 썸네일 생성하기

이미지 썸네일을 생성하는 방법은 아래와 같다. 황당할 정도로 더 이상의 설명이 필요 없을 정도이다. 놀라운 것은 빠른 속도로 고품질의 썸네일을 생성한다는 것이다.

File image = new File("D:/image.jpg");
File thumbnail = new File("D:/thumbnail.png");
if (image.exists()) {
    thumbnail.getParentFile().mkdirs();
    Thumbnails.of(image).size(190, 150).outputFormat("png").toFile(thumbnail);
}

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고

Java에서 User-Agent 파써 사용하기

개요

User-Agent는 HTTP 요청시 헤더에 담겨 오는 정보로 요청 클라이언트의 디바이스 및 브라우저 정보를 담고 있다. 국제적으로 표준화되어 있지 않아 엄격히 관리되고 있지 않으며 어떤 값을 넣어도 상관없기 때문에 완전히 신뢰할 수 있는 데이터는 아니지만 간단한 통계 및 디바이스 특성에 따른 분기 처리에 있어 가장 기초가 되는 데이터이기도 하다.

Java 진영의 User-Agent 파써 도구들

User-Agent 파써의 관건은 자체적으로 보유한 데이터베이스의 양이 중요하다. 현재 이순간에도 실시간으로 새로운 User-Agent 정보가 추가되고 있기 때문이다. 데이터베이스가 주기적으로 갱신되지 않으면 새로운 기기, 새로운 브라우저에 대한 감지가 되지 않을 가능성이 높다.

  • user-agent-utils: Java 진영 최초의 User-Agent 파써이다. 현재 개발 중단되었다.

  • UADetector: Java 진영에서 가장 잘 만들어진 User-Agent 파써이다. 아쉬운 점은 2014-10 부로 User-Agent 데이터베이스의 업데이트가 중단되었다. 본 글에서 사용할 라이브러리이다.

  • uap-java: 사용자들의 참여로 현재까지 계속 User-Agent 데이터베이스가 업데이트되고 있는 uap-core 기반의 파써이다. 데이터베이스의 주기적 갱신이라는 측면에서 가장 높은 점수를 주고 싶다.

UADetector, 의존성 추가

본 글에서 소개할 파써는 UADetector이다. 먼저 /build.gradle 파일에 아래와 같이 라이브러리 의존성을 추가한다.

dependencies {
    compile group: 'net.sf.uadetector', name: 'uadetector-core', version: '0.9.22'
    compile group: 'net.sf.uadetector', name: 'uadetector-resources', version: '2014.10'
}

사용 예

String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36";

// User-Agent 데이터베이스를 로드하여 파써를 초기화한다. 초기화는 소모적인 작업이므로 Spring 환경의 경우 Bean으로 관리하는 것을 추천한다.
UserAgentStringParser parser = UADetectorServiceFactory.getResourceModuleParser();

// ReadableDevieCategory.Category를 반환한다.
// PERSONAL_COMPUTER, SMARTPHONE, TABLET, SMART_TV, WEARABLE_COMPUTER, GAME_CONSOLE, PDA, OTHER, UNKNOWN을 반환한다.
parser.parse(userAgent).getDeviceCategory().getCategory();

// ReadableOperatingSystemFamily.OperatingSystemFamily을 반환한다.
// WINDOWS, MAC_OS, BSD, LINUX, ANDROID, IOS, BLACKBERRY_OS, UNKNOWN 등을 반환한다.
parser.parse(userAgent).getOperatingSystem().getFamily();

// UserAgentType을 반환한다.
// BROWSER, MOBILE_BROWSER, OFFLINE_BROWSER, ROBOT, LIBRARY, UNKNOWN 등을 반환한다.
parser.parse(userAgent).getType();

// UserAgentFamily를 반환한다.
// CHROME, CHROME_MOBILE, FIREFOX, MOBILE_FIREFOX, SAFARI, MOBILE_SAFARI, IE, IE_MOBILE, UNKNOWN 등을 반환한다.
parser.parse(userAgent).getFamily();
저작자 표시 비영리 동일 조건 변경 허락
신고

Gradle 기반의 Java 프로젝트에서 로컬 .JAR 라이브러리 추가하기

개요

최근의 소프트웨어 개발 트렌드는 빌드시 명시된 중앙 저장소에 위치한 라이브러리를 다운로드 받아 프로젝트에 포함하는 편리한 방식으로 개발되고 있다. 이러한 관리 방법의 변화는 과거 DLL 지옥 또는 JAR 지옥의 공포로부터 개발자를 해방시켜 주었다. Java 진영에서는 빌드 툴인 Maven 또는 Gradle이 이러한 소프트웨어 의존성 관리 도구를 제공한다. 본 글에서는 Gradle 기반의 Java 프로젝트에서의 로컬 라이브러리에 대한 의존성 관리 방법을 설명하고자 한다.

중앙 저장소의 라이브러리 의존성 추가

Gradle에서는 Java 프로젝트 빌드시 포함할 외부 라이브러리는 아래와 같이 /build.gradle 파일에 외부 중앙 저장소와 라이브러리를 명시한다. 홈페이지에서 .JAR 파일을 다운로드할 필요가 없어 매우 편리하다.

repositories {
    mavenCentral()
}

dependencies {
    compile("org.projectlombok:lombok:1.16.8")
}

로컬 프로젝트의 라이브러리 의존성 추가

하지만 때때로 중앙 저장소에 존재하지 않는 라이브러리의 의존성을 추가해야 하는 상황이 발생하기도 한다. 프로젝트에 /libs 디렉토리를 생성하고 추가할 라이브러리의 .JAR 파일을 복사한다. /build.gradle 파일에는 아래와 같이 명시한다.

dependencies {
    compile files('libs/lombok-1.16.8.jar')
}

/libs 디렉토리에 위치한 모든 라이브러리를 의존성 추가하고자 한다면? 아래와 같이 명시한다.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고