Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GRADLE_METADATA feature preview: task generateMetadataFileForMyIvyPublication failed with NullPointerException #5450

Closed
ameliedagenais opened this issue May 17, 2018 · 6 comments
Assignees
Labels
Milestone

Comments

@ameliedagenais
Copy link

ameliedagenais commented May 17, 2018

Expected Behavior

module.json file should be generated successfully

Current Behavior

Task generateMetadataFileForMyIvyPublication fails with this error:

* What went wrong:
Execution failed for task ':generateMetadataFileForMyIvyPublication'.
> java.lang.NullPointerException (no error message)

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':generateMetadataFileForMyIvyPublication'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:110)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:77)
        at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ResolveBuildCacheKeyExecuter.execute(ResolveBuildCacheKeyExecuter.java:66)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101)
        at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.run(EventFiringTaskExecuter.java:51)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:97)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:46)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$ExecuteTaskAction.execute(DefaultTaskExecutionGraph.java:262)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$ExecuteTaskAction.execute(DefaultTaskExecutionGraph.java:246)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:136)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:130)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.execute(DefaultTaskPlanExecutor.java:201)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.executeWithTask(DefaultTaskPlanExecutor.java:192)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:130)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: java.lang.NullPointerException
        at org.gradle.api.publish.internal.ModuleMetadataFileGenerator.writeVariants(ModuleMetadataFileGenerator.java:189)
        at org.gradle.api.publish.internal.ModuleMetadataFileGenerator.writeComponentWithVariants(ModuleMetadataFileGenerator.java:129)
        at org.gradle.api.publish.internal.ModuleMetadataFileGenerator.generateTo(ModuleMetadataFileGenerator.java:98)
        at org.gradle.api.publish.tasks.GenerateModuleMetadata.run(GenerateModuleMetadata.java:149)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:46)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:794)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:761)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:131)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:97)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:120)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:99)
        ... 31 more

And the module.json ends up being half-generated:

{
  "formatVersion": "0.4",
  "component": {
    "group": "myGroup",
    "module": "myModule",
    "version": "0.1.0-SNAPSHOT",
    "attributes": {
      "org.gradle.status": "integration"
    }
  },
  "createdBy": {
    "gradle": {
      "version": "4.8-rc-1",
      "buildId": "ansgkrdgqjcehamvpeespobzsi"
    }
  }

Context

I've been interested to try the GRADLE_METADATA feature for a while, because I'm very interested to use the module.json metadata file. I tried a few things, including running the samples from the https://github.com/gradle/dependency-management-samples project, but just couldn't figure out how to get the module metadata file generated for my project. But then I saw the generateMetadataFileForPublication task made available as of 4.8-rc-1 so I decided to give it a try. It worked nicely on the sample projects, but just didn't work for my project.

Steps to Reproduce (for bugs)

My build.gradle is as simple as this, but references a custom plugin:

plugins {
    id 'mygroup:my-own-java-plugin' version '1.1.12'
}

The custom plugin in the backgrounds does a bunch of things. It defines source/publish repos, artifacts to publish, etc. It also applies a few other plugins such as java-library, ivy-publish, base, jacoco.

I can try to dig deeper to recreate a simpler build.gradle which reproduces the issue if needed, but it might take me while, so I'd only do it if it can be useful.

Your Environment

@marcphilipp
Copy link
Contributor

@gradle/dependency-management Can you please take a look?

@melix melix self-assigned this May 18, 2018
@melix
Copy link
Contributor

melix commented May 18, 2018

@ameliedagenais Thanks for the report, and glad to see someone giving the new metadata format a try. The error you see is definitely unexpected. I can see different possible causes:

  1. your plugin uses custom publications, using internal APIs, and something bad happens (seems unlikely, but I want to mention it)
  2. there's an ordering issue somewhere, and more importantly the code that is supposed to set the UsageContext isn't called (possible, but unlikely)
  3. there's no associated component to your publication, which would explain the NPE.

I'm leaning towards 3, because I can reproduce with the following build file:

apply plugin: 'java-library'
apply plugin: 'ivy-publish'

publishing {
   publications {
      main(IvyPublication) {
         // commenting will cause the NPE
         // from components.java
      }
   }
}

See https://scans.gradle.com/s/3gcahqhfqzd4i/failure?openFailures=WzBd&openStackTraces=WzEse31d#top=0

So while we should fix the NPE, it seems that you may have a configuration problem. Or not, because I'm not sure what publication corresponds to generateMetadataFileForPublication (there must be an implicit one, I need to check this out).

melix added a commit that referenced this issue May 18, 2018
If the task to generate the module metadata file was explicitly called
and that the publication didn't define any component to publish (aka,
no call to `from components....`), then we would fail the generation
with an NPE.

This commit fixes the problem by adding a precondition before executing
the task, which warns the user that the task shouldn't be called if
there's no attached component, and disables the task.

Fixes #5450
@ameliedagenais
Copy link
Author

@melix Sorry for the confusion around the name of the task, I was trying to scrub out confidential information in the task name and just didn't replace it with anything which ended up being confusing. It would actually look more like generateMetadataFileForMyIvyPublication. Actually, I've been able to get a much simpler repro by digging through how our custom plugin works and hopefully that will help you investigate further. Here's what the build.gradle would look like:

plugins {
    id 'java-library'
    id 'ivy-publish'
}

publishing {
    publications {
        myIvy(IvyPublication) {
            artifact(project.tasks.jar) {
                classifier 'common.rel'
            }
        }
    }
}

So you're right, there's no associated component to this publication, however, we define an artifact and the generateDescriptorFileForMyIvyPublication task works just fine. Therefore I would expect the generateMetadataFileForMyIvyPubication to also work fine

@ameliedagenais ameliedagenais changed the title GRADLE_METADATA feature preview: task generateMetadataFileForPublication failed with NullPointerException GRADLE_METADATA feature preview: task generateMetadataFileForMyIvyPublication failed with NullPointerException May 18, 2018
@melix
Copy link
Contributor

melix commented May 18, 2018

however, we define an artifact and the generateDescriptorFileForMyIvyPublication task works just fine.

That's correct, but there's a good reason for that. Ivy and Maven metadata are not "variant aware", or, at a simpler level, component aware. We don't know what you are publishing: is it a Java library? Is it test fixtures? Is it a variant with an -all jar? Without the proper model we can't tell. Gradle metadata models components, so if you don't have a component, we don't know what to do.

Eventually, we will have a public API for defining your own components, but in the meantime you are limited to the components Gradle knows about, which are, for now, Java libraries, platforms and native components.

The PR I have submitted will not give you a Gradle metadata file, but at least, it will not fail with a NPE.

marcphilipp pushed a commit that referenced this issue May 19, 2018
If the task to generate the module metadata file was explicitly called
and that the publication didn't define any component to publish (aka,
no call to `from components....`), then we would fail the generation
with an NPE.

This commit fixes the problem by adding a precondition before executing
the task, which warns the user that the task shouldn't be called if
there's no attached component, and disables the task.

Fixes #5450
@marcphilipp
Copy link
Contributor

Fixed by #5459 for 4.8 RC2.

@ameliedagenais
Copy link
Author

Thanks for fixing the NPE and providing a better error message. The explanation makes sense, I can fix my project to define components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants