Activiti
Spring Boot
Gradle
Build Issue
Testing

Activiti Spring Boot Gradle build hangs while gradle clean test

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When gradle clean test appears to hang in an Activiti plus Spring Boot project, the usual cause is not Gradle itself. More often, a test has started a Spring context, workflow executor, database connection, or background thread that never shuts down cleanly, so the JVM stays alive after the test logic finishes.

Find Out Whether It Is Stuck or Just Slow

The first job is to learn where the build stops making progress. Run Gradle with more detail:

bash
./gradlew clean test --info --stacktrace

If the console stops after a specific test class, that class is the first suspect. If the logs show Spring context startup but never show teardown, look for non-daemon threads or a test waiting on workflow completion that never arrives.

You can also temporarily run one test class at a time:

bash
./gradlew test --tests com.example.workflow.ProcessTest --info

That narrows the search quickly.

Activiti Can Start Background Work

Activiti is not just a passive library. Depending on configuration, it may start async executors, job acquisition threads, timers, or engine infrastructure that outlives the individual test method.

For tests, that often means you should disable asynchronous execution unless the test explicitly needs it:

yaml
spring:
  activiti:
    async-executor-activate: false

If a test expects a background job to run but the executor is disabled, trigger that work manually or isolate it into an integration test with explicit waiting and cleanup.

Reduce the Spring Boot Test Footprint

A full @SpringBootTest loads much more than many tests actually need. That increases startup time and makes hangs more likely.

A leaner setup is often enough:

java
1@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
2@ActiveProfiles("test")
3class ProcessTest {
4}

Using a test profile lets you turn off schedulers, messaging integrations, remote clients, and other infrastructure that is irrelevant to process-engine validation.

Watch for Database and Transaction Waits

Activiti tests often involve an embedded database or a real SQL engine. A build that looks hung may really be waiting on:

  • an uncommitted transaction
  • a schema lock during startup
  • a job executor polling loop
  • a test waiting forever for a process state transition

If you poll for completion, use timeouts instead of open-ended loops:

java
await()
    .atMost(Duration.ofSeconds(5))
    .until(() -> runtimeService.createProcessInstanceQuery().count() == 0);

Without a timeout, one failed condition can keep the build alive indefinitely.

Gradle and Test Parallelism Can Expose Races

Parallel test execution can make shared workflow infrastructure behave badly. If multiple tests share the same database, schema, or process-engine state, they can block each other or interfere in subtle ways.

A conservative test configuration is often safer while debugging:

groovy
1tasks.test {
2    maxParallelForks = 1
3    forkEvery = 1
4}

This is not always the best long-term performance setting, but it is a useful diagnostic move. If the hang disappears with single-process test execution, you likely have test isolation problems rather than a Gradle bug.

Clean Shutdown Matters

If you create custom executors, embedded servers, or messaging containers inside tests, close them explicitly. The same applies to Spring contexts started manually. A test can "pass" while still leaving a non-daemon thread running, which keeps Gradle waiting forever for JVM shutdown.

Thread dumps are very effective here. If a stuck build leaves a Java process alive, inspect the live threads and look for names related to Activiti jobs, Hikari pools, schedulers, or HTTP servers.

Common Pitfalls

  • Assuming Gradle is hung when a specific test is actually waiting forever on process completion or I/O.
  • Running full @SpringBootTest contexts for tests that only need the process engine adds startup cost and more moving parts.
  • Leaving the Activiti async executor enabled during tests creates background threads that are easy to forget about.
  • Allowing parallel tests to share one database or engine state can create blocking that looks random.
  • Polling without a timeout is a classic cause of "hangs" that are really infinite waits.

Summary

  • A hanging gradle clean test in Activiti projects is usually caused by test infrastructure that does not stop cleanly.
  • Start with --info and isolate the exact test class or context that stops progressing.
  • Disable unnecessary async engine features in the test profile and keep the Spring context as small as possible.
  • Use explicit timeouts, avoid uncontrolled parallelism, and check for leftover non-daemon threads.

Course illustration
Course illustration

All Rights Reserved.