GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - reactor/BlockHound: Java agent to detect blocking calls from non-blocking threads.

BranchesTags
Open more actions menu

Latest commit

 

History

412 Commits
412 Commits

Folders and files

NameName
Last commit message
Last commit date
.github
.github
 
 
agent
agent
 
 
benchmarks
benchmarks
 
 
docs
docs
 
 
example
example
 
 
gradle
gradle
 
 
junit-platform
junit-platform
 
 
.gitignore
.gitignore
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
build.gradle
build.gradle
 
 
gradle.properties
gradle.properties
 
 
gradlew
gradlew
 
 
gradlew.bat
gradlew.bat
 
 
jitpack.yml
jitpack.yml
 
 
settings.gradle
settings.gradle
 
 

Repository files navigation

BlockHound

Gitter

Java agent to detect blocking calls from non-blocking threads.

How it works

BlockHound will transparently instrument the JVM classes and intercept blocking calls (e.g. IO) if they are performed from threads marked as "non-blocking operations only" (ie. threads implementing Reactor's NonBlocking marker interface, like those started by Schedulers.parallel()). If and when this happens (but remember, this should never happen! 😜), an error will be thrown. Here is an example:

// Example.java
BlockHound.install();

Mono.delay(Duration.ofSeconds(1))
    .doOnNext(it -> {
        try {
            Thread.sleep(10);
        }
        catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    })
    .block();

Will result in:

reactor.blockhound.BlockingOperationError: Blocking call! java.lang.Thread.sleep
	at java.base/java.lang.Thread.sleep(Native Method)
	at com.example.Example.lambda$exampleTest$0(Example.java:16)

Note that it points to the exact place where the blocking call got triggered. In this example it was Example.java:16.

Getting it

Download it from Maven Central repositories (stable releases only) or repo.spring.io:

Gradle

repositories {
  mavenCentral()
  // maven { url 'https://repo.spring.io/milestone' }
  // maven { url 'https://repo.spring.io/snapshot' }
}

dependencies {
  testImplementation 'io.projectreactor.tools:blockhound:$LATEST_RELEASE'
  // testImplementation 'io.projectreactor.tools:blockhound:$LATEST_MILESTONE'
  // testImplementation 'io.projectreactor.tools:blockhound:$LATEST_SNAPSHOT'
}
with Kotlin DSL
repositories {
    mavenCentral()
    // maven("https://repo.spring.io/milestone")
    // maven("https://repo.spring.io/snapshot")
}

dependencies {
    testImplementation("io.projectreactor.tools:blockhound:$LATEST_RELEASE")
    // testImplementation("io.projectreactor.tools:blockhound:$LATEST_MILESTONE")
    // testImplementation("io.projectreactor.tools:blockhound:$LATEST_SNAPSHOT")
}

Maven

<dependencies>
  <dependency>
    <groupId>io.projectreactor.tools</groupId>
    <artifactId>blockhound</artifactId>
    <version>$LATEST_RELEASE</version>
  </dependency>
</dependencies>

Where:

$LATEST_RELEASE
$LATEST_MILESTONE
$LATEST_SNAPSHOT

JDK13+ support

for JDK 13+, it is no longer allowed redefining native methods. So for the moment, as a temporary work around, please use the -XX:+AllowRedefinitionToAddDeleteMethods jvm argument:

Maven

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <argLine>-XX:+AllowRedefinitionToAddDeleteMethods</argLine>
                </configuration>
    </plugin>

Gradle

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

Built-in integrations

Although BlockHound supports the SPI mechanism to integrate with, it comes with a few built-in integrations:

  1. Project Reactor
    Version 3.2.x is supported out of the box.
    Starting with reactor-core version 3.3.0, there is a built-in integration in Reactor itself that uses the SPI.
  2. RxJava 2 is supported.
    RxJava 3 and further versions of RxJava will require an SPI to be implemented, either by the framework or user. See this PR to RxJava with an example of the SPI's implementation.

Quick Start

See the docs.


Licensed under Apache Software License 2.0

Sponsored by Pivotal

About

Java agent to detect blocking calls from non-blocking threads.

Resources

Readme
Apache-2.0 license

Code of conduct

Code of conduct

Contributing

Contributing

Security policy

Security policy
Activity
Custom properties

Stars

1.5k stars

Watchers

34 watching

Forks

96 forks
Report repository

Releases

Packages

Used by

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.