Gradle의 종속성 해결이 SpringBoot 플러그인으로 인한 것인지 묻지 않을 때의 예

개요



이 항목에서는 Gradle을 사용할 때 종속성 해결 방법이 작동하지 않는 경우의 예를 소개합니다.

Enterprise 계산기 만들기 Advent Calendar 2019 의 12/3 항목입니다.

가정 독자


  • Gradle을 사용하고 있고, SpringBoot를 사용하고 있을 때, 의존성 해결에 있어서 써드파티의 라이브러리가 왠지 낡은 버젼이 사용되지만, 라고 하는 경험이 있는 분.
  • JLine3 를 SpringBoot 로 사용할 때, Windows 플랫폼에서 JNA 로 기동하려고 하고 있을 때에 곤란하고 있는 분.

  • 사건



    로그



    Java에서 콘솔에서 키 입력을 한 문자씩 처리하고 싶을 때 JLine 사용의 항목을 작성했을 때, 다음과 같은 에러가 발생했습니다. 이런 사건에 대응하기 위한 수단 중 하나를 소개합니다.



    이 로그를 보려면,
            Suppressed: java.lang.NoSuchMethodError: com.sun.jna.Native.load(Ljava/lang/String;Ljava/lang/Class;Ljava/util/Map;)Lcom/sun/jna/Library;
    

    그렇다고 하는 것으로, 이용하고 있는 라이브러리중에서, 특정의 클래스에 메소드가 없지만, 라고 하는 바람에 읽을 수 있습니다.

    Gradle을 사용해 의존성 해결을 맡기고 있는데 뭐야 이것, 이라는 것이 됩니다만, 그러한 것이 되어 있으므로 어쩔 수 없습니다.

    확인



    Gradle에서 프로젝트가 사용하는 라이브러리의 확인 명령은 다음과 같습니다.
    gradle dependencies 
    

    예를 들어, 아래 그림과 같은 간단한 build.gradle을 준비하고,
    
    plugins {
        id 'java'
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation group: 'org.jline', name: 'jline', version: '3.12.1'
        implementation group: 'org.jline', name: 'jline-terminal-jna', version: '3.12.1'
    }
    

    실행하면 아래 그림과 같은 트리가 표시됩니다. 각 작업에 사용되는 라이브러리를 알 수 있습니다.
    
    > Task :dependencies
    
    ------------------------------------------------------------
    Root project
    ------------------------------------------------------------
    
    annotationProcessor - Annotation processors and their dependencies for source set 'main'.
    No dependencies
    
    apiElements - API elements for main. (n)
    No dependencies
    
    archives - Configuration for archive artifacts.
    No dependencies
    
    compile - Dependencies for source set 'main' (deprecated, use 'implementation' instead).
    No dependencies
    
    compileClasspath - Compile classpath for source set 'main'.
    +--- org.jline:jline:3.12.1
    \--- org.jline:jline-terminal-jna:3.12.1
         +--- net.java.dev.jna:jna:5.3.1
         \--- org.jline:jline-terminal:3.12.1
    
    compileOnly - Compile only dependencies for source set 'main'.
    No dependencies
    
    default - Configuration for default artifacts.
    +--- org.jline:jline:3.12.1
    \--- org.jline:jline-terminal-jna:3.12.1
         +--- net.java.dev.jna:jna:5.3.1
         \--- org.jline:jline-terminal:3.12.1
    
    implementation - Implementation only dependencies for source set 'main'. (n)
    +--- org.jline:jline:3.12.1 (n)
    \--- org.jline:jline-terminal-jna:3.12.1 (n)
    
    runtime - Runtime dependencies for source set 'main' (deprecated, use 'runtimeOnly' instead).
    No dependencies
    
    runtimeClasspath - Runtime classpath of source set 'main'.
    +--- org.jline:jline:3.12.1
    \--- org.jline:jline-terminal-jna:3.12.1
         +--- net.java.dev.jna:jna:5.3.1
         \--- org.jline:jline-terminal:3.12.1
    
    runtimeElements - Elements of runtime for main. (n)
    No dependencies
    
    runtimeOnly - Runtime only dependencies for source set 'main'. (n)
    No dependencies
    
    testAnnotationProcessor - Annotation processors and their dependencies for source set 'test'.
    No dependencies
    
    testCompile - Dependencies for source set 'test' (deprecated, use 'testImplementation' instead).
    No dependencies
    
    testCompileClasspath - Compile classpath for source set 'test'.
    +--- org.jline:jline:3.12.1
    \--- org.jline:jline-terminal-jna:3.12.1
         +--- net.java.dev.jna:jna:5.3.1
         \--- org.jline:jline-terminal:3.12.1
    
    testCompileOnly - Compile only dependencies for source set 'test'.
    No dependencies
    
    testImplementation - Implementation only dependencies for source set 'test'. (n)
    No dependencies
    
    testRuntime - Runtime dependencies for source set 'test' (deprecated, use 'testRuntimeOnly' instead).
    No dependencies
    
    testRuntimeClasspath - Runtime classpath of source set 'test'.
    +--- org.jline:jline:3.12.1
    \--- org.jline:jline-terminal-jna:3.12.1
         +--- net.java.dev.jna:jna:5.3.1
         \--- org.jline:jline-terminal:3.12.1
    
    testRuntimeOnly - Runtime only dependencies for source set 'test'. (n)
    No dependencies
    
    (n) - Not resolved (configuration is not meant to be resolved)
    
    A web-based, searchable dependency report is available by adding the --scan option.
    
    BUILD SUCCESSFUL in 2s
    1 actionable task: 1 executed
    
    

    이것을 보면 org.jline : jline-terminal-jna : 3.12.1이 net.java.dev.jna : jna : 5.3.1에 의존하기 때문에 Gradle이 사용할 수있게 해줍니다. 표시합니다.

    눈앞의 사건



    자, 이제 두 개의 플러그인을 추가해 보겠습니다. SpringInitializr 에서 SpringBoot 프로젝트를 만들 때 추가되었습니다.
    build.gradle의 전체는 아래 그림과 같습니다.
    
    plugins {
        id 'org.springframework.boot' version '2.2.1.RELEASE'
        id 'io.spring.dependency-management' version '1.0.8.RELEASE'
        id 'java'
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation group: 'org.jline', name: 'jline', version: '3.12.1'
        implementation group: 'org.jline', name: 'jline-terminal-jna', version: '3.12.1'
    }
    

    종속성을 확인해 봅시다.
    default - Configuration for default artifacts.
    +--- org.jline:jline:3.12.1
    \--- org.jline:jline-terminal-jna:3.12.1
         +--- net.java.dev.jna:jna:5.3.1 -> 4.5.2
         \--- org.jline:jline-terminal:3.12.1
    
    
    runtimeClasspath - Runtime classpath of source set 'main'.
    +--- org.jline:jline:3.12.1
    \--- org.jline:jline-terminal-jna:3.12.1
         +--- net.java.dev.jna:jna:5.3.1 -> 4.5.2
         \--- org.jline:jline-terminal:3.12.1
    

    어, , , net.java.dev.jna:jna:5.3.1 -> 4.5.2가 되어, 낡은 버젼의 것을 참조해 버리고 있습니다.

    이 상황은 플러그인의 동작 때문에 망설였고 Gradle 커뮤니티 사이트에서도 교환이있었습니다. 이하 인용.

    However, as you already suspected, Spring Gradle plugins do configure the dependency resolution by providing their own dependency management plugin:
    htps : // 기주 b. 코 m / sp 린 g-g 등 d ぇ p ㎅ 긴 s / 84.
    Using the spring boot plugin, you need to use that, but you can reconfigure dependencies there

    잠정 대책



    장래는 이 근처 잘 해 주기를 바라면서, 잠정 대책으로 스스로 dependeency를 하나 추가합니다. build.gradle은 아래 그림과 같습니다.
    plugins {
        id 'org.springframework.boot' version '2.2.1.RELEASE'
        id 'io.spring.dependency-management' version '1.0.8.RELEASE'
        id 'java'
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation group: 'org.jline', name: 'jline', version: '3.12.1'
        implementation group: 'org.jline', name: 'jline-terminal-jna', version: '3.12.1'
        implementation group: 'net.java.dev.jna', name: 'jna', version: '5.3.1'
    
    }
    
    

    이렇게 하면 의도한 버전의 라이브러리가 사용됩니다.
    default - Configuration for default artifacts.
    +--- org.jline:jline:3.12.1
    +--- org.jline:jline-terminal-jna:3.12.1
    |    +--- net.java.dev.jna:jna:5.3.1
    |    \--- org.jline:jline-terminal:3.12.1
    \--- net.java.dev.jna:jna:5.3.1
    
    

    이제 서두 오류가 사라졌습니다.

    결론



    이 엔트리에서는, Gradle의 의존 해결로, 잘못되었을 때의 대처의 일례로서, 의존관계를 확인하는 방법과, 이용 라이브러리를 덧쓰기로 하고 싶은 방법을 소개했습니다.

    좋은 웹페이지 즐겨찾기