오늘 작성할 내용은 elasticsearch 소스를 직접 받아서  local(IDEA) 로 띄어보는 것을 해보도록 하자. 딱히 어렵거나 복잡하진 않지만 몇가지 할 작업이 있기에 작성해보도록 하자. 

기준은 mac과 intellij, elasticsearch 버전은 6.4  버전 gradle 4.9 기준으로 설명한다.

git clone https://github.com/elastic/elasticsearch.git

특정 작업할 공간에서 위와 같이 elasticsearch 를 받아오자. 물론 IDEA에서 직접 받아와도 된다. 

elasticsearch 를 받아왔다면 다음과 같이 커멘드창에 작성해야 한다.

cd elasticsearch
git checkout 6.4
gradle idea

저렇게 작성했는데 필자는 다음과 같은 에러가 발생하였다.

> Failed to apply plugin [id 'elasticsearch.build']
   > the environment variable JAVA_HOME must be set to a JDK installation directory for Java 1.10 but is [/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home] corresponding to [1.8]

정확한 이유는 모르겠으나 기존에 설치되어 있던 java10으로 변경하였다. java10이 설치 되어 있어 그런지.. 원래 6.4버전은 java8 부터 가능하다고 문서에 나와있는데. java8보다 높은 버전이 있어서 그런지 몰라도 java10으로 바꾸니 잘된다.

gradle idea 가 끝나면 elasticsearch 를 IDEA로 띄어보자. 그 후에 gradle를 리플레시 해보면 소스들이 모듈별로 잘 나눠져 있을 것이다. 

이정도만 해도 일단 반은 끝났다. 솔직히 여기까지 오는데만 해도 시간이 꽤 걸렸다. elasticsearch 자체만 빌드하는 것만으로도 오래걸린다. 소스가 워낙 많아서..

실제 서버를 돌리는 모듈은 server 라는 모듈에 있다.

캡쳐가 왜 이렇게 크지.. 

아무튼 server라는 모듈에 src/main/java/org/elasticsearch/bootstrap/Elasticsearch 보면 main 함수가 존재한다. 그걸 이용해 서버를 돌리면 된다. 한번 Run을 해보자. 아마도 안될 것이다. 이렇게 쉽게 된다면 굳이 이 글을 쓸필요가 없었을 것이다. 

일단 돌려보면 아래와 같은 메세지가 나온다.

ERROR: the system property [es.path.conf] must be set

es.path.conf 라는 프로퍼티가 필요 하다는 것이다. 일단 설정 파일이 필요한데 그 파일은 distribution/src/config 폴더 밑에 elasticsearch.yml, jvm.options, log4j2.properties 복사하여 설정할 경로에 복사하면 된다. 물론 이것을 그대로 `es.path.conf` 넣어도 상관은 없다. 하지만 필자는 따로 폴더를 만들어서 거기에 복사해 넣었다. elasticsearch.yml 보면 ${path.data} 와 같은 문자들이 있는데 지금은 필요 없다. 다 삭제해도 된다.

그 후에 다음과 같이 intellij 에 vm options으로 해당 프로퍼티에 경로를 작성해준다. 

다시 한번 Run 버튼을 눌러보자. 이번은 다른 에러가 발생한다.

Exception in thread "main" java.lang.IllegalStateException: path.home is not configured
	at org.elasticsearch.env.Environment.<init>(Environment.java:103)
	at org.elasticsearch.env.Environment.<init>(Environment.java:94)
	at org.elasticsearch.node.InternalSettingsPreparer.prepareEnvironment(InternalSettingsPreparer.java:86)
	at org.elasticsearch.cli.EnvironmentAwareCommand.createEnv(EnvironmentAwareCommand.java:95)
	at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
	at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
	at org.elasticsearch.cli.Command.main(Command.java:90)
	at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93)
	at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:86)

이번엔 path.home이 없다는 에러이다. 할일이 많다. path.home 도 역시 원하는 폴더를 만들어 작성하면 된다.

