프로그래밍/Vert.x2015.07.19 17:17

Vert.x 3.0이 지난 2015년 6월 24일 릴리즈 되었다.



Vert.x 2.x 에서 Vert.x 3.0 으로 넘어오며 많은 변화가 생겼다. 몇 가지 큰 변화를 살펴보면 다음과 같다.

(아래 목록을 포함한 다양한 기능 소개 및 문서는 http://vertx.io/docs/ 에서 확인할 수 있다.)


  1. Node.js의 Express 같은 강력한 웹 프레임워크 기능 제공
  2. MySQL, MongoDB, Redis를 위한 DataAccess 기능 제공
  3. 비동기 테스팅을 지원하기 위한 Vert.x Testing 제공
  4. Apache Shiro, JWT 등 다양한 인증 기능 제공
  5. RxJava 통합 기능 제공


그러나 Vert.x 3.0에서 제공하는 다양한 기능의 혜택을 누리기 위해서는 기존 Vert.x 2.x에서 Vert.x 3.0으로 마이그레이션 작업이 필요하다. 패키지 구조 및 의존성 변경, 빌드 방식에 변경에 있기 때문에 마이그레이션 작업이 생각보다 간단치 않다는 것을 염두해두자. 따라서 Vert.x 3.0에서 제공하는 기능을 꼭 사용하기 위해 기존 Vert.x 2.x 기반 애플리케이션을 반드시 업그레이드 해야겠다는 것이 아니면 기존 Vert.x 애플리케이션은 2.1.6 버전으로 유지하고 (2.1.6 버전은 2015년 6월 30일에 발표되었다. 몇 가지 버그 픽스가 이루어진 것으로 보인다. http://vertx.io/blog/vert-x-2-1-6-released/ 를 참고하자.) 앞으로 새롭게 개발할 Vert.x 애플리케이션에 3.0 을 적용해보는 것이 좋을 것 같다. 아래 링크는 Vert.x 3.0으로 마이그레이션 포인트에 대해 잘 설명하고 있다. 



특히 Vert.x Module 체계를 fat-jar 방식으로 변경함에 따라 기존 Maven Archetype 및 Plug-In이 완전히 소용없게 되어버렸다. (앞으로 Vert.x 3.0을 지원하기 위한 Maven Archetype, Plug-In이 나올지는 미지수이다. 아마 안나올듯...) 이것은 필자 처럼 IntelliJ나 Eclipse 같은 IDE 환경에서 Maven Archetype, Plug-In + Java 언어 조합으로 개발하던 개발자들에게 Vert.x 개발 환경을 다시 세팅해야 한다는 것을 의미하기도 한다(...)

따라서 본 포스팅에서는 Vert.x 3.0 개발 환경을 IntelliJ에 구축하는 것을 설명하도록 하겠다.

1. Vert.x 3.0 다운로드
일단 Vert.x 3.0 실행 바이너리를 다운로드 한다. (JDK8버전이 필요하다. Vert.x 3.0에서는 람다표현식을 매우 빈번하게 사용하고 있다.) 적당한 곳에 압출을 풀고 $PATH에 (압축해제 경로)/bin을 추가해두자. 잘 설치되었는지 확인해보기 위해 콘솔을 하나 열고 vertx -version을 입력해보자. 3.0.0이 출력된다면 설치가 완료된 것이다.

 PS C:\Users\home> vertx -version

 3.0.0 



2. IntelliJ 개발 환경 설정

일단 IntelliJ를 실행시키고, Maven기반 모듈을 하나 만든다. (archetype은 선택하지 않는다.) 적당한 groupId와 artifactId,version을 입력한다. 모듈이 생성되면 아래 그림과 같은 구조가 된다.



pom.xml의 내용도 아래 처럼 매우 간단하다.

<?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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.devop.vertx3</groupId> <artifactId>vertx3-test</artifactId> <version>1.0-SNAPSHOT</version> </project>

위 pom.xml의 내용을 https://github.com/vert-x3/vertx-examples/blob/master/maven-simplest/pom.xml를 참고하여 다음과 같이 수정한다. 편집한 pom.xml 파일은 Vert.x 3.0 필수 의존 라이브러리 관리 및 실행 가능한 fat-jar를 빌드하기 위한 내용을 담고 있다. (properties 항목의 main.verticle 값은 fat-jar가 실행될 때 main 함수 역할을 하는 entry class를 지정한다.)

<?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/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.devop.vertx3</groupId>
    <artifactId>vertx3-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!-- the main verticle class name -->
        <main.verticle>com.devop.vertx3.TestVerticle</main.verticle>
        <vertx.version>3.0.0</vertx.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.vertx</groupId>
            <artifactId>vertx-core</artifactId>
            <version>${vertx.version}</version>
        </dependency>
        <dependency>
            <groupId>io.vertx</groupId>
            <artifactId>vertx-hazelcast</artifactId>
            <version>${vertx.version}</version>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <!-- We specify the Maven compiler plugin as we need to set it to Java 1.8 -->
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>

        <!-- You only need the part below if you want to build your application into a fat executable jar.-->
        <!-- This is a jar that contains all the dependencies required to run it, so you can just run it with  java -jar -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <manifestEntries>
                                        <Main-Class>io.vertx.core.Starter</Main-Class>
                                        <Main-Verticle>${main.verticle}</Main-Verticle>
                                    </manifestEntries>
                                </transformer>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>META-INF/services/io.vertx.core.spi.VerticleFactory</resource>
                                </transformer>
                            </transformers>
                            <artifactSet>
                            </artifactSet>
                            <outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

이제 테스트를 위해 간단한 Verticle을 하나 작성해보자. 아래 Verticle은 logger를 통해 hello vertx3을 출력하는 아주 간단한 Verticle이다.

package com.devop.vertx3;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;

public class TestVerticle extends AbstractVerticle {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void start() throws Exception {
        logger.info("hello vertx3 ");
    }
}

위 TestVerticle을 IntelliJ에서 실행하기 위한 방법은 2가지가 있다. 


첫 번째 방법은 Vert.x 3.0에서 제공하는 io.vertx.core.Starter를 직접 사용해 Verticle을 실행하는 것이다. (io.vertx.core.Starter는 콘솔에서 vertx 명령을 입력했을 때 실행되는 class이다. 위 pom.xml 파일에서 main.verticle 값으로 지정한 entry class를 실행하는데에도 io.vertx.core.Starter가 사용되고 있음을 확인할 수 있다.)



위 그림 처럼 Run/Debug 설정의 Main class 항목에 io.vertx.core.Starter를 입력하고, Program arguments 항목에는 run 명령과 함께 실행할 Verticle class를 입력한다. 필요한 경우 run com.devop.vertx3.TestVerticle -conf conf.json 처럼 Verticl을 실행하는데 필요한 설정 파일을 함께 입력할 수 있다. 즉, 콘솔에서 vertx 명령을 실행할 때 입력할수 있는 모든 옵션은 Program arguments 항목에 입력할 수 있는 것이다. (io.vertx.core.Starter 자체가 vertx 명령을 의미한다.)


이제 IntelliJ에서 모듈을 실행해보면 콘솔에 'hello vertx3'이 출력되는 것을 확인할 수 있다.


두 번째 방법은 Verticle을 Embedded 방식으로 실행하는 것인데 이를 위해 아래 처럼 main() 함수를 포함하는 새로운 class를 하나 작성한다.

import io.vertx.core.Vertx;

public class TestLauncher {

    public static  void main(String[] args) {
        Vertx.vertx().deployVerticle("com.devop.vertx3.TestVerticle");
    }
}

TestLauncher와 TestVerticle을 포함하는 모듈 전체 구조는 아래 그림과 같다.



그리고 Run/Debug 설정을 아래 그림 처럼 변경한다. Main class 항목에 io.vertx.core.Starter대신 main() 함수를 포함하는 Launcher class를 입력하고 Program arguments 항목 값을 삭제한다.



앞에서와 마찬가지로 IntelliJ에서 모듈을 실행해보면 콘솔에 'hello vertx3'이 출력되는 것을 확인할 수 있다.


첫 번째, 두 번 째 방법 모두 브레이크 포인트를 설정하고, 디버그 모드로 실행해보면 프레이크 포인트에서 실행이 멈추고 정상적으로 디버깅 작업이 가능한 것을 확인할 수 있다. 한 가지 참고할 점은 Vert.x 3.0에서는 이벤트 루프 스레드가 오랜시간 블록되면 예외를 발생시키는데, 아래와 같이 StackTrace와 스레드가 블록된 시간 정보를 확인할 수 있다.


 경고: Thread Thread[vert.x-eventloop-thread-2,5,main] has been blocked for 18730 ms, time limit is 2000

 io.vertx.core.VertxException: Thread blocked

at java.lang.invoke.DirectMethodHandle.makePreparedLambdaForm(DirectMethodHandle.java:212)

at java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:188)

at java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:177)

