Gradle构建的Jar包无法找到主类问题求助
Alright, let's break this down—you’ve got a JAR that has the correct App.class file, runs perfectly when you unpack it and run java com.my.company.App, but throws that frustrating "Could not find or load main class" error when using java -jar. The issue boils down to one key thing: your JAR’s manifest file isn’t properly configured to tell the JVM where your main class lives.
Why this happens
When you use java -jar, the JVM doesn’t scan the entire JAR for main classes—it looks exclusively at the META-INF/MANIFEST.MF file in the JAR’s root directory. It needs a Main-Class attribute that points directly to your fully qualified main class (in your case, com.my.company.App). If this attribute is missing, misspelled, or formatted wrong, the JVM won’t know where to start execution.
How to fix this with Gradle
You’ve got two solid options here—pick the one that fits your project setup:
Option 1: Configure the default jar task
If you’re using the standard Gradle java plugin, add this configuration to your build.gradle (Groovy DSL) or build.gradle.kts (Kotlin DSL) to explicitly set the main class in the manifest:
Groovy DSL
jar { manifest { attributes 'Main-Class': 'com.my.company.App' } // Optional: If your app depends on external libraries, include them in the JAR from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } }
Kotlin DSL
tasks.jar { manifest { attributes["Main-Class"] = "com.my.company.App" } // Optional: Package dependencies into the JAR from(configurations.runtimeClasspath.map { if (it.isDirectory) it else zipTree(it) }) }
After adding this, run ./gradlew jar to rebuild your JAR.
Option 2: Use the Gradle application plugin (recommended)
This plugin takes care of manifest configuration, dependency packaging, and even generates cross-platform executable scripts for your app. It’s way more streamlined for applications:
Groovy DSL
plugins { id 'application' } application { mainClass = 'com.my.company.App' }
Kotlin DSL
plugins { application } application { mainClass.set("com.my.company.App") }
Run ./gradlew assemble to build distributable packages (found in build/distributions/), or ./gradlew run to test your app directly. If you still want a standalone JAR, you can combine this with the shadowJar plugin to build a fat JAR with all dependencies included.
Verify the fix
Once you’ve rebuilt your JAR, check the manifest to confirm the Main-Class attribute is present:
unzip -p com.my.company.app-1.0.jar META-INF/MANIFEST.MF
You should see a line that looks like this:
Main-Class: com.my.company.App
If that’s there, running java -jar com.my.company.app-1.0.jar should work just fine and output "Hey, I'm running" as expected.
内容的提问来源于stack exchange,提问作者rbobrowicz

