Publishing EARs?

Working on adopting Gradle for our first ever real build tool, and I’m confused about publishing EARs. I’m new to Gradle so maybe I’m just not interpreting the documentation correctly.

I’m working on implementing Gradle for a J2EE web application. It consists of several JARs and a WAR that get packaged into an EAR. Building and publishing the JARs and WAR is working fine with maven-publish, but it looks like maven-publish doesn’t support publishing EARs yet. Since maven-publish doesn’t support publishing EARs, I think I need to use the “old way” outlined in Chapter 53 of the user guide.

I’ve configured the artifacts configuration and uploadArchives task to include the ear and upload to our Artifactory respectively. That works in that the EAR is uploaded to Artifactory, but the POM and associated meta-data is not uploaded like it is for the JARs and WAR with maven-publish. An ivy.xml is uploaded though I don’t know why. How do I get the POM and meta-data to upload/publish for the EAR? Do I need to somehow include them in the archives artifact?

I’m running Gradle 2.9 and publishing to Artifactory 4.2.2.

You can use the ‘maven-publish’ plugin to publish an EAR as well. You can publish any file really. The POM that gets uploaded won’t have dependency metadata in it though (although I’m not exactly sure what you’d expect that to be for an EAR).

publications {
    ear(MavenPublication) {
        artifact ear
    }
}

Thanks for the reply.

Honestly, I’m new to Gradle and never used Maven so I don’t have a complete understanding of what the POM is all for. I just noticed it was missing on the EAR upload and was concerned. Maybe it’s not an issue.

I added the code snippet you specified and now I’m getting an error. See below. How do I make the EAR be of type MavenArtifact?

[code]
A problem occurred configuring root project ‘MyProjectEAR’.

Exception thrown while executing model rule: PublishingPlugin.Rules#publishing
Cannot convert the provided notation to an object of type MavenArtifact: org.gradle.api.publish.maven.internal.publ
ication.DefaultMavenPublication_Decorated@51d6cc5e.
The following types/formats are supported:
- Instances of MavenArtifact.
- Instances of AbstractArchiveTask, for example jar.
- Instances of PublishArtifact
- Maps containing a ‘source’ entry, for example [source: ‘/path/to/file’, extension: ‘zip’].
- Anything that can be converted to a file, as per Project.file()[/code]

Try artifact tasks.ear instead.

I am having the same issue. I have tried building an EAR. It worked fine. when I publish, the EAR file is not being published to artifactory.

publishing {
println 'In build.gradle… publishing action’
publications {
println ‘In build.gradle… publishing.publication action’

    mavenJava(MavenPublication) {
        groupId 'com.rkanth.test.gradlebuild'
        artifactId 'myEAR'
        version '1.0.1'          
        from 'build/libs'
        //from components.ear // I get an error -- > Exception thrown while executing model rule: //PublishingPlugin.Rules#publishing  > Could not find property 'ear' on SoftwareComponentInternal set.
    }
}
repositories {
	    println 'In build.gradle... publishing.repositories action'
    maven {
        credentials {
          username "${artifactory_user}"
          password "${artifactory_api_key}"                
        }
        url "${artifactory_internalUrl}"
    }
}

You’ll want to do

mavenJava(MavenPublication) {
    groupId 'com.rkanth.test.gradlebuild'
    artifactId 'myEAR'
    version '1.0.1'          
    artifact ear
}

Thank you! that worked.

In the meantime i tried the below and it worked but I like your approach of not having to specify any specific file names.
mavenJava(MavenPublication) {
groupId 'com.rkanth.test.gradlebuild’
artifactId 'myEAR’
version '1.0.1’
artifact ("/build/libs/myEAR.ear") {
//classifier "ear"
extension “ear”
}
//from ‘build/libs’
//from components.ear
}

Additionally Could you please explain how artifact ear is interpreted ? And why didn’t components.ear work ?

The from() method here only accepts a SoftwareComponent. Unfortunately, only components.java and components.web exist.

The artifact() method however will accept a number of different arguments, one being a Task. This allows you to specify pretty much any arbitrary file as a publication artifact.

https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html

The following block will publish an EAR (tested with gradle 7.3.3, kotlin syntax):

publishing {
    publications {
        create<MavenPublication>(project.name) {
            artifact("$buildDir/libs/ear.ear")
        }
    }

    repositories {
        maven {
            name = "LocalMavenRepo"
            url = uri("../mvnrepo")
        }
    }
}

That’s a pretty bad idea.
Basically almost always when you configure inputs to something as plain path, you are doing something wrong.
If you for example try to run a publish from a clean build it will not work because there is no dependendency on the ear task as you just configured an arbitrary path.

Instead use the suggested way to configure the ear task as artifact and it will work properly.