Gradle에서 Java 멀티 프로젝트 만들기

16204 단어 자바gradle
Gradle에서 멀티 프로젝트를 수행하는 방법입니다.

단일 프로젝트에서 jar 파일 만들기



멀티 프로젝트 전에 먼저 단일 프로젝트에서 jar 파일을 만들고 실행해 보겠습니다.

gradle 프로젝트 만들기



gradle 초기화
$ gradle init

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 1

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Project name (default: JavaMultiProject): 

> Task :init
Get more help with your project: https://guides.gradle.org/creating-new-gradle-builds

BUILD SUCCESSFUL in 6s
2 actionable tasks: 2 executed

build.gradle 파일 수정



자동으로 작성된 build.gradle 파일을 약간 수정합니다.
중요한 것은 jar 작업을 만드는 것입니다.

build.gradle
apply plugin: 'java'
apply plugin: 'application'

sourceCompatibility = 11
targetCompatibility = 11

repositories {
    jcenter()
}

dependencies {
}

mainClassName = 'App'
jar {
    manifest {
        attributes 'Main-Class': "App"
    }
}

소스 생성



실행할 소스를 만듭니다.

src/main/java/App.java
public class App {
    public static void main(String[] args) {
        System.out.println("Hello");
    }
}

build와 실행을 시도합니다.



빌드 및 실행
$ gradle build

BUILD SUCCESSFUL in 2s
5 actionable tasks: 1 executed, 4 up-to-date

$ java -jar build/libs/JavaMultiProject.jar 
Hello

이제 무사히 단일 프로젝트에서 jar 파일을 만들고 실행할 수있었습니다.

다중 프로젝트 만들기



그럼 멀티 프로젝트를 작성해 보겠습니다.

이번 디렉토리 구성입니다.

구성
.(JavaMultiProject)
├── bar  (アプリケーションプロジェクト)
│   ├── src
│   ├── build.gradle
├── foo  (アプリケーションプロジェクト)
│   ├── src
│   ├── build.gradle
├── share  (共通ライブラリとして利用するプロジェクト)
│   ├── src
│   ├── build.gradle
├── build.gradle
├── setting.gradle

디렉토리를 작성하십시오.
$ mkdir -p bar/src/main/java
$ mkdir -p foo/src/main/java
$ mkdir -p share/src/main/java

setting.gradle 수정



멀티프로젝트를 하려면 setting.gradle로 설정합니다.

include에 하위 프로젝트를 지정합니다.

setting.gradle
rootProject.name = 'JavaMultiProject'
include 'foo', 'bar', 'share'

이렇게 하면 for bar share 디렉터리가 각각 하위 프로젝트로 인식됩니다.
IntelliJ IDEA에서도 이러한 방식으로 프로젝트가 인식됩니다.






build.gradle 수정



프로젝트 루트에 존재하는 build.gradle은 subprojects를 지정하여 모든 하위 프로젝트에 적용할 설정을 지정합니다.

build.gradle(root)
allprojects {
}

subprojects {
    apply plugin: 'java'

    sourceCompatibility = 11
    targetCompatibility = 11

    repositories {
        jcenter()
    }
}

그런 다음 하위 프로젝트 build.gradle이 됩니다.
애플리케이션 프로젝트인 bar 에서 살펴보겠습니다.

bar/build.gradle
apply plugin: 'application'

dependencies {
    implementation project(":share")
}

mainClassName = 'com.example.Bar'
jar {
    manifest {
        attributes 'Main-Class': "com.example.Bar"
    }
    from configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}

중요한 부분을 해설하면,
dependencies 내의 implementation project(":share")는 다른 하위 프로젝트인 share에 종속되어 있음을 정의합니다.

또한 jar 태스크에서 from 〜를 지정합니다. 이는 종속 라이브러리를 Bar 프로젝트의 jar에 포함시키는 것을 의미합니다.

덧붙여서, from 메소드가 존재하지 않는 경우는 jar 에 의존 라이브러리가 포함되지 않기 때문에 NoClassDefFoundError 에러가 출력합니다. 나가 이것에서 포장했기 때문에 당신을 위해.
$ java -jar bar/build/libs/bar.jar 
Exception in thread "main" java.lang.NoClassDefFoundError: com/example/Hello
    at com.example.Bar.main(Bar.java:5)
Caused by: java.lang.ClassNotFoundException: com.example.Hello
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 1 more

foo 프로젝트는 bar 프로젝트와 거의 같지만 만약을 위해 기재해 둡니다.
mainClassName만 Foo로 변경하고 있습니다.

foo/build.gradle
apply plugin: 'application'

dependencies {
    implementation project(":share")
}

mainClassName = 'com.example.Foo'
jar {
    manifest {
        attributes 'Main-Class': "com.example.Foo"
    }
    from configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}

share의 build.gradle은 이번에는 특별히 아무것도 언급하지 않았습니다.

share/build.gradle

코드

最後にコードを記載します。

bar/src/main/java/com/exmaple/Bar.java
package com.example;

public class Bar {
    public static void main(String[] args) {
        var hello = new Hello("Bar");
        System.out.println(hello.say());
    }
}
foo/src/main/java/com/exmaple/Foo.java
package com.example;

public class Foo {
    public static void main(String[] args) {
        var hello = new Hello("Foo");
        System.out.println(hello.say());
    }
}
share/src/main/java/com/exmaple/Hello.java
package com.example;

public class Hello {
    private final String name;
    public Hello(String name) {
        this.name = name;
    }

    public String say() {
        return name + " Hello!";
    }
}

빌드 및 실행

buildしてみます。
サブプロジェクトのタスクは:(プロジェクト名):(タスク名) 에서 실행합니다.

또, bar가 의존하고 있는 share 프로젝트의 build도 이 타이밍에 동시에 실행해 줍니다.

$ gradle :bar:build

BUILD SUCCESSFUL in 804ms
7 actionable tasks: 7 up-to-date

$ ls -l bar/build/libs/
total 8
-rw-r--r--  1 ysaito  staff  1591  4 29 21:15 bar.jar

참고로 작성된 jar를 해동해 보면 share의 내용의 Hello.class가 작성된 bar.jar에 포함되어 있는 것을 알 수 있습니다.

항아리를 풀고 확인
$ jar xvf bar.jar 
  META-INF/が作成されました
 META-INF/MANIFEST.MFが展開されました
  com/が作成されました
  com/example/が作成されました
 com/example/Bar.classが展開されました
 com/example/Hello.classが展開されました

jar가 생겼으므로 실행해 보겠습니다.
$ java -jar bar/build/libs/bar.jar 
Bar Hello!
$ java -jar foo/build/libs/foo.jar 
Foo Hello!

참고



Gradle User Guide -> 다중 프로젝트 빌드

좋은 웹페이지 즐겨찾기