Skip to content

Add workaround for JDK-8166253#2065

Merged
Godin merged 5 commits into
jacoco:masterfrom
Godin:JDK-8166253
Mar 9, 2026
Merged

Add workaround for JDK-8166253#2065
Godin merged 5 commits into
jacoco:masterfrom
Godin:JDK-8166253

Conversation

@Godin

@Godin Godin commented Mar 6, 2026

Copy link
Copy Markdown
Member

For the past few days I observe frequent failures in AzurePipelines on JDK 6:

[INFO] Running org.jacoco.agent.rt.internal.output.FileOutputTest
[ERROR] Tests run: 5, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.51 s <<< FAILURE! - in org.jacoco.agent.rt.internal.output.FileOutputTest
[ERROR] startup_should_throw_OverlappingFileLockException_when_execfile_is_permanently_locked(org.jacoco.agent.rt.internal.output.FileOutputTest)  Time elapsed: 0.506 s  <<< FAILURE!
java.lang.AssertionError: OverlappingFileLockException expected
	at org.jacoco.agent.rt.internal.output.FileOutputTest.startup_should_throw_OverlappingFileLockException_when_execfile_is_permanently_locked(FileOutputTest.java:103)

see build log for first commit in this PR


While

System.runFinalization();
System.gc();
System.runFinalization();
System.gc();

does not guarantee GCs and finalizations to happen, addition of it after every out.getChannel().lock() in tests seems to increase chances to reproduce, so that it becomes even visible also in another test on JDK versions from 6 to 10, as well as in GitHub Actions and locally on my machine:

[INFO] Running org.jacoco.agent.rt.internal.output.FileOutputTest
[ERROR] Tests run: 5, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.032 s <<< FAILURE! - in org.jacoco.agent.rt.internal.output.FileOutputTest
[ERROR] startup_should_throw_InterruptedIOException_when_execfile_is_locked_and_thread_is_interrupted(org.jacoco.agent.rt.internal.output.FileOutputTest)  Time elapsed: 0.019 s  <<< FAILURE!
java.lang.AssertionError: InterruptedIOException expected
	at org.jacoco.agent.rt.internal.output.FileOutputTest.startup_should_throw_InterruptedIOException_when_execfile_is_locked_and_thread_is_interrupted(FileOutputTest.java:131)

[ERROR] startup_should_throw_OverlappingFileLockException_when_execfile_is_permanently_locked(org.jacoco.agent.rt.internal.output.FileOutputTest)  Time elapsed: 0.01 s  <<< FAILURE!
java.lang.AssertionError: OverlappingFileLockException expected
	at org.jacoco.agent.rt.internal.output.FileOutputTest.startup_should_throw_OverlappingFileLockException_when_execfile_is_permanently_locked(FileOutputTest.java:104)

see build logs for second commit in this PR


And so I suspect that these tests demonstrate http://bugs.openjdk.org/browse/JDK-8166253 which was fixed in JDK 11.

Our main code seems to be affected too - like tests it does not preserve reference on lock object:


so there is a chance that another FileOutput writing to the same file within same JVM will not receive OverlappingFileLockException while first one not yet finished writing data.

Note that this does not seem to affect filesystem level lock - see build log on Windows for the second commit in this PR - it hangs (blocked on the above call) in test startup_should_throw_InterruptedIOException_when_execfile_is_locked_and_thread_is_interrupted because OverlappingFileLockException is not be observed after GC of FileLock.


And maybe this might be an explanation of past reports about data corruption such as https://groups.google.com/g/jacoco/c/wrKJbyJyNII/m/WIe6yrewAwAJ

Following test

	@Test
	public void test() throws Exception {
		File destFile = folder.newFile("jacoco.exec");
		final AgentOptions options = new AgentOptions();
		options.setDestfile(destFile.getAbsolutePath());

		final RuntimeData runtimeData = new RuntimeData();
		runtimeData.setSessionId(new String(new char[1024]));

		Thread thread0 = new Thread() {
			@Override
			public void run() {
				for (int i = 0; i < 100; i++) {
					System.runFinalization();
					System.gc();
				}
			}
		};
		thread0.start();

		Thread thread1 = new Thread() {
			@Override
			public void run() {
				FileOutput output = new FileOutput();
				try {
					output.startup(options, runtimeData);
					output.writeExecutionData(false);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		};
		thread1.start();

		Thread thread2 = new Thread() {
			@Override
			public void run() {
				FileOutput output = new FileOutput();
				try {
					output.startup(options, runtimeData);
					output.writeExecutionData(false);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		};
		thread2.start();

		thread0.join();
		thread1.join();
		thread2.join();
		new ExecFileLoader().load(destFile);
	}

demonstrates such corruption:

java.io.UTFDataFormatException: malformed input around byte 1153
	at java.io.DataInputStream.readUTF(DataInputStream.java:634)
	at java.io.DataInputStream.readUTF(DataInputStream.java:564)
	at org.jacoco.core.data.ExecutionDataReader.readSessionInfo(ExecutionDataReader.java:138)
	at org.jacoco.core.data.ExecutionDataReader.readBlock(ExecutionDataReader.java:113)
	at org.jacoco.core.data.ExecutionDataReader.read(ExecutionDataReader.java:93)
	at org.jacoco.core.tools.ExecFileLoader.load(ExecFileLoader.java:60)
	at org.jacoco.core.tools.ExecFileLoader.load(ExecFileLoader.java:74)
	at org.jacoco.agent.rt.internal.output.FileOutputTest.test(FileOutputTest.java:200)

@Godin Godin added this to the 0.8.15 milestone Mar 6, 2026
@Godin Godin self-assigned this Mar 6, 2026
@Godin Godin changed the title Add workaround for JDK-8166253 to tests Add workaround for JDK-8166253 Mar 6, 2026
@Godin Godin added component: core type: bug 🐛 Something isn't working labels Mar 6, 2026
@Godin Godin requested a review from marchof March 6, 2026 21:59
@Godin Godin marked this pull request as ready for review March 9, 2026 20:26
@Godin Godin enabled auto-merge (squash) March 9, 2026 20:26
@Godin Godin merged commit 61e3e8a into jacoco:master Mar 9, 2026
80 of 82 checks passed
@Godin Godin deleted the JDK-8166253 branch March 9, 2026 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants