File name mapping in assemble ear

plugins

(Daniel G) #1

Hello,

i m in the process of migrating a rather large ant based project to gradle.
We have a rather specific requirement on how dependencies have to be packaged in a ear file. Because all references (in the application server) are described via MANIFEST.MF Class-Path s changing the version number of one module would need the rebuild of significant parts of the application we are packaging all dependencies without their version number.

With ant/ivy we used a specific pattern in the retrieve task, to copy the jars in a folder we later packaged.
During evaluation of maven it was even easier, just setting the ear-plugin property fileNameMapping to “no-version”.

But i’d like to know how this can be done in gradle. Even though the dependency management is very much like ivy, i can’t seem to find a way to specify a file name pattern for the packaging.

I know that i may get all the resolved artifacts via configurations.earlib.resolvedConfiguration.resolvedArtifacts and copy them somewhere on my own, but i quiet sure there is another way to integrate it into the greadle-ear-plugin lifecycle, isn’t it?

kind regards
Daniel


(Daniel G) #2

Well this is realy disapointing, that ivy s native ability is unsupported in gradle (altough i beliefed, the origins of gradles dependency management is ivy?).

I found a solution that works for a headless build but is in not in any IDE (neither Intellij, nor Eclipse).
Is there even any single IDE that has a reasonable JEE support for gradle (idea plugin is totaly out, eclipse wtp is broken with the following solution, Intellijs native support does not work and eclipse buildship doesnt even know about faceted project setups)?

At first you needed to make sure any project (if you are running a multi project build) you want to include, does the packaging without version numbers (these files are not part of the following rename phase - for whatever reason i dont know):

jar { version = null }

then you can utilize the ear plugins copy task roots to rename every copied file according to their desired name. I used to do this with the help of the resolved dependencies as i didnt wanted to rely on a regex that may be broken for certain name/version combinations - if anyone has a better idea please let me know:

ear {
    version = null // supress Version numbers in the produced artifact

    rename { String fileName ->

        // looking for possible candidates in all configurations
        for(def conf : configurations){
            // checking all resolved artifacts of that configuration
            for(def artifact : conf.resolvedConfiguration.resolvedArtifacts){
                // the artifact already points to a fileName
                if(artifact.file.name.equals(fileName)){
                    return artifact.name + (artifact.classifier == null? ".${artifact.extension}" : "-${artifact.classifier}.${artifact.extension}");
                } 
            }
        }
    }
}

the very disappointing thing is, that this solution is far from perfect:

  1. it is unsupported by IDEs. Neither Intellij s gradle integration nor the gradle idea plugin respects these settings.
  2. there are still situations were this setup will produce wrong results as it tries to rename all files - including EAR configurations, e.g. from the META-INF directory (just think of a file that has the same name as one of the packaged artifacts and you didnt want to rename that one. This is a rare condition but not impossible)
  3. you will check all configurations, even if not needed (when the copy task copies a file from META-INF directory), e.g. you added the java plugin in your multi module project, but you just dont care about the testCompile configuration

Well maybe my solution helps someone.
For me the IDE integration is actually a showstopper (not only in this aspect) that makes me wonder if maven may be the better choice for the moment… :frowning: