Copy issue from subproject

Hi, I have a multi-project build (that creates an EAR file) and i’m having an issue when trying to build.

I have a tasks that creates an “uber” ejb jar file from subprojects that looks something like:

tasks.register<Jar>("all-ejbs") {
    archiveFileName = "all-ejbs.jar"

    metaInf {
        from(project(":subproject:ejbProject1").configurations.archives.get().allArtifacts.files.map { zipTree(it) }) {
            include("META-INF/**")
        }
    }
}

along with other things. Then in the dependencies block:

dependencies {
    deploy(tasks.getByName("all-ejbs").outputs.files)
}

When i run the ear task, i get the following error:
> Configuration with name 'archives' not found.

If i remove the deploy line and just run the all-ejbs task, it works.

Any ideas? Thanks.

You should definitely not reach into other projects like that and especially do not try to get artifacts out that way. That is highly fragile and unsafe even if you would get it to work.

Please have a look at Sharing outputs between projects on how to properly share outputs between projects of a multi-project build.

ok, gotcha (i think). so if i did something like:

val allEjbs by configurations.creating {
    isTransitive = false
}

then

dependencies {
    allEjbs(project(":subproject:ejbProject1"))
    allEjbs(project(":subproject:ejbProject2"))

    deploy(tasks.getByName("all-ejbs").outputs.files)
}

i’m not sure how to do something like:

tasks.register<Jar>("all-ejbs") {
    archiveFileName = "all-ejbs.jar"

    metaInf {
        allEjbs.allDependencies.withType<ProjectDependency>().forEach {
            when (it.name) {
                "ejbProject1" -> {
                    from(???) {
                        include("META-INF/**")
                    }
                }
                "ejbProject2" -> {
                    from(???) {
                        include("META-INF/*.xml")
                    }
                }
            }
        }
    }
}

what would i replace “???” with

I found i could do something like:

from(allEjbs.map {zipTree(it)}) {
    include("META-INF/**")
}

but i need to copy specific things from each project

No, don’t try to use allEjbs.allDependencies. Just use allEjbs.files to get the files you depended on. And you also have to make sure it is recognized as input of the task so that you get the necessary task dependencies.

And I also don’t think deploy(tasks.getByName("all-ejbs").outputs.files) is a good idea either. You probably instead want to do ear { lib { from(allEjbs) } } to get just get the ejbs as libs into your ear. Is there a particular reason why you want to build a fat jar, instead of just using the jars as they are and how it is intended? Or even better just throw all that away and just declare the dependencies for the earlib configuration which then makes them packaged properly?

Unfortunately, it is a requirement that i can’t get around. This is a migration of an old (large) build that used ant and shell scripts to build. At some point 15-20 years ago, someone thought it was a good idea and a lot of code (like jndi lookups) seem to depend on this structure. :frowning_face: