# Converting Maven plugin to Gradle plugin

**URL:** <https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863>\
**Category:** Plugin Portal\
**Created:** [April 28, 2020, 7:09am UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863 "2020-04-28T07:09:44Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![marceloverdijk](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/marceloverdijk/32/4963_2.png) [@marceloverdijk](https://discuss.gradle.org/u/marceloverdijk)\
**Post date:** [April 28, 2020, 7:09am UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/1 "2020-04-28T07:09:44Z")

</div>

Hi,

I’m converting a Maven plugin to Gradle where the Maven plugin is doing:

```
    for (Object a : mavenProject.getArtifacts()) {
        Artifact artifact = (Artifact) a;
        File file = artifact.getFile();
        // do something with the file
    }

```

What is the equivalent to get these dependency file references in a Gradle task?

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [April 28, 2020, 7:45pm UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/3 "2020-04-28T19:45:52Z")

</div>

I believe that by default the artifacts (eg jars) are added to the “archives” [Configuration](https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.Configuration.html).

So you could do something like

```gradle
// closure will be executed live (as archives are added) 
configurations.archives.all { File archive -> ... } 

```

Or

```gradle
 // need to be careful with this closure, it might execute before the archives are added
configurations.archives.each { File archive -> ... } 

```

---

<div class="post-metadata">

**Author:** ![marceloverdijk](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/marceloverdijk/32/4963_2.png) [@marceloverdijk](https://discuss.gradle.org/u/marceloverdijk)\
**Post date:** [April 29, 2020, 7:09am UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/4 "2020-04-29T07:09:17Z")

</div>

I’m now using this:

> <https://github.com/smallrye/smallrye-graphql/blob/master/gradle-plugin/src/main/java/io/smallrye/graphql/gradle/tasks/GenerateSchemaTask.java#L143-L158>

Don’t know if it is the optimal implementation, but it works.

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [April 29, 2020, 7:46am UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/5 "2020-04-29T07:46:32Z")

</div>

Your task now has a dependency on the artifacts (or maybe the configurations) but I can’t see that dependency being expressed.

See [Task.dependsOn(Object …)](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html#org.gradle.api.Task:dependsOn(java.lang.Object%5B%5D)) and the [supported object types](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html#org.gradle.api.Task.dependencies). I’m guessing you’ll use a [Provider](https://docs.gradle.org/current/javadoc/org/gradle/api/provider/Provider.html) to delay the execution until after the configuration phase

---

<div class="post-metadata">

**Author:** ![marceloverdijk](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/marceloverdijk/32/4963_2.png) [@marceloverdijk](https://discuss.gradle.org/u/marceloverdijk)\
**Post date:** [April 29, 2020, 4:32pm UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/6 "2020-04-29T16:32:32Z")

</div>

The code I posted earlier does not what I want after all.

Basically I want to have a custom taks which could loop over all Artifacts in the Configurations.  
I need the actual File of the artifact as I need to index the file contents.

I already found out that e.g. the “implementation” configuration is not resolvabe.

Now based on the previous code we want to offer that users using the custom task can even define which configurations should be used to index it’s artifacts.

So if someone has:

```
dependencies {
    implementation 'io.smallrye:smallrye-graphql-servlet:1.0.2-SNAPSHOT'
    implementation 'com.github.javafaker:javafaker:1.0.2'
    runtimeOnly 'org.microprofile-ext.openapi-ext:openapi-ui:1.1.4'
    providedCompile 'org.eclipse.microprofile:microprofile:3.3'
    compileOnly 'org.projectlombok:lombok:1.18.12'
    annotationProcessor 'org.projectlombok:lombok:1.18.12'
}

```

then in my task I want to be configurable to only index jars from implementation configuration.

But as the implementation configuration is not resolvable this won’t work.

In the Maven plugin this is quite straightforward like:

```
        for (Object a : mavenProject.getArtifacts()) {
            Artifact artifact = (Artifact) a;
            if (includeDependenciesScopes.contains(artifact.getScope())
                    && includeDependenciesTypes.contains(artifact.getType())) {
                getLog().debug("Indexing file " + artifact.getFile());
                try {
                    Result result = JarIndexer.createJarIndex(artifact.getFile(), new Indexer(), false, false, false);
                    indexes.add(result.getIndex());
                } catch (Exception e) {
                    getLog().error("Can't compute index of " + artifact.getFile().getAbsolutePath() + ", skipping", e);
                }
            }
        }

```

I’m a bit stuck how one should do something similar in a Gradle custom task.

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [April 29, 2020, 5:39pm UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/7 "2020-04-29T17:39:01Z")

</div>

So you want the dependency jars? Not the artifacts produced by the project? I think you’d do something like:

```gradle
   @InputFiles
   public FileCollection getImplementationConfiguration() {
      return getProject().getConfigurations().getByName("implementation");
   }

   @TaskAction
   public void doIt() {
      Set<File> files = getImplementationConfiguration().getFiles();
      for (File file : files) {...}
   }

```

---

<div class="post-metadata">

**Author:** ![marceloverdijk](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/marceloverdijk/32/4963_2.png) [@marceloverdijk](https://discuss.gradle.org/u/marceloverdijk)\
**Post date:** [April 29, 2020, 5:49pm UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/8 "2020-04-29T17:49:35Z")

</div>

Yes, I want the dependency jars. And thanks for your patience 🙂

E.g. when I do the `getFiles()` like:

```
        Set<Configuration> configurations = getProject().getConfigurations();
        for (Configuration configuration : configurations) {
            if (includeDependenciesConfigurations.contains(configuration.getName())) {
                Set<File> files = configuration.getFiles();
                .. do other stuff
            }
        } 

```

then it gives me:

```
Caused by: java.lang.IllegalStateException: Resolving dependency configuration 'implementation' is not allowed as it is defined as 'canBeResolved=false'.
Instead, a resolvable ('canBeResolved=true') dependency configuration that extends 'implementation' should be resolved.

```

So I can’t seem to be able to get the files for the `implementation` configuration.

Btw besides the `File` object I also need the extension of the dependency.

Thanks for your help so far,  
Marcel

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [April 29, 2020, 10:29pm UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/9 "2020-04-29T22:29:32Z")

</div>

Hmm, I’ve seen this “canBeResolved=false” before and never took the time to understand why.

I wonder if you can do

```gradle
ConfigurationContainer cc = project.getConfigurations();
Configuration resolvable = cc.detachedConfiguration();
Configuration impl = cc.getByName("implementation");
resolvable.extendsFrom(impl);
Set<File> files = resolvable.getFiles();

```

Or perhaps

```gradle
Configuration resolvable = impl.copyRecursive();
Set<File> files = resolvable.getFiles();

```

---

<div class="post-metadata">

**Author:** ![marceloverdijk](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/marceloverdijk/32/4963_2.png) [@marceloverdijk](https://discuss.gradle.org/u/marceloverdijk)\
**Post date:** [April 30, 2020, 7:04am UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/10 "2020-04-30T07:04:06Z")

</div>

I tried.

The first option does not contain any files unfortunately…  
The second option gives `Resolving dependency configuration 'implementationCopy' is not allowed as it is defined as 'canBeResolved=false'.`

But I think you put me in the right direction with copying the configuration.

I now have this:

```
        ConfigurationContainer configurations = getProject().getConfigurations();

        for (String s : includeDependenciesConfigurations) {

            Configuration configuration = configurations.getByName(s);

            Configuration copiedConfiguration = configuration.copyRecursive();
            copiedConfiguration.setCanBeResolved(true); // THIS IS IMPORTANT; AS IT IS A COPIED CONFIG I GUESS IT IS OK TO DO.

            ResolvedConfiguration resolvedConfiguration = copiedConfiguration.getResolvedConfiguration();

            Set<ResolvedArtifact> artifacts = resolvedConfiguration.getResolvedArtifacts();
            for (ResolvedArtifact artifact : artifacts) {
                getLogger().lifecycle("INCLUDED CONFIG = " + s +
                        "\n INCLUDED ARTIFACT = " + artifact.getName() +
                        "\n INCLUDED CLASSIFIER = " + artifact.getClassifier() +
                        "\n INCLUDED EXTENSION = " + artifact.getExtension() +
                        "\n INCLUDED TYPE = " + artifact.getType() +
                        "\n INCLUDED FILE = " + artifact.getFile().getPath());
            }
        }

```

So I think I’m almost there.

The artifacts printed also include transitive dependencies.  
I wonder if it would be possible to include only the top dependencies defined directly in the configuration.

So e.g.

```
dependencies {
    implementation 'com.github.javafaker:javafaker:1.0.2' // just a random dep
}

```

would only include this artifact, but not the transitive dependency artifacts.

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [April 30, 2020, 7:14am UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/11 "2020-04-30T07:14:00Z")

</div>

> I think you put me in the right direction

Glad to hear

> I wonder if it would be possible to include only the top dependencies defined directly in the configuration.

You’re in luck! Just do `impl.copy()` instead of `impl.copyRecursive()`

---

<div class="post-metadata">

**Author:** ![marceloverdijk](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/marceloverdijk/32/4963_2.png) [@marceloverdijk](https://discuss.gradle.org/u/marceloverdijk)\
**Post date:** [April 30, 2020, 7:28am UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/12 "2020-04-30T07:28:42Z")

</div>

Thanks, I will give this a try this evening but I think that will do indeed!

Thanks for your help and I will let you know later if it worked.

---

<div class="post-metadata">

**Author:** ![marceloverdijk](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/marceloverdijk/32/4963_2.png) [@marceloverdijk](https://discuss.gradle.org/u/marceloverdijk)\
**Post date:** [April 30, 2020, 3:13pm UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/13 "2020-04-30T15:13:43Z")

</div>

`configuration.copyRecursive()` vs `configuration.copy()` doesn’t seem to matter.

From the apidocs I see for `copyRecursive`:

> Creates a copy of this configuration that contains the dependencies directly in this configuration and those derived from superconfigurations.

and for `copy()`:

> Creates a copy of this configuration that only contains the dependencies directly in this configuration (without contributions from superconfigurations).

I don’t think that is related to transitive dependencies, only derived from other configurations?

---

<div class="post-metadata">

**Author:** ![marceloverdijk](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/marceloverdijk/32/4963_2.png) [@marceloverdijk](https://discuss.gradle.org/u/marceloverdijk)\
**Post date:** [April 30, 2020, 4:46pm UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/14 "2020-04-30T16:46:49Z")

</div>

It can be solved with:

```
copiedConfiguration.setTransitive(true|false);

```

So in my case:

```
Configuration copiedConfiguration = configuration.copyRecursive();
copiedConfiguration.setCanBeResolved(true);
copiedConfiguration.setTransitive(includeDependenciesTransitive);
ResolvedConfiguration resolvedConfiguration = copiedConfiguration.getResolvedConfiguration();

```

The resolved configuration in this case contain the transitive dependencies or not depending on the flag.

This covers it 🙂

Thanks for your help Lance, much appreciated.

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [April 30, 2020, 7:49pm UTC](https://discuss.gradle.org/t/converting-maven-plugin-to-gradle-plugin/35863/15 "2020-04-30T19:49:13Z")

</div>

For a bit of further reading you might also be interested in `Configuration. resolvedConfiguration.firstLevelModuleDependencies` which I make usage of here

> <https://github.com/uklance/gradle-java-monkey-patch/blob/master/java-monkey-patch/src/main/groovy/com/lazan/JavaMonkeyPatchPlugin.groovy#L55-L70>
