[Git 만들어보기 - Geet] 프로젝트 생성 및 CLI 환경 세팅

송준섭 Junseop Song·2024년 2월 1일
post-thumbnail

2023-12-23 구현

위와 같이 Kotlin 프로젝트 생성

그리고 다음과 같이 테스트로 args를 받아와 실행해보았다.

개발 중에는 다음과 같이 Intellij IDEA의 도움을 받아서 args를 받아오려고 한다.

Progran arguments에 위와 같이 args에 담고자 하는 것들을 넣어줄 수 있음

코드 실행 결과 위처럼 args에 [”geet”, “init”]과 같은 배열이 담김

실제 사용시에는 빌드 후 jar 파일이 생기면 zsh 설정 파일에 alias를 “geet”으로 설정하여 jar를 실행시키고, 명령어를 보낼 생각이다.

즉 “geet init”이라고 치면 “geet”은 jar파일을 실행하는 용도, “init”이 실제 전해지는 명령어(args)인 것

예시로 진행해보았다.

일단 빌드

./gradlew build 명령어로 빌드 → 그러면 build/libs 폴더 안에 jar 파일이 생성되어있다.

그 후 zshrc에 아래와 같이 alias를 넣어준다.

vi ~/.zshrc

그리고 “geet” 명령어를 입력했더니 다음과 같은 에러가 발생했다.

/Users/songjs/projects/myproject/intellij/kotlin/Geet/build/libs/Geet-1.0-SNAPSHOT.jar에 기본 Manifest 속성이 없습니다.

“기본 Manifest 속성이 없습니다.” 에러를 해결하고자 GPT를 참고하였다.

tasks.jar {
    manifest {
        attributes["Main-Class"] = "MainKt"
    }
}

위와 같이 tasks.jarmanifest 관련 설정을 build.gradle에 추가해 주었다.

Main-Class는 실행하고자 하는 메인 클래스를 지정하는데, 이 클래스를 실행하기 위해 필요

만약 이러한 설정이 되어 있지 않다면, Manifest 속성을 명시적으로 추가하여 JAR 파일을 생성해야 한다.

위 예시처럼 tasks.jar 블록 안에 manifest 속성을 추가하여 Manifest를 설정할 수 있다.

그 후 빌드하고 다시 실행을 하려고 하니 다시 아래와 같은 에러가 발생하였다.

Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
        at MainKt.main(Main.kt)
Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
        ... 1 more

해결 참고

Gradle Project: java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics

tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "MainKt"
    }

    duplicatesStrategy = DuplicatesStrategy.EXCLUDE

    from(sourceSets.main.get().output)

    dependsOn(configurations.runtimeClasspath)
    from({
        configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
    })
}

tasks.jar 부분을 위와 같이 수정해주었다.

  1. manifest 설정:

    • manifest 설정은 JAR 파일의 메인 클래스를 지정하는 데 사용됩니다.
    • attributes["Main-Class"] = "MainKt"는 JAR 파일에서 실행될 메인 클래스를 MainKt로 지정합니다. Kotlin 스크립트의 메인 클래스 이름은 MainKt입니다.
  2. duplicatesStrategy 설정:

    • duplicatesStrategy = DuplicatesStrategy.EXCLUDE는 중복 파일이 있을 때 어떻게 처리할지를 지정합니다. 여기서는 중복을 제외하는 설정을 사용하고 있습니다.
  3. from 설정:

    • from(sourceSets.main.get().output)은 소스 세트의 출력을 JAR에 포함시키도록 지정합니다. 이 부분은 소스 코드 및 리소스 파일을 JAR에 포함시킵니다.
  4. dependsOn 설정:

    • dependsOn(configurations.runtimeClasspath)는 런타임 클래스패스에 있는 파일들을 JAR에 포함시키도록 지정합니다. 이는 빌드된 JAR 파일이 실행될 때 필요한 라이브러리와 종속성을 포함하게 합니다.
  5. frommap 설정:

    • frommap을 조합하여 런타임 클래스패스의 JAR 파일을 필터링하고, 필요한 파일들을 JAR에 추가합니다. configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) } 부분은 런타임 클래스패스에 있는 JAR 파일들을 필터링하여 JAR에 포함시키도록 구성합니다.

    이제 드디어 빌드 후 실행하면 잘 된다!!

0개의 댓글