본문 바로가기
Dev/Gradle

[Gradle/Windows] Caused by: java.io.IOException: CreateProcess error=206, 파일 이름이나 확장명이 너무 깁니다.

by 돈코츠라멘 2019. 11. 20.

Windows 환경에서 bootRun 실행 시 아래와 같은 오류가 발생할 수 있다.

Caused by: java.io.IOException: Cannot run program "C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" (in directory "D:\dev\rhea\safe\fds"): CreateProcess error=206, 파일 이름이나 확장명이 너무 깁니다
        at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:25)
        ... 8 more
Caused by: java.io.IOException: CreateProcess error=206, 파일 이름이나 확장명이 너무 깁니다
        ... 9 more

이 오류는 Gradle에서 bootRun을 실행할 때 자동으로 classpath를 지정하는데, 이 길이가 Windows에서 허용하는 길이 제한을 넘는 경우 발생한다. bootRun 실행 시 명령어의 풀버전은 --info 옵션과 함께 실행하면 확인할 수 있다.

$ gradle bootRun --info

해결 방법으로 종속성을 나열하는 manifest 파일을 만들고 그 jar 파일 하나만을 bootRun 호출시에 classpath로 잡아주는 방법이 있다.

task pathingJar(type: Jar) {
    dependsOn configurations.runtime
    appendix = 'pathing'

    doFirst {
        manifest {
            attributes "Class-Path": configurations.runtime.files.collect {
                it.toURI().toString().replaceFirst(/file:\/+/, '/')
            }.join(' ')
        }
    }
}

bootRun {
    dependsOn pathingJar
    doFirst {
        classpath = files("$buildDir/classes/main", "$buildDir/resources/main", pathingJar.archivePath)
    }
}

하지만 사용하는 필드나 메서드들이 gradle 버전 5 이상에서는 이미 모두 deprecated... 게다가 나는 Kotlin 유전데 kts 기준의 코드는 어딜 봐도 없었다.

위 코드를 kts로 바꾸고, 없어진 필드들의 대체제를 찾아가면서 종속성들의 Path 모음을 가지고 오는것. 그리고 bootRun 실행 시에 classPath를 그 manifest jar로 잡는 부분들은 해결하였다. 하지만 다른 문제로 결국 이 이슈를 마무리 지을 수 없었다. (포스팅 하단에 코드와 에러 첨부하였으니, 혹시 해결하시는 분은 알려주세요 ㅠㅠ 궁금해 미치것음)

역시 내가 고민인 건 남들도 고민인 것...! Gradle plugin이 있지 않을까 검색해보니 역시나 있다.

springBoot.mainClassName = "packages.ApplicationKt"
plugins {
    id("com.github.ManifestClasspath") version "0.1.0-RELEASE"
}

거의 하루를 꼬박 날렸는데, 단 세줄로 해결! mainClassName 이름을 지정한 것은 Kotlin 프로젝트라서 그런지 mainClassName을 자동으로 못 찾길래 따로 추가해주었다.

실패작

tasks.register<Jar>("pathingJar") {
    archiveAppendix.set("classpath")
    dependsOn(configurations.runtimeClasspath)
    doFirst {
        manifest.attributes["Class-Path"] = configurations.runtimeClasspath.get().joinToString(";")
    }
}

tasks.getByName<BootJar>("bootJar") {
    enabled = true
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        dependsOn(tasks.getByName("pathingJar"))
        // println(" --before" + classpath.asPath)
        classpath = sourceSets["main"].output + files(tasks.getByName("pathingJar").outputs.files.asPath)
        // println(" --after" + classpath.asPath)
    }
}

configurations.runtimeClasspath.get().joinToString(";")의 실행결과가 종속성들의 리스트를 모두 잘 가지고 오는 것을 확인하였으나, bootRun 또는 build 실행 시 아래 에러가 계속해서 발생하였다.

Cannot change dependencies of configuration ':projectName:subModuleName:implementation' after it has been included in dependency resolution

https://stackoverflow.com/questions/43954073/gradle-cannot-change-dependencies-of-configuration 링크에서 설명한 대로 doLast를 이용해보았지만, 결과는 마찬가지 ㅠ

댓글