You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多模块Kotlin-Gradle项目打可执行Jar后Kotlin Object初始化失败

Troubleshooting java.lang.NoClassDefFoundError for Kotlin Object in Fat Jar

Let's break down why you're hitting this error and how to fix it—even though the class exists in your jar, the JVM can't initialize it properly, which is what this error is really signaling (it's not that the class is missing, but that its initialization failed).

1. First: Uncover Hidden Initialization Exceptions

Kotlin objects are initialized lazily when first accessed, and if their init block (or property initializers) throw an exception, the JVM marks the class as failed to initialize—and subsequent attempts to access it throw NoClassDefFoundError without showing the original exception.

Add explicit error handling to your object to expose any hidden issues:

object MyKotlinObjectClass {
    init {
        try {
            // Wrap all your existing initialization logic here
            println("Initializing MyKotlinObjectClass...")
            // Example: If you're loading config files or external resources, add logs here
        } catch (e: Throwable) {
            e.printStackTrace(System.err)
            throw e // Re-throw to preserve the original error
        }
    }

    // Your existing variables
}

Re-package your jar and run java -jar again—you should now see the root cause exception in the output.

2. Fix Your Gradle Fat Jar Configuration

For Custom Jar Tasks

Your current setup uses compileClasspath, which in newer Gradle versions (7+) doesn't include all runtime dependencies (like Kotlin stdlib, or transitive dependencies from other modules). Switch to runtimeClasspath instead, and add a duplicates strategy to handle overlapping classes:

jar {
    manifest {
        attributes( 'Main-Class': 'my_package.RunnerKt' )
    }
    // Use runtimeClasspath to include all runtime dependencies
    from {
        configurations.runtimeClasspath.filter{ it.exists() }.collect { it.isDirectory() ? it : zipTree(it) }
    }
    // Handle duplicate classes (adjust based on your needs: INCLUDE, EXCLUDE, or FAIL)
    duplicatesStrategy = DuplicatesStrategy.INCLUDE
}

For Shadow Plugin

Make sure you're configuring Shadow to use the correct classpath and explicitly set the main class. Also, ensure your Shadow and Kotlin plugin versions are compatible (e.g., Shadow 7.x works with Gradle 7+ and Kotlin 1.7+):

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.9.20'
    id 'com.github.johnrengelman.shadow' version '7.1.2'
}

shadowJar {
    manifest {
        attributes 'Main-Class': 'my_package.RunnerKt'
    }
    // Explicitly use runtimeClasspath to include all required dependencies
    configurations = [project.configurations.runtimeClasspath]
}

// Optional: Tie shadowJar to the assemble task so it runs automatically
assemble.dependsOn(shadowJar)

3. Verify Multi-Module Dependencies

Double-check that the module containing MyKotlinObjectClass is correctly added as a dependency to your main module:

// In your main module's build.gradle
dependencies {
    implementation project(':module-with-your-object')
    // Other dependencies...
}

You can also verify the class is actually in the jar by running:

jar tf your-fat-jar.jar | grep MyKotlinObjectClass

You should see entries like my/kotlin/object/class/MyKotlinObjectClass.class.

4. Check for Circular Initialization or Classpath Conflicts

  • Circular Dependencies: If your Kotlin object references another class that also references the object, you'll get a silent initialization failure. Audit your code for circular dependencies between objects/classes.
  • Duplicate Classes: If your fat jar contains multiple versions of the same class (from conflicting dependencies), the JVM might load the wrong one. For Shadow, use the relocate feature to package conflicting dependencies under a unique namespace, or set duplicatesStrategy = DuplicatesStrategy.FAIL during packaging to catch duplicates early.

内容的提问来源于stack exchange,提问作者Andranik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 21:17:34