Paulo Marcio
Paulo Marcio

Reputation: 245

Gradle dependency between subprojects

I am trying to figure out the proper way to declare a project dependency in gradle, i have this two subprojects:

A java app

apply plugin: 'java'

sourceSets {main {java {srcDirs = ['./']}}}
dependencies{compile project(':p2')}

jar {manifest.attributes(
        'Class-Path': configurations.runtime.files.collect { it.name }.join(''),
        'Main-Class': 'Main'
    )
}

and a java library:

apply plugin: 'java-library'

sourceSets {main {java {srcDirs = ['./']}}
}

jar {
   manifest.attributes(
    'Class-Path': configurations.runtime.files.collect { it.name }.join(' ')
)
}

The root project is empty and the settings just include the subprojects.

The dependencies in the p1 project only tells that p2 must be built before p1, but what about configuring p2 as a lib for p1? Right now if a run p1 i got: Exception in thread "main" java.lang.NoClassDefFoundError: StaticClass

Gradle build is fine:

C:\...>gradle build
BUILD SUCCESSFUL in 1s
4 actionable tasks: 4 up-to-date

I have to copy and paste p2.jar to the p1.jar directory for it to run properly, how can i get gradle to do it for me?

Upvotes: 0

Views: 1593

Answers (2)

Louis Jacomet
Louis Jacomet

Reputation: 14500

Depending on your exact needs, you should have a look at the java-library-distribution plugin or the application plugin.

  • The first one will package a jar and its dependencies in an archive.
  • The second one will do the same and allow you to configure the main jar to be executable.

Upvotes: 1

user31601
user31601

Reputation: 2610

If you're trying to pack the classes from p2 into the p1 jar, try adding this to p1's build.gradle:

jar {
    from project(':p2:').sourceSets.main.output
}

This is a bit unusual, though. Normally, if you've set up a separate library project, you pack it in a separate jar and add it to the classpath of dependent projects, so it's reusable.

Setting the Class-Path on the jar's manifest won't work the way you've written it. The manifest attribute interprets each entry as a file path relative to the working dir of the JVM, but you're just giving it the name of each jar, and Gradle doesn't do any copying or moving of files when setting up configuration classpaths. It's generally not a good idea to rely on the manifest to set the classpath, as it will only work if your jars are arranged on the filesystem exactly as as the manifest expects it. If this is really what you want, then you need to set up an 'installation' directory containing all the required jars arranged as expected. The Gradle Application Plugin can probably help you to achieve this, or something equivalent, but I've never used it.

Upvotes: 1

Related Questions