This rule raises an issue when a java.time.Duration conversion method is passed as a long argument alongside an adjacent java.util.concurrent.TimeUnit argument whose unit does not match the converted unit.

Why is this an issue?

Timeout interfaces commonly accept a numeric duration and a TimeUnit constant, such as Future.get(long, TimeUnit) or CountDownLatch.await(long, TimeUnit). The numeric value has no unit by itself; the TimeUnit gives it meaning.

Converting a Duration value already chooses a unit. For example, toMillis() produces a value in milliseconds, and toSeconds() produces a value in seconds. Passing that converted number with a different TimeUnit causes the API to interpret the value in the wrong unit.

For example, passing timeout.toMillis() with TimeUnit.SECONDS changes a one-second timeout into 1,000 seconds. Conversely, passing timeout.toSeconds() with TimeUnit.MILLISECONDS turns a one-second timeout into one millisecond. Such mismatches can cause operations to time out prematurely or block much longer than intended.

What is the potential impact?

A mismatched time unit can make a timeout much shorter or longer than intended, causing premature operation failures, blocked threads, exhausted resources, or delayed shutdowns.

How to fix it

Use the TimeUnit that matches the Duration conversion, or convert the Duration to the unit expected by the API.

Code examples

Noncompliant code example

future.get(timeout.toMillis(), TimeUnit.SECONDS); // Noncompliant: Change this TimeUnit to "MILLISECONDS" or convert the duration to seconds.

Compliant solution

future.get(timeout.toMillis(), TimeUnit.MILLISECONDS);
future.get(timeout.toSeconds(), TimeUnit.SECONDS);

Resources

Documentation