lastruggling
lastruggling

Reputation: 1

How to create multi project fat jar as bundle of some libraries with buildSrc

First of all, sorry for my poor english.

Goal

I want create multi project containing some custom libraries as subproject with gradle.

For centralized dependency version control, using buildSrc and setting versions (spring-boot, detekt, ktlint etc.)

my-core-project(root)
+buildSrc
+-src/main/kotlin
+--int-test-convention.gradle.kts
+--library-convention.gradle.kts
+library-A
+-src
+--main/kotlin
+--test/kotlin
+-build.gradle.kts
+library-B
+-src
+--main/kotlin
+--test/kotlin
+-build.gradle.kts
+build.gradle.kts
+setting.gradle.kts

buildSrc contains common tasks for libraries(integration test, detekt, etc.) library-A and library-B are custom libraries based on spring boot.

There is no application module or any main method.

my goal is using method of library-A and/or library-B with another separated project with adding my-core-project to dependency.

Problem

./gradlew build created 3 jar files

my-core-project
+build/libs
+-my-core-project.jar
+library-A
+-build/libs
+--library-A.jar
+library-B
+-build/libs
+--library-B.jar

copied 3 jar files to libs directory under project which actually using these library, tried adding dependency created jar

with implementation(files("libs/library-A.jar")), class and methods are resolved well.

but with implementation(files("libs/my-core-project.jar")), class and methods are not unresolved.

when check my-core-project.jar, recognized that any information of sub projects contained.

Here is my setting.gradle.kts and build.gradle.kts of root directory.

# setting.gradle.kts

pluginManagement {
    repositories {
        mavenCentral()
        gradlePluginPortal()
    }
}
rootProject.name = "my-core-project"

include(
    "library-A",
    "library-B"
)
# build.gradle.kts

plugins {
    id("java-library")
    id("io.spring.dependency-management")
}

group = "com.demo"

version = "0.0.1-SNAPSHOT"

dependencies {
    api(project(":library-A"))
    api(project(":library-B"))
}

repositories {
    mavenCentral()
}

Tried things

In my opinion, my-core-project.jar should be fatJar(uberJar), so i added FatJar task like this

val fatJar = task("fatJar", type = Jar::class) {
    archiveBaseName.set("${project.name}-fat")
    from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
    with(tasks.jar.get() as CopySpec)
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

tasks {
    "build" {
        dependsOn(fatJar)
    }
}

but cannot resolve class and method, additionally occurs version conflict with other dependency of projects using this package, due to library-A created as fatJar too.

Question

  1. Is there a simple way packaging/bundling sub-modules into one jar file? if there are tasks like this already in gradle, prefer to use that.

  2. Modifying fatJar task like "add jar of submodules, not contained dependencies" can solve this problem?(even couldn't try completely newbie to gradle and kts.) if so, can you show me how to modify task?

  3. tried shadowJar already. that solved version-conflict problem with relocate option. but still couldn't resolve package in library-A

  4. If structure has problem, is there a good practice/example for "bundle of library"?

thanks for reading.

Upvotes: 0

Views: 413

Answers (1)

lastruggling
lastruggling

Reputation: 1

TL;DR

If someone faced this problem, try set archive name shorter than current one.

For someone who faced same problem, sharing some informations.

as result, resolved this problem.(maybe even not problem)

current shadowJar configure is as following

tasks.named<ShadowJar>("shadowJar").configure {
    archiveBaseName.set("shorten-name")
    archiveClassifier.set("")
    exclude("**/*.kotlin_metadata")
    exclude("**/*.kotlin_builtins")
}
  • exclude kotlin_metadata, kotlin_builtins
  • set shorten name(original project name was 30 long characters)

I have no idea but shorten jar file name has no problem.

Interesting one is, upload in artifactory package with original(long) name worked well.

I don't know Gradle declaring dependency with files has length constraints.

implementation(files("path/to/package"))

And now it works well with original name with local jar package file.

Upvotes: 0

Related Questions