필자는 다음과 같이 작성하였다.

이제 다시 한번 돌려보자.  다시 돌려보면 일단 많은 에러가 발생한다. 한개씩 해결해보자.

org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: modules directory [/Users/wonwoo/elastic/modules] not found

첫 번째로 위와 같은 에러가 발생한다. 해당 설정 폴더에 modules  이라는 폴더를 찾을 수 없다는 것이다. 이 에러는 git으로 다운 받은 모듈들을 복사해서 넣어도 되고 아니면 실제 elastic  사이트가서 elasticsearch 를 다운받은 후에 모듈폴더만 가져와도 된다. 필자의 경우에는  elasticsearch 사이트가서 다운받은 후 해당 폴더에 넣어 두었다.  참고로 다운받는 것을 추천한다. git으로 clone한 모듈은 intellij 관련한 파일들도 있어 잘 파싱이 안되는 것 같았다. 

위와 같이 /Users/wonwoo/elastic/modules 폴더안에 elasticsearch 모듈들을 넣었다.  위와 같이 폴더를 넣고 다시 돌려보자. 

이제는 다음과 같은 에러가 발생한다.

main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTrustPermission" "register")

이 것은 정확한 원인은 잘 모르겠지만 해결 방법은 존재한다. 아마도 권한이 없어서 그런거 같은데.. 저것은 그냥 -Dlog4j2.disable.jmx=true log4j2의 jmx를 disable로 하는 것으로 끝냈다. 하지만 정확한 원인은 필자도 잘.. 

다시 한번 돌려보자. 그럼 아래와 같은 에러가 또 발생한다. 이놈의 에러는 언제쯤..

java.lang.NoClassDefFoundError: org/elasticsearch/plugins/ExtendedPluginsClassLoader

ExtendedPluginsClassLoader  클래스가 정의가 안되어 있다고 에러가 발생한다. 이것은 intellij 와 gradle 과의 관련이 있는 듯 하다. intellij에서 Edit Configurations 에 들어가 Include dependencies with "Provided" scope 를 다음과 같이 체크해 준다.

그 후에 다시 Run을 해보자. 

아마도 마지막 에러일 듯 싶다.

org.elasticsearch.bootstrap.StartupException: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createClassLoader")

이 것 역시 권한과 관련이 있어보인다.  이것의 해결방법은 ${JAVA_HOME}/conf/security/java.policy 파일을 열어서 다음과 같이 추가해주면 된다.

permission java.lang.RuntimePermission "createClassLoader";

이제 마지막으로 서버를 돌려보자. 그럼 아무 에러없이 정상적으로 서버가 올라가는 것을 볼 수 있다. 

정상적으로 서버가 동작하는지 확인하기 위해 다음과 같이 커멘드창에 입력하거나 브라우저를 띄워서 확인해보자.

$ http :9200
curl http://localhost:9200

{
    "cluster_name": "elasticsearch",
    "cluster_uuid": "ierbMoD4SDmXbY9xbsrQng",
    "name": "fcsWvlW",
    "tagline": "You Know, for Search",
    "version": {
        "build_date": "Unknown",
        "build_flavor": "unknown",
        "build_hash": "Unknown",
        "build_snapshot": true,
        "build_type": "unknown",
        "lucene_version": "7.4.0",
        "minimum_index_compatibility_version": "5.0.0",
        "minimum_wire_compatibility_version": "5.6.0",
        "number": "6.4.1"
    }
}

그럼 위와 같이 정상적으로 response가 나온것을 확인할 수 있다. 

오늘은 이렇게 elasticsearch 소스를 받아서 로컬로 띄어보는 작업을 해봤다. 별거 아닐줄 알았는데 해보니까 시간이 꽤 걸렸다. 혹시나 elasticsearch에 기여할 것이 있다면 위와 같이 해당 소스를 받아서 테스트를 해보도록 하자. 

그럼 오늘은 이만!