# Access generatePomFileFor\*Publication from plugin code

**URL:** <https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426>\
**Category:** Help/Discuss\
**Created:** [January 11, 2018, 9:20pm UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426 "2018-01-11T21:20:31Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 11, 2018, 9:20pm UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/1 "2018-01-11T21:20:31Z")

</div>

I am writing a plugin that ultimately needs access to the generated POM file for a `MavenPublication`. As far as I know, that information is currently only available via `GenerateMavenPom#destination`. However I have tried many ways to be able to access the various `generatePomFileFor*Publication` with no success. I have tried:

1. project.getTasks().findByName( name ) - and getByName
2. the same as above, but done in an `project.afterEvaluation` block
3. via ModelMap as a Rule(Source)

None of them worked. Any pointers?

---

<div class="post-metadata">

**Author:** ![luke\_daley](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/luke_daley/32/9890_2.png) [@luke\_daley](https://discuss.gradle.org/u/luke_daley)\
**Post date:** [January 12, 2018, 12:10am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/2 "2018-01-12T00:10:29Z")

</div>

`project.getTasks().findByName(name)` should work, it’s likely just a matter of timing.

What I think you really want is access to:

> <https://github.com/gradle/gradle/blob/b91219f539b2ff4755f7bab76d7f0e1d2185e5e4/subprojects/maven/src/main/java/org/gradle/api/publish/maven/internal/publication/DefaultMavenPublication.java#L106>

You could try reflectively hacking access to that to see if that would work for you. If so, we could at least promote that to the internal interface as an interim step so you wouldn’t have to hack at private fields.

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 12, 2018, 12:17am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/3 "2018-01-12T00:17:07Z")

</div>

Thanks @luke_daley. I had seen that one but wanted to stay away from reflection if possible. But that seems like the best/only option. The Task lookup is very perplexing.

Another reason I did not really think to use this is I had no idea why it is a `FileCollection`. Any insight into that? As far as I understand, the `MavenPublication` allows just a single POM be associated with it, so why not just a single `File`?

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 12, 2018, 12:31am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/4 "2018-01-12T00:31:51Z")

</div>

Maybe just to be `Buildable`?

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 12, 2018, 12:53am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/5 "2018-01-12T00:53:02Z")

</div>

Also, access the field just returns `null` ☹

```gradle

	private static final String PUBLICATION_IMPL_CLASS_NAME = "org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication";
	private static final Class PUBLICATION_IMPL_CLASS;
	private static final String POM_FILE_COLLECTION_FIELD_NAME = "pomFile";
	private static final Field POM_FILE_COLLECTION_FIELD;

	static {
		try {
			PUBLICATION_IMPL_CLASS = Utils.class.getClassLoader().loadClass( PUBLICATION_IMPL_CLASS_NAME );
		}
		catch (ClassNotFoundException e) {
			throw new GradleException( "Could not locate DefaultMavenPublication class : " + PUBLICATION_IMPL_CLASS_NAME, e );
		}

		try {
			POM_FILE_COLLECTION_FIELD = PUBLICATION_IMPL_CLASS.getDeclaredField( POM_FILE_COLLECTION_FIELD_NAME );
			POM_FILE_COLLECTION_FIELD.setAccessible( true );
		}
		catch (NoSuchFieldException e) {
			throw new GradleException( "Could not locate DefaultMavenPublication#pomFile field", e );
		}
	}

	public static FileCollection getPomFileCollection(MavenPublication mavenPublication) {
		try {
			return (FileCollection) POM_FILE_COLLECTION_FIELD.get( mavenPublication );
		}
		catch (IllegalAccessException e) {
			throw new GradleException( "Could not access DefaultMavenPublication#pomFile field [" + mavenPublication + "]", e );
		}
	}

```

Calls to this `#getPomFileCollection` method return `null`

---

<div class="post-metadata">

