NoClassDefFoundError for Gradle 7.6.3 * Java 8 Fatjar

I have created a java library with some factory and service class. Its a simple java 8 and gradle 7.6.3 project. My use case is to create a fatjar which can be used by anyone. fatjar is getting built with my custom class files and dependencies that i have added in build.gradle. But on trying to access the class in a client code i am getting NoClassDefFoundError

build.gradle in jar project -

plugins {
	id 'java'
    id 'jacoco'
}
version = "1.0.0"
repositories {
    mavenCentral()
    
}
jacoco{
toolVersion = "0.8.7"
}

jacocoTestReport {
    reports {
        xml.enabled true
        csv.enabled false
        html.destination file("${buildDir}/jacocoHtml")
    }
    afterEvaluate {
       classDirectories.from = files(classDirectories.files.collect {
           fileTree(dir: it, exclude: ['**/com/test/lib/interfaces/**'])
       })
   }
}


dependencies {
    implementation 'software.amazon.awssdk:secretsmanager:2.21.44'
       implementation 'software.amazon.awssdk:auth:2.21.44'
       implementation 'org.apache.commons:commons-lang3:3.9'
        implementation'com.fasterxml.jackson.core:jackson-databind:2.16.0'
implementation 'org.tinylog:tinylog:1.3.6'


		implementation'com.azure:azure-security-keyvault-secrets:4.7.3'
	implementation	'com.azure:azure-identity:1.8.3'
		implementation'com.google.cloud:google-cloud-secretmanager:2.31.0'
    
    testImplementation  'junit:junit:4.13.1'
          testImplementation  'org.mockito:mockito-core:4.11.0'
          implementation group: 'com.google.auth', name: 'google-auth-library-oauth2-http', version: '1.21.0'
          
    

  
}
ext.mockitoVersion='4.11.0'


task buildJar(type: Jar) {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE

    manifest {
        attributes 'Implementation-Title': 'Gradle Jar ',  
            'Implementation-Version': version       
    }
    baseName = "testlibrary"
	    from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

Created jar using ./gradlew clean buildJar command
Please note i dont have any main method. Its just a normal library whos factory method will be used to create a cloud provider and then some related cloud operations will be performed.

CLient Code - Created a folder name libs and placed the jar inside it.
added dependency -

implementation files('libs/testlibrary.jar')

Did a gradle refres from the IDE. I could see the jar under project and external dependencies and it had my custom java filea and dependent files specified in build.gradle.

Note: If i do a normal ./gradlew clean build, jar is getting created with only my custom files .but no gradle dependecies and client code is able to find my TestFactory class.it fails when it goes inside as it cant find dependencies like say logger.But with above task, it creates jar with gradle defined dependencies,but it cant find my file itself.

Error:

Exception in thread "main" java.lang.NoClassDefFoundError: com/test/lib/factory/TestFactory
	at tes.Library.main(Library.java:11)
Caused by: java.lang.ClassNotFoundException: com.test.lib.factory.TestFactory
	at java.net.URLClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)

What am i doing wrong here?

The standard jar task only contains your code.
The buildJar task you created you only configured to contain the compileClasspath but not your code.
So what you get is exactly what you configured.
Besides that the runtimeClasspath makes more sense.

If you really want to build such a bad-practice fat jar, I’d recommend you at least use the GitHub - johnrengelman/shadow: Gradle plugin to create fat/uber JARs, apply file transforms, and relocate packages for applications and libraries. Gradle version of Maven's Shade plugin. plugin which at least ships around some of the problems you run into with such bad-practice fat jars.

But actually my strong advice is, to not at all build such a library fat jar, especially not without relocation, but instead publish it to some Maven or Ivy repository and let the consumers build tool resolve the dependencies. Otherwise you get into various problems, especially if the consuming project uses the same dependencies but in different versions and so on.

I did try with runtimeClasspath but still getting NoClassDefFoundError. Anythign else that i might be missing ?

adding shadowjar plugin and running ./gradlew shadowJar task worked . Thanks a lot!

I did try with runtimeClasspath but still getting NoClassDefFoundError. Anythign else that i might be missing ?

This does not make much difference in your case as you neither have compileOnly dependencies, nor runtimeOnly dependencies. At least not directly, maybe transitively though.

But still with that you only package your dependencies, not your own code, which would come from sourceSets.main.output iirc.