junit-team/junit5 · error · JUnitException

Failed to close extension context

Error message

Failed to close extension context

What it means

Thrown by JupiterEngineExecutionContext.close() when the ExtensionContext (which implements AutoCloseable) throws an Exception from its close() method. The ExtensionContext.close() cascades through its NamespacedHierarchicalStore, closing every stored CloseableResource/AutoCloseable, so any single resource that fails to close surfaces here.

Source

Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/JupiterEngineExecutionContext.java:54

	private boolean beforeAllMethodsExecuted = false;

	public JupiterEngineExecutionContext(EngineExecutionListener executionListener, JupiterConfiguration configuration,
			LauncherStoreFacade launcherStoreFacade) {
		this(new State(executionListener, configuration, launcherStoreFacade));
	}

	private JupiterEngineExecutionContext(State state) {
		this.state = state;
	}

	public void close() throws Exception {
		ExtensionContext extensionContext = getExtensionContext();
		if (extensionContext instanceof @SuppressWarnings("resource") AutoCloseable closeable) {
			try {
				closeable.close();
			}
			catch (Exception e) {
				throw new JUnitException("Failed to close extension context", e);
			}
		}
	}

	public EngineExecutionListener getExecutionListener() {
		return this.state.executionListener;
	}

	public JupiterConfiguration getConfiguration() {
		return this.state.configuration;
	}

	public LauncherStoreFacade getLauncherStoreFacade() {
		return this.state.launcherStoreFacade;
	}

	public TestInstancesProvider getTestInstancesProvider() {
		return requireNonNull(this.state.testInstancesProvider);

View on GitHub (pinned to 956246301e)

Solutions

  1. Inspect the cause Exception — it identifies which stored resource's close() failed.
  2. Make your stored resource's close() swallow/ log non-fatal exceptions and only throw on truly unrecoverable errors.
  3. If a resource need not be auto-closed, do not implement AutoCloseable/CloseableResource, or disable auto-close via the configuration flag isClosingStoredAutoCloseablesEnabled.
  4. Close heavy resources explicitly in an @AfterEach/@AfterAll rather than relying on context shutdown.

Example fix

// before
class ConnResource implements Store.CloseableResource {
    Connection conn;
    public void close() throws Exception { conn.close(); } // SQLException bubbles up
}
// after
class ConnResource implements Store.CloseableResource, AutoCloseable {
    Connection conn;
    public void close() {
        try { conn.close(); } catch (SQLException e) { /* log, do not rethrow */ }
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate each stored CloseableResource closes cleanly in a test
Store.CloseableResource r = createResource();
try { r.close(); } catch (Exception e) { throw new AssertionError("Resource close leaks exception", e); }

Try / catch

// Wrap resource close so it never propagates from context shutdown
class SafeResource implements Store.CloseableResource, AutoCloseable {
    public void close() {
        try { delegate.close(); } catch (Exception e) { log.warn("close failed", e); }
    }
}

Prevention

When it happens

Trigger: An extension stored a CloseableResource (or AutoCloseable) in the ExtensionContext Store whose close() throws an Exception (e.g. a database connection, network socket, or file handle that fails on shutdown).

Common situations: A Store.CloseableResource wrapping a JDBC connection whose close() throws SQLException; an AutoCloseable test fixture whose close() fails after a test error; resources registered via getStore(...).put(key, resource) where resource.close() is not exception-safe.

Related errors


AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04). Data as JSON: /data/errors/8355948a330e650c.json. Report an issue: GitHub.