at java.lang.invoke.DirectMethodHandle.make(DirectMethodHandle.java:81)

at java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:1656)

at java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:1613)

at java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(MethodHandles.java:1798)

at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1747)

at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:477)

at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$169(DeploymentManager.java:408)

at io.vertx.core.impl.DeploymentManager$$Lambda$4/992768706.handle(Unknown Source)

at io.vertx.core.impl.ContextImpl.lambda$wrapTask$15(ContextImpl.java:314)

at io.vertx.core.impl.ContextImpl$$Lambda$5/726281927.run(Unknown Source)

at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:357)

at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:357)

at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:111)

at java.lang.Thread.run(Thread.java:745) 


지금까지 IntelliJ에서 Vert.x 3.0 개발 환경 설정하는 방법에 대해 설명했지만, io.vertx.core.Starter의 역할만 이해하고 있다면 어렵지 않게 Eclipse에서도 Vert.x 3.0 개발 환경을 만들 수 있을 것이다.



3. fat-jar 패키징

Vert.x 3.0 기반 애플리케이션 개발을 완료 했다면, 해당 응용 프로그램을 어딘가에 배포해야 할 것이다. 이때 수 많은 class와 의존 라이브러리를 하나하나 관리하기는 번거로움이 있으므로, 하나의 모듈로 묶어서 관리할 수 있으면 매우 편리할 것이다. 기존 Ver.tx 2.x에서는 관련 class와 리소스를 묶어 Vert.x Module로 관리할 수 있었다.


그러나 Vert.x 3.0에서는 더 이상 이런 Vert.x Module을 사용하지 않는다. 대신 실행 가능한 far-jar 형태로 java -jar 명령을 통해 바로 실행 가능한 바이너리로 패키징한다. 앞서 살펴본 pom.xml 파일의 대부분의 내용이 fat-jar 패키징을 위한 내용이었다. 이를 위해 mvn clean package 명령을 실행하면 빌드가 실행되고, fat-jar가 생성된다. (Vert.x Module Repository에 등록되어 있는 모듈들은 어쩔 것인가!! 물론 쓸만한 모듈이 많지는 않다만은...)



아래는 java -jar 명령을 통해 fat-jar를 실행한 결과이다.


PS C:\Dev\intellij\my-work\vertx3-test\target> java -jar .\vertx3-test-1.0-SNAPSHOT-fat.jar

7월 19, 2015 5:12:19 오후 com.devop.vertx3.TestVerticle

정보: hello vertx3

7월 19, 2015 5:12:19 오후 io.vertx.core.Starter

정보: Succeeded in deploying verticle 


한 가지 흥미로운 것은 fat-jar에는 아래 그림 처럼 Vert.x 3.0 Core 라이브러리 등 실행에 필요한 모든 리소스가 함께 패키징 되기 때문에 fat-jar 파일 용량이 생각보다 크다는 것과 따라서 far-jar를 실행하는 시스템에서 반드시 Vert.x 3.0 바이너리를 설치하지 않아도 된다는 것이다.


저작자 표시 비영리 변경 금지
신고

'프로그래밍 > Vert.x' 카테고리의 다른 글

Vert.x 3.0 개발 환경 설정  (0) 2015.07.19
Posted by devop