1

I'm trying to upgrade from docker-java 0.10.3 to 3.2.7. This line has me completely stumped:

InputStream response = 
  dockerClient.attachContainerCmd(container.getId())
    .withLogs(true)
    .withStdErr(true)
    .withStdOut(true)
    .withFollowStream(true)
    .exec();

I have managed to get round one error by changing it to

InputStream response = 
  dockerClient.attachContainerCmd(container.getId())
    .withLogs(true)
    .withStdErr(true)
    .withStdOut(true)
    .withFollowStream(true)
    .exec(new AttachContainerResultCallback());

(but my IDE says that AttachContainerResultCallback is deprecated.) The problem is that .exec() used to return an InputStream. Now it returns a void. I need the InputStream, because the output of the commands running in the container needs to find it's way to the screen. This needs to be realtime, because the user needs to see the output of the commands as they are running; I can't just copy a file at the end.

How can I get hold of this InputStream?


The error is:

java: incompatible types: inference variable T has incompatible bounds
    lower bounds: java.io.InputStream,com.github.dockerjava.api.async.ResultCallback<com.github.dockerjava.api.model.Frame>
    lower bounds: com.github.dockerjava.core.command.AttachContainerResultCallback
Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44
  • Why not 3.2.12? Because 3.2.7 was the latest when I started. I am not a prgrammer (I'm a HW engineer) and so have been making slow progress. I have managed to make some changes (they compile, but I have no idea whether they work or not, yet.) But I have been looking for days now (on and off), to find some method that returns an InputStream . But there doesn't seem to be one. There also seems to be very little documentation. I don't understand how I'd be able to work this out even if I were a programmer. – Matthew Taylor Nov 17 '21 at 13:59

1 Answers1

1

Try it:

    var outputStream = new PipedOutputStream();
    var inputStream = new PipedInputStream(outputStream);

    var response =
            dockerClient.attachContainerCmd(container.getId())
                    .withLogs(false)
                    .withStdErr(true)
                    .withStdOut(true)
                    .withFollowStream(true)
                    .exec(new ResultCallback.Adapter<>() {
                        @Override
                        public void onNext(Frame object) {
                            System.out.println(object);  //for example
                            try {
                                outputStream.write(object.getPayload());
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    });

    try {
        response.awaitCompletion();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

Variable inputStream will be what you are looking for. P.S. In my case I do withLogs(false) because it blocks the current output and I get only part of the log. It probably has something to do with the container I'm connecting to.