Skip to content
This repository was archived by the owner on Aug 11, 2023. It is now read-only.
This repository was archived by the owner on Aug 11, 2023. It is now read-only.

Future key returns null for ConcurrentHashMap #274

Closed
@msmcconnell

Description

@msmcconnell

I have recently begun to see the following error when running a launch file with rosjava nodes.

java.lang.NullPointerException
	at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
	at org.ros.concurrent.RetryingExecutorService$RetryLoop.loop(RetryingExecutorService.java:84)
	at org.ros.concurrent.CancellableLoop.run(CancellableLoop.java:56)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

The error occurs on node startup via DefaultNode constructor and the Registrar constructor which creates a RetryingExecutorService.
Inspecting the RetryingExecutorService, it would appear that the RetryLoop.loop function contains the the responsible lines

  private class RetryLoop extends CancellableLoop {
    @Override
    public void loop() throws InterruptedException {
      Future<Boolean> future = completionService.take();
      final Callable<Boolean> callable = callables.remove(future);
      boolean retry;
      try {
        retry = future.get();
      } catch (ExecutionException e) {
        throw new RosRuntimeException(e.getCause());
      }
      if (retry) {
        if (DEBUG) {
          log.info("Retry requested.");
        }
        scheduledExecutorService.schedule(new Runnable() {
          @Override
          public void run() {
            submit(callable);
          }
        }, retryDelay, retryTimeUnit);
      } else {
        latches.get(callable).countDown();
      }
    }
  }

The callable returned here must be null

      Future<Boolean> future = completionService.take();
      final Callable<Boolean> callable = callables.remove(future);

Resulting in the exception coming from this line

 latches.get(callable).countDown();

This could be prevented with a simple null check. However, I am very unsure of how this exception can occur. It appears the RetryingExecutorService.submit function is only ever called in the Registrar using new Callable instances. This would seem to make the error impossible. Another set of eyes would help in my understanding of this problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions