recently we tried to rewrite a plugin of ours to make use of the Worker API, specifically to make use of the classloaderIsolation feature.
@TaskAction
public void executeTask() {
ConfigurableFileCollection classpath = getClasspath();
WorkerExecutor executor = getWorkerExecutor();
WorkQueue queue = executor.classLoaderIsolation(spec -> spec.getClasspath().from(classpath));
queue.submit(DbWorkAction.class, parameters -> {
// set db params
});
queue.await();
}
The task does interact with a database and this can be unavailable due to various reasons, so the WorkAction will obviously fail.
public void execute() {
try {
// do database stuff
} catch (Exception e) {
throw new GradleException("db interaction failed", e);
}
}
As we covered that in a test-kit case we experienced that (even though we could see the right stacktrace in the logs) the test was not successful due to the call to buildAndFail crashing before we could even evaluate the builds output.
when:
def gradleRunner = GradleRunner.create()
.forwardOutput()
.withProjectDir(dir)
.withEnvironment(env)
.withArguments(arguments)
.withPluginClasspath();
BuildResult result = gradleRunner.buildAndFail() // <-- it fails here!
then:
result.task(':updateDB').outcome == TaskOutcome.FAILED
result.output.contains("Connection to localhost:43432 refused")
The result of the test states:
// at first there are the PostgreSql jdbc driver stacks but then:
* Exception is:
java.lang.NoClassDefFoundError: org/postgresql/util/ServerErrorMessage
at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3166)
at java.base/java.lang.Class.getDeclaredMethods(Class.java:2309)
at org.gradle.internal.serialize.ExceptionPlaceholder.findCandidateGetCausesMethod(ExceptionPlaceholder.java:296)
at org.gradle.internal.serialize.ExceptionPlaceholder.tryExtractMultiCauses(ExceptionPlaceholder.java:315)
at org.gradle.internal.serialize.ExceptionPlaceholder.extractCauses(ExceptionPlaceholder.java:279)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:104)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.TopLevelExceptionPlaceholder.<init>(TopLevelExceptionPlaceholder.java:28)
at org.gradle.internal.serialize.ExceptionReplacingObjectOutputStream.doReplaceObject(ExceptionReplacingObjectOutputStream.java:67)
at org.gradle.internal.serialize.ExceptionReplacingObjectOutputStream$1.transform(ExceptionReplacingObjectOutputStream.java:31)
at org.gradle.internal.serialize.ExceptionReplacingObjectOutputStream.replaceObject(ExceptionReplacingObjectOutputStream.java:62)
at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1135)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:345)
at org.gradle.tooling.internal.provider.serialization.PayloadSerializer.serialize(PayloadSerializer.java:53)
at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:105)
at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:80)
at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:71)
at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:62)
at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:41)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:51)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:39)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
at org.gradle.util.internal.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:64)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.ClassNotFoundException: org.postgresql.util.ServerErrorMessage
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:594)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527)
... 66 more
// and at the end there's even more:
org.gradle.tooling.GradleConnectionException: Could not execute build using connection to Gradle installation ...
Caused by: java.lang.NullPointerException
at org.gradle.tooling.internal.provider.serialization.PayloadSerializer.deserialize(PayloadSerializer.java:67)
at org.gradle.tooling.internal.provider.ProviderConnection.run(ProviderConnection.java:232)
at org.gradle.tooling.internal.provider.ProviderConnection.run(ProviderConnection.java:152)
at org.gradle.tooling.internal.provider.DefaultConnection.getModel(DefaultConnection.java:149)
at org.gradle.tooling.internal.consumer.connection.CancellableModelBuilderBackedModelProducer.produceModel(CancellableModelBuilderBackedModelProducer.java:54)
at org.gradle.tooling.internal.consumer.connection.PluginClasspathInjectionSupportedCheckModelProducer.produceModel(PluginClasspathInjectionSupportedCheckModelProducer.java:38)
at org.gradle.tooling.internal.consumer.connection.AbstractConsumerConnection.run(AbstractConsumerConnection.java:64)
at org.gradle.tooling.internal.consumer.connection.ParameterValidatingConsumerConnection.run(ParameterValidatingConsumerConnection.java:49)
at org.gradle.tooling.internal.consumer.DefaultBuildLauncher$1.run(DefaultBuildLauncher.java:97)
at org.gradle.tooling.internal.consumer.DefaultBuildLauncher$1.run(DefaultBuildLauncher.java:89)
at org.gradle.tooling.internal.consumer.connection.LazyConsumerActionExecutor.run(LazyConsumerActionExecutor.java:143)
at org.gradle.tooling.internal.consumer.connection.CancellableConsumerActionExecutor.run(CancellableConsumerActionExecutor.java:45)
at org.gradle.tooling.internal.consumer.connection.ProgressLoggingConsumerActionExecutor.run(ProgressLoggingConsumerActionExecutor.java:61)
at org.gradle.tooling.internal.consumer.connection.RethrowingErrorsConsumerActionExecutor.run(RethrowingErrorsConsumerActionExecutor.java:38)
at org.gradle.tooling.internal.consumer.async.DefaultAsyncConsumerActionExecutor$1$1.run(DefaultAsyncConsumerActionExecutor.java:67)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
We found 3 workarounds, but none of them seem very appealing:
switching from classloaderIsolation to processIsolation
running the test withDebug(true) (which is not possible when using environment variables for the gradleRunner) completes the test successfully but the NoClassDefFoundError is still in the log
“stringify” the original Exception and deliver the messages and stacktraces as message of the GradleException
Anyone an Idea if we’re doing something wrong or is it a known issue in test-kit?
Maybe investigate what getClasspath() returns and whether it is the expected result including that PostgreSQL class?
If it works when executing the plugin in a real project but not when using TestKit, often a proper mitigation is to not use withPluginClasspath(), but publishing the plugin to some local maven repository (optimally something dedicated and notmavenLocal()). Then use the plugin in the test from that repository.
The postgresql.jar is compileOnly for the plugin, but it’s a dependency in a configuration created by the plugin which is the classpath you see in my code example.
We specifically wanted to decouple the Tasks runtime dependencies from the plugin classpath, cause we had issues earlier with plugins that where forcing certain library versions that where not compatible with another plugins dependencies (one plugin forcing commons-io:1.2 and the other requesting 1.12 - awful but it really happened).
We also wanted to be able to simply play with the dependencies versions without the need to rebuild the plugins.
In my quick testing as an includedBuild the same error occurred when trying to run the task while no database was up.
FAILURE: Build completed with 2 failures.
1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':PBL_TestEAR:updateDB'.
> There was a failure while executing work items
> A failure occurred while executing com...UpdateWorkAction
> db interaction failed
* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':updateDB'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:130)
at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:282)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:128)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:116)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:331)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:318)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:314)
at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:314)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
Caused by: org.gradle.workers.WorkerExecutionException: There was a failure while executing work items
at org.gradle.workers.internal.DefaultWorkerExecutor.workerExecutionException(DefaultWorkerExecutor.java:223)
at org.gradle.workers.internal.DefaultWorkerExecutor.await(DefaultWorkerExecutor.java:217)
at org.gradle.workers.internal.DefaultWorkerExecutor.access$100(DefaultWorkerExecutor.java:60)
at org.gradle.workers.internal.DefaultWorkerExecutor$DefaultWorkQueue.await(DefaultWorkerExecutor.java:312)
at com...UpdateTask.updateDB(UpdateTask.java:42)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:244)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:229)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:212)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:195)
at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:162)
...
Caused by: org.gradle.workers.internal.DefaultWorkerExecutor$WorkExecutionException: A failure occurred while executing com...UpdateWorkAction
at org.gradle.workers.internal.DefaultWorkerExecutor$WorkItemExecution.waitForCompletion(DefaultWorkerExecutor.java:287)
at org.gradle.internal.work.DefaultAsyncWorkTracker.lambda$waitForItemsAndGatherFailures$2(DefaultAsyncWorkTracker.java:130)
at org.gradle.internal.Factories$1.create(Factories.java:31)
at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLocks(DefaultWorkerLeaseService.java:336)
at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLocks(DefaultWorkerLeaseService.java:319)
at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLock(DefaultWorkerLeaseService.java:324)
at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForItemsAndGatherFailures(DefaultAsyncWorkTracker.java:126)
at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForItemsAndGatherFailures(DefaultAsyncWorkTracker.java:88)
at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForAll(DefaultAsyncWorkTracker.java:78)
at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForCompletion(DefaultAsyncWorkTracker.java:72)
at org.gradle.workers.internal.DefaultWorkerExecutor.await(DefaultWorkerExecutor.java:215)
at org.gradle.workers.internal.DefaultWorkerExecutor.access$100(DefaultWorkerExecutor.java:60)
at org.gradle.workers.internal.DefaultWorkerExecutor$DefaultWorkQueue.await(DefaultWorkerExecutor.java:312)
at com...UpdateTask.updateDB(UpdateTask.java:42)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:244)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:229)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:212)
...
Caused by: org.gradle.api.GradleException: db interaction failed
at com...UpdateWorkAction.execute(UpdateWorkAction.java:20)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:54)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:48)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:48)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:49)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:30)
at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.lambda$execute$0(IsolatedClassloaderWorkerFactory.java:57)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.execute(IsolatedClassloaderWorkerFactory.java:49)
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:174)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:187)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:120)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:162)
at org.gradle.internal.Factories$1.create(Factories.java:31)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:264)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:128)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:133)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:157)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:126)
... 2 more
Caused by: liquibase.exception.DatabaseException: org.postgresql.util.PSQLException: Connection to localhost:43432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
at liquibase.database.DatabaseFactory.openConnection(DatabaseFactory.java:247)
at liquibase.database.DatabaseFactory.openDatabase(DatabaseFactory.java:151)
at liquibase.database.DatabaseFactory.openDatabase(DatabaseFactory.java:140)
... 32 more
Caused by: org.postgresql.util.PSQLException: Connection to localhost:43432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195)
at org.postgresql.Driver.makeConnection(Driver.java:454)
at org.postgresql.Driver.connect(Driver.java:256)
at liquibase.database.DatabaseFactory.openConnection(DatabaseFactory.java:239)
... 39 more
Caused by: java.net.ConnectException: Connection refused: connect
at org.postgresql.core.PGStream.<init>(PGStream.java:70)
at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:91)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:192)
... 44 more
==============================================================================
2: Task failed with an exception.
-----------
* What went wrong:
org/postgresql/util/ServerErrorMessage
> org.postgresql.util.ServerErrorMessage
* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
* Exception is:
java.lang.NoClassDefFoundError: org/postgresql/util/ServerErrorMessage
at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3166)
at java.base/java.lang.Class.getDeclaredMethods(Class.java:2309)
at org.gradle.internal.serialize.ExceptionPlaceholder.findCandidateGetCausesMethod(ExceptionPlaceholder.java:296)
at org.gradle.internal.serialize.ExceptionPlaceholder.tryExtractMultiCauses(ExceptionPlaceholder.java:315)
at org.gradle.internal.serialize.ExceptionPlaceholder.extractCauses(ExceptionPlaceholder.java:279)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:104)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.ExceptionPlaceholder.convertToExceptionPlaceholderList(ExceptionPlaceholder.java:174)
at org.gradle.internal.serialize.ExceptionPlaceholder.<init>(ExceptionPlaceholder.java:141)
at org.gradle.internal.serialize.TopLevelExceptionPlaceholder.<init>(TopLevelExceptionPlaceholder.java:28)
at org.gradle.internal.serialize.ExceptionReplacingObjectOutputStream.doReplaceObject(ExceptionReplacingObjectOutputStream.java:67)
at org.gradle.internal.serialize.ExceptionReplacingObjectOutputStream$1.transform(ExceptionReplacingObjectOutputStream.java:31)
at org.gradle.internal.serialize.ExceptionReplacingObjectOutputStream.replaceObject(ExceptionReplacingObjectOutputStream.java:62)
at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1135)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:345)
at org.gradle.tooling.internal.provider.serialization.PayloadSerializer.serialize(PayloadSerializer.java:53)
...
Caused by: java.lang.ClassNotFoundException: org.postgresql.util.ServerErrorMessage
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:594)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527)
... 66 more
==============================================================================
BUILD FAILED in 2s
12:26:21: Execution finished 'updateDB --stacktrace'.
So that might answer my previous question if it’s only related to test-kit, as it’s also happening without. But now it’s even more astounding that withDebug(true) did work during testing.
Not an included build, published to a local directory and taken from there.
When using withPluginClasspath iirc the plugin’s classes are in some higher class loader that might then also be available from there in the classloader isolation and then cannot find the PostgreSQL class as it is in a lower classpath.
When using debug, the tests are executed in-process and so classloaders are again different.
The more production-y setup you have if you publish to a local repository and consume from there.
For the classloaders I am expecting them to behave like you said.
The plugin classloader should not see the tasks Worker classes.
The Worker should not see the plugin classpath.
I am fully aware that throwing an Exception in the Worker, which is an instance of a Class that is only available within that worker is a tricky thing to hand back to the gradle core, but I expected that to be taken care of and don’t remember seeing that issue before.
For the MVCE, I’ll try to squeeze out some time to create one.
Ah, wait, I think I see what you mean now, sorry.
The Gradle serialization tries to replace the exception with some placeholder and there fails due to that no class def found error while trying to get all declared methods.