Manifest with Classpath in Jar Task for Subprojects

Is it possible to define a jar task for a subset of subprojects that creates a manifest file that has the complete classpath of the jar in it (projects and 3rd party libs)?

I tried the following configure target, but that didn’t work:

configure(subprojects.findAll {it.name.endsWith('Service') || it.name.endsWith('Common') || it.name.endsWith('Client')}) {
    sourceSets {
        main {
            java {
                srcDir 'src'
            }
        }
    }
          jar {
      destinationDir = file('../../../../_temp/core/modules')
      archiveName = baseName + '.' + extension
      metaInf {
        from 'ejbModule/META-INF/' exclude 'MANIFEST.MF'
      }
              def manifestClasspath = configurations.compile.collect { it.getName() }.join(',')
       manifest {
            attributes("Manifest-Version"
     : "1.0",
                "Created-By"
           : vendor,
                "Specification-Title"
  : appName,
                "Specification-Version"
: version,
                "Specification-Vendor"
 : vendor,
                "Implementation-Title"
 : appName,
                "Implementation-Version" : version,
                "Implementation-Vendor"
: vendor,
                "Main-Class"
           : "com.dcx.epep.Start",
                "Class-Path"
           : manifestClasspath
            )
      }
  }
}

Does anyone have any suggestions what is wrong?

Can you be more specific than “that didn’t work”? Some problems I can spot:

  • Entries of the ‘Class-Path’ attribute need to be separated by spaces

  • You need to use ‘configurations.runtime’ rather than ‘configurations.compile’

  • Unless you copy all Jars into the same directory, you need to use file paths instead of file names

Sorry that I wasn’t specific enough.

My problem is, that with configurations.runtime the dependent projects aren’t written into the manifest classpath.

Of course I can move the jar target to all my sub projects but unfortunately I have a bunch of them and I’d like to keep my build script simple.

You need to defer computing the class path until all build scripts have been evaluated. Try to wrap the class path related code into a ‘doFirst { … }’.

Thanks for your hint. The following implementation did the trick

jar.doFirst{
      manifest {
            attributes("Manifest-Version"
     : "1.0",
                "Created-By"
           : vendor,
                "Specification-Title"
  : appName,
                "Specification-Version"
: version,
                "Specification-Vendor"
 : vendor,
                "Implementation-Title"
 : appName,
                "Implementation-Version" : version,
                "Implementation-Vendor"
: vendor,
                "Main-Class"
           : "com.dcx.epep.Start",
                "Class-Path"
           : configurations.compile.collect { it.getName() }.join(' ')
             )
      }
            }

Using ‘“Class-Path”: configurations.compile.collect { it.getName() }.join(’ ‘)’ in my build script results in such breaked lines:

Class-Path: async-http-client-1.7.21.jar commons-codec-1.8.jar commons

-compress-1.3.jar hsqldb-2.2.6.jar jcommon-1.0.17.jar jfreechart-1.0.

14.jar kxml2-2.3.0.jar sqltool-2.2.8.jar xstream-1.4.2.jar cloning-1.

9.0.jar jsoup-1.7.2.jar japura-1.18.3.jar lib-utils-0.0.1.jar xml-api

s-1.3.04.jar itext-2.1.5.jar xmlpull-1.1.3.1.jar xpp3_min-1.1.4c.jar

objenesis-1.2.jar guava-15.0.jar commons-lang3-3.2.1.jar bcmail-jdk14

-138.jar bcprov-jdk14-138.jar netty-3.6.6.Final.jar slf4j-api-1.7.5.j

ar

What could be the problem?

I’m using Gradle 1.11

Sorry, I’ve just discovered that’s a correct behaviour

From

http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Notes_on_Manifest_and_Signature_Files

No line may be longer than 72 bytes (not characters), in its UTF8-encoded form. If a value would make the initial line longer than this, it should be continued on extra lines (each starting with a single SPACE).