reactor / reactor/BlockHound

Blockhound not working as expected when Future.get

Open
#529 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
1.5k
Forks
95
Avg merge
1d 14m
Merged PRs (30d)
6

Description

Hi mates!!

I would like to try BlockHound in Java 17 or Java 21 but I cannot make it work properly.
I have an empty project using Spring Boot 3.5.6, with WebFlux starter and blockhound in version 1.0.14.RELEASE.

I just created a test class with a super simple Blockhound install and a single test to check that blockhound works.

In that test, I tried the Thread.sleep (as documentation suggests) and another Mono chain because I could read that there are some issues with native operations in Java methods.

I also configured the gradle tests to add the VM argument to enabling the native instrumentation.

I'm using the reactor versions defined by Spring Webflux, which are almost the latest one.

Expected Behavior

The expected behavior should be that the check tests should pass.

Actual Behavior

The dummy test is not passing.

Steps to Reproduce

package com.example.demoblockhound;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import reactor.blockhound.BlockHound;
import reactor.blockhound.BlockingOperationError;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;


@SpringBootTest
class DemoBlockHoundApplicationTests {


    @BeforeAll
    static void beforeAll() {
        BlockHound.builder()
                // Optional: Customize BlockHound here (see next section)
                // .allowBlockingCallsInside(...)
                // .install();
                .install(); // Minimal installation
    }


    @Test
    void contextLoads() {
    }

    @Test
    public void blockHoundWorks() throws TimeoutException, InterruptedException {
        try {
            FutureTask<?> task = new FutureTask<>(() -> {
//                Thread.sleep(10);   <- it was the first attempt, as documentation indicates
//                return "";
                return Mono.just("block")
                        .map(b -> "other")
                        .toFuture().get();

            });
            Schedulers.parallel().schedule(task);

            task.get(10, TimeUnit.SECONDS);
            Assertions.fail("should fail");
        } catch (ExecutionException e) {
            //e.printStackTrace();
            Assertions.assertTrue(e.getCause() instanceof BlockingOperationError, "detected");
        }
    }

}


(build.gradle)

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.5.6'
    id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
description = 'demoBlockHound'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.projectreactor:reactor-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'io.projectreactor.tools:blockhound:1.0.14.RELEASE'
}

tasks.named('test') {
    useJUnitPlatform()
}

tasks.withType(Test).all {
    if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) {
        jvmArgs += [
                "-XX:+AllowRedefinitionToAddDeleteMethods"
        ]
    }
}

Your Environment

  • Reactor version(s) used:
  • Other relevant libraries versions (eg. netty, ...):
  • reactor-netty-core: 1.2.10
  • reactor-core:3.7.11
  • netty: 4.1.127.Final
  • SB: 3.5.6
  • JVM version (java -version): tested with java 17 and java 21
  • OS and version (eg uname -a): MacOS Sequoia 15.6.1 (24G90)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the DemoBlockHoundApplicationTests reproducer and the test configuration in build.gradle, then run the test on Java 17 and Java 21. Compare the Thread.sleep and Future.get cases and inspect the ExecutionException cause. Done means the expected BlockHound behavior for this reproducer is established and the failing behavior is either corrected or clearly documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring-boot
Domain
backend, testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.