Blockhound

Java agent to detect blocking calls from non-blocking threads.
Alternatives To Blockhound
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Rxandroid19,77010,146214a month ago6February 15, 20191apache-2.0Java
RxJava bindings for Android
Rxjava Android Samples7,548
6 months ago10apache-2.0Java
Learning RxJava for Android by example
Rxbus2,08810212 years ago13January 09, 20216apache-2.0Java
Event Bus By RxJava.
Blockhound1,163149 days ago7April 06, 202116apache-2.0Java
Java agent to detect blocking calls from non-blocking threads.
Mvvm Kotlin Android Architecture1,147
2 years ago6apache-2.0Kotlin
MVVM + Kotlin + Retrofit2 + Hilt + Coroutines + Kotlin Flow + mockK + Espresso + Junit5
Reaktive1,031113 days ago4June 13, 20227apache-2.0Kotlin
Kotlin multi-platform implementation of Reactive Extensions
Rxjavafx4942722 years ago18February 25, 201718apache-2.0Java
RxJava bindings for JavaFX
Asyncawait410
5 years ago9apache-2.0Kotlin
async/await for Android built upon coroutines introduced in Kotlin 1.1
Inlineactivityresult214
3 years agomitJava
Receive the activity result directly after the startActivityForResult with InlineActivityResult
Rxkotlinfx176732 years ago19November 27, 20178apache-2.0Kotlin
Kotlin extensions to the RxJavaFX framework
Alternatives To Blockhound
Select To Compare


Alternative Project Comparisons
Readme

BlockHound

Travis CI 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'
}

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"
            ]
        }
    }

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

Popular Thread Projects
Popular Rxjava Projects
Popular Control Flow Categories

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Java
Thread
Rxjava
Spi
Reactor