**Author:** ![luke\_daley](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/luke_daley/32/9890_2.png) [@luke\_daley](https://discuss.gradle.org/u/luke_daley)\
**Post date:** [January 12, 2018, 2:40am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/6 "2018-01-12T02:40:29Z")

</div>

> [@Steve\_Ebersole](#):
>
> Another reason I did not really think to use this is I had no idea why it is a FileCollection. Any insight into that? As far as I understand, the MavenPublication allows just a single POM be associated with it, so why not just a single File?

Yes, just so that it can encode the task dependency.

---

<div class="post-metadata">

**Author:** ![luke\_daley](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/luke_daley/32/9890_2.png) [@luke\_daley](https://discuss.gradle.org/u/luke_daley)\
**Post date:** [January 12, 2018, 2:40am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/7 "2018-01-12T02:40:54Z")

</div>

> [@Steve\_Ebersole](#):
>
> Also, access the field just returns null ☹

Timing is critical. When are you trying to access? When do you need to have it?

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 12, 2018, 12:02pm UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/8 "2018-01-12T12:02:56Z")

</div>

The background is that I am working on a solution to sign all of the artifacts associated with a MavenDeployment[1] in preparation for uploading to OSSRH[2].

I have tried numerous timings. I’ve tried applying my plugin at different points in the script. I’ve tried delaying this specific work until `afterEvaluation`.

The basic idea I was going for was to add a `MavenArtifact` to the publictaion for each artifact (including the pom file) in the publication. So I need to be able to access all of the artifacts at a time I can still add to the collection of artifacts. Maybe you could suggest a better “timing”?

[1] [https://github.com/gradle/gradle/issues/1165](https://github.com/gradle/gradle/issues/1165)  
[2] I wanted to use Bintray but then noticed the 10G storage limit of the OSS plan which Hibernate would hit in no time.

---

<div class="post-metadata">

**Author:** ![luke\_daley](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/luke_daley/32/9890_2.png) [@luke\_daley](https://discuss.gradle.org/u/luke_daley)\
**Post date:** [January 15, 2018, 11:33pm UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/9 "2018-01-15T23:33:13Z")

</div>

afterEvaluate is not going to be late enough. The pomFile property is set as the tasks are created, which is later. The only practical option is to reference this property (i.e. lazily) and not try to copy it.

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 16, 2018, 1:47am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/10 "2018-01-16T01:47:09Z")

</div>

The feasibility of that depends on how eagerly Gradle tries to access `org.gradle.api.publish.maven.MavenArtifact#getFile` for the artifacts I am adding to the `MavenPublication`.

Or how lately I can add my `MavenArtifact` objects to the publication.

Any ideas about these?

---

<div class="post-metadata">

**Author:** ![luke\_daley](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/luke_daley/32/9890_2.png) [@luke\_daley](https://discuss.gradle.org/u/luke_daley)\
**Post date:** [January 16, 2018, 2:20am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/11 "2018-01-16T02:20:48Z")

</div>

I see what you’re saying. That’s not going to work as you can’t practically have a lazy `File`.

Next, I’d try doing your own impl of `MavenArtifact` with a `getFile()` that is lazy. You’d have to add this directly via `publication.artifacts.add()` instead of the `publication.artifact {}` factory.

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 16, 2018, 6:57pm UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/12 "2018-01-16T18:57:25Z")

</div>

> [@luke\_daley](#):
>
> Next, I’d try doing your own impl of MavenArtifact with a getFile() that is lazy. You’d have to add this directly via publication.artifacts.add() instead of the publication.artifact {} factory.

`MavenArtifact` is unfortunately a `org.gradle.api.Buildable` - I don’t really know how to implement `Buildable#getBuildDependencies` here since the pomFile is part of its dependencies

---

<div class="post-metadata">

**Author:** ![luke\_daley](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/luke_daley/32/9890_2.png) [@luke\_daley](https://discuss.gradle.org/u/luke_daley)\
**Post date:** [January 16, 2018, 11:19pm UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/13 "2018-01-16T23:19:29Z")

</div>

You can just return a `DefaultTaskDependency`, populated with a `Callable` that returns `DefaultMavenPublication.pomFile`.

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 17, 2018, 1:51am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/14 "2018-01-17T01:51:12Z")

</div>

I’ve already been down this path. `DefaultTaskDependency` is unfortunately internal and implementing the `TaskDependency` contract is beyond my understanding - I’ve looked through the code in `DefaultTaskDependency` and it sadly makes zero sense to me.

---

<div class="post-metadata">

**Author:** ![luke\_daley](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/luke_daley/32/9890_2.png) [@luke\_daley](https://discuss.gradle.org/u/luke_daley)\
**Post date:** [January 17, 2018, 2:07am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/15 "2018-01-17T02:07:08Z")

</div>

You aren’t going to be able to implement what you want without using some internals.

You could try just delegating to `DefaultMavenPublication.pomFile.getTaskDependency()` (i.e. that thing is a `Buildable`) when it is not null.

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 17, 2018, 2:41pm UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/16 "2018-01-17T14:41:52Z")

</div>

> [@luke\_daley](#):
>
> You aren’t going to be able to implement what you want without using some internals.

I generally do not have a problem with that. However, whenever I do rely on Gradle internal classes I end up getting runtime errors during the build saying that Gradle internal dependencies cannot be found

> [@luke\_daley](#):
>
> You could try just delegating to DefaultMavenPublication.pomFile.getTaskDependency() (i.e. that thing is a Buildable) when it is not null.

Well that comes back to the original thing I am asking… when does `MavenPublication.pomFile` become non-null so that I can do this, and is that point in time too late to still add a `MavenArtifact` to that `MavenPublication`?

So the crux here seems to be: When is the latest I can add the `MavenArtifact` to that `MavenPublication`? This would facilitate delaying the creation/addition of the `MavenArtifact` until the `#pomFile` information is ready.

I guess the easiest route (really the only workable route atm) is to plan on saving the signature files into a dedicated “build dir”. The trouble here is ultimately coming from the fact that I was trying to have a “nice” feature of saving the signature files to the same dir as the artifact file it is verifying. For that to work for the POM I have to know its output directory which is why I need access to the pomFile. If I just plan on saving all signature files to the one dir then its not relevant where the POM is generated.

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 18, 2018, 12:22am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/17 "2018-01-18T00:22:12Z")

</div>

FWIW I went ahead and forced naming a “signature directory” and this code is now working.

The non-working code was trying to access `MavenPublication#pomFile` in order to determine a base name for the POM signature file; roughly it was trying to name it `mavenPublication.getPomFile().getSingleFile().getName + ".asc"`. However, this is actually not correct since the build can name this generated POM file anything it wants locally - so this is not necessarily a “hack” change. I am happy with this.

Thanks for your help (as always) Luke.

---

<div class="post-metadata">

**Author:** ![luke\_daley](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/luke_daley/32/9890_2.png) [@luke\_daley](https://discuss.gradle.org/u/luke_daley)\
**Post date:** [January 18, 2018, 12:40am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/18 "2018-01-18T00:40:25Z")

</div>

Success!

Great stuff Steve. I am sure that many will be eagerly awaiting your work.

---

<div class="post-metadata">

**Author:** ![Steve\_Ebersole](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/steve_ebersole/32/9763_2.png) [@Steve\_Ebersole](https://discuss.gradle.org/u/Steve_Ebersole)\
**Post date:** [January 18, 2018, 3:43am UTC](https://discuss.gradle.org/t/access-generatepomfilefor-publication-from-plugin-code/25426/19 "2018-01-18T03:43:08Z")

</div>

I may end up using Bintray after all, in which case all of this work was not necessary for me 😄

But in the meantime, here is the working code: [https://github.com/sebersole/gradle-clean-room2/tree/master/buildSrc](https://github.com/sebersole/gradle-clean-room2/tree/master/buildSrc)
