Skip to content

Latest commit

 

History

History
147 lines (125 loc) · 5.71 KB

quick_start.md

File metadata and controls

147 lines (125 loc) · 5.71 KB

Quick start

Getting it

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

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

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

Using Tomcat

When using BlockHound from a Tomcat webapp, do not embedd blockhound dependency within your webapp. Instead of that, just drop the blockhound jar in the Tomcat shared "lib" directory. If you are using Cargo maven plugin, this can be done using a shared classpath

Here is an example using Cargo maven plugin:

    <dependencies>
        <dependency>
            <groupId>io.projectreactor.tools</groupId>
            <artifactId>blockhound</artifactId>
            <version>(latest blockhound version)</version>
            <scope>provided</scope>
        </dependency>
        ...
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven3-plugin</artifactId>
                <version>1.10.4</version>
                <configuration>
                    <container>
                        <containerId>tomcat9x</containerId>
                        <type>embedded</type>
                        <dependencies>
                            <dependency>
                                <groupId>io.projectreactor.tools</groupId>
                                <artifactId>blockhound</artifactId>
                                <classpath>shared</classpath>
                            </dependency>
                        </dependencies>
                    </container>
                    <deployables>
                        <deployable>
                            <type>war</type>
                            <location>${project.build.directory}/${project.build.finalName}.war</location>
                            <properties>
                                <context>/</context>
                            </properties>
                        </deployable>
                    </deployables>
                </configuration>
            </plugin>
        </plugins>
    </build>
    ...

Installation

BlockHound is a JVM agent. You need to "install" it before it starts detecting the issues:

BlockHound.install();

On install, it will discover all known integrations (see writing custom integrations for details) and perform a one time instrumentation (see how it works). The method is idempotent, you can call it multiple times.

The best place to put this line is before any code gets executed, e.g. @BeforeClass, or static {} block, or test listener. BlockHound also supports some testing frameworks.

NB: it is highly recommended to add a dummy test with a well-known blocking call to ensure that it installed correctly.
Something like this will work:

Mono.delay(Duration.ofMillis(1))
    .doOnNext(it -> {
        try {
            Thread.sleep(10);
        }
        catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    })
    .block(); // should throw an exception about Thread.sleep

If you can't change the application code, you can also activate BlockHound using the -javaagent: JVM option, something like this (you need at least version 1.0.7):

java -javaagent:BlockHound/agent/build/libs/agent.jar -jar my-application.jar

Notice that when using JPMS, for the moment BlockHound needs to be installed using -javaavant JVM option.

What's Next?

You can further customize Blockhound's behavior, see customization.