docker-maven-plugin: docker-maven-plugin hangs when waiting for log

I configured mysql image to wait for log with a timeout. It was able to match the pattern from the log. However it got stuck cleaning up the connection afterwards.

Everything works if I remove the log wait.

  • d-m-p version : 0.21.0
  • Maven version: 3.3.9
  • Docker version : 17.03.1-ce-win12 (12058)

Pom:

                                <image>
                                    <name>mysql/mysql-server:5.7</name>

                                        <wait>
                                            <log>MySQL init process done. Ready for start up.</log>
                                            <time>60000</time>
                                        </wait>
                                    </run>
                                </image>

Maven log:

[DEBUG] Releasing connection 
[DEBUG] Connection can be kept alive indefinitely
[DEBUG] Cancelling request execution
[DEBUG] http-outgoing-4: Shutdown connection

Thread dump:

"main" #1 prio=5 os_prio=0 tid=0x000000000332e800 nid=0x26cc in Object.wait() [0x000000000315d000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at sun.nio.ch.NativeThreadSet.signalAndWait(NativeThreadSet.java:101)
	- locked <0x000000076f1f1c50> (a sun.nio.ch.NativeThreadSet)
	at sun.nio.ch.FileChannelImpl.implCloseChannel(FileChannelImpl.java:130)
	at java.nio.channels.spi.AbstractInterruptibleChannel.close(AbstractInterruptibleChannel.java:115)
	- locked <0x000000076f1f1c40> (a java.lang.Object)
	at io.fabric8.maven.docker.access.hc.win.NamedPipe.close(NamedPipe.java:255)
	at org.apache.http.impl.BHttpConnectionBase.shutdown(BHttpConnectionBase.java:311)
	at org.apache.http.impl.conn.DefaultManagedHttpClientConnection.shutdown(DefaultManagedHttpClientConnection.java:97)
	at org.apache.http.impl.conn.LoggingManagedHttpClientConnection.shutdown(LoggingManagedHttpClientConnection.java:100)
	at org.apache.http.impl.execchain.ConnectionHolder.abortConnection(ConnectionHolder.java:127)
	- locked <0x000000076f1ea858> (a org.apache.http.impl.conn.LoggingManagedHttpClientConnection)
	at org.apache.http.impl.execchain.ConnectionHolder.cancel(ConnectionHolder.java:145)
	at org.apache.http.client.methods.AbstractExecutionAwareRequest.abort(AbstractExecutionAwareRequest.java:90)
	at io.fabric8.maven.docker.access.log.LogRequestor.finish(LogRequestor.java:228)
	- locked <0x000000076f0142d0> (a java.lang.Object)
	at io.fabric8.maven.docker.wait.LogWaitChecker.cleanUp(LogWaitChecker.java:49)
	at io.fabric8.maven.docker.wait.WaitUtil.cleanup(WaitUtil.java:80)
	at io.fabric8.maven.docker.wait.WaitUtil.wait(WaitUtil.java:64)
	at io.fabric8.maven.docker.service.WaitService.wait(WaitService.java:53)
	at io.fabric8.maven.docker.StartMojo$1.call(StartMojo.java:249)
	at io.fabric8.maven.docker.StartMojo$1.call(StartMojo.java:235)
	at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:108)
	at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:41)
	at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:77)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at com.google.common.util.concurrent.MoreExecutors$DirectExecutorService.execute(MoreExecutors.java:310)
	at java.util.concurrent.ExecutorCompletionService.submit(ExecutorCompletionService.java:181)
	at io.fabric8.maven.docker.StartMojo.startImage(StartMojo.java:235)
	at io.fabric8.maven.docker.StartMojo.executeInternal(StartMojo.java:132)
	- locked <0x000000076e96f3b8> (a io.fabric8.maven.docker.StartMojo)
	at io.fabric8.maven.docker.AbstractDockerMojo.execute(AbstractDockerMojo.java:223)
	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
	at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
	at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
	at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
	at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
	at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
	at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
	at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
	at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
	at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
	at org.codehaus.classworlds.Launcher.main(Launcher.java:47)

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 2
  • Comments: 25 (1 by maintainers)

Most upvoted comments

@rhuss I seem to be stuck with a similar problem under Windows, with dmp 0.27.2 and Oracle JDK 8.171 (works fine in a jenkins-slim Docker container with OpenJDK 8.181).

The behaviour is the following:

. DMP starts the container . DMP finds the log ([INFO] DOCKER> Pattern '<my pattern>' matched for container 34100e85616e . DMP just waits, not finishing…

Windows 10 Java: Oracle JDK 8.171 Maven 3.5.3 DMP 0.27.2

The tip that @artnaseef posted gave me some direction into a workaround, yet unfortunately setting the environment variable didn’t do anything towards my Docker server. What did work is adding the following to the configuration of the docker-maven-plugin to my pom.xml:

<configuration>
	<dockerHost>tcp://localhost:2375</dockerHost>
</configuration>

Please do make sure that you enable the TCP daemon in the Docker for Windows settings.

Thanks for you investigation ! I hope I have time to jump onto this evergreen issue over the x-mas break (but no promise 😦

We have the same problem.

  • only happens on Windows, Linux is fine
  • d-m-p at least 0.27.2 and 0.31.0 broken
  • d-m-p 0.24.0 is working

config snippet:

                        <image>
                            <name
                            <run>

                                <wait>
                                    <log>started successfully</log>
                                    <time>30000</time>
                                </wait>
                            </run>
                        </image>

It even recognizes the pattern but hangs. Removing log and only using time works. log, hangs at that line:

[INFO] --- docker-maven-plugin:0.31.0:start (setup-it-dependencies) @ service ---
[INFO] DOCKER> [service-image] "service": Start container 4a9e2d814dbf
[INFO] DOCKER> Pattern 'started successfully' matched for container 4a9e2d814dbf

I dug through the stack trace provided and the related code. It looks like the issue is related to handling of the file channel. Details follow…

The “main” thread is doing this:

at java.lang.Object.wait(Native Method)
- waiting on <0x0000000786794c00> (a sun.nio.ch.NativeThreadSet)
at sun.nio.ch.NativeThreadSet.signalAndWait(NativeThreadSet.java:101)
- locked <0x0000000786794c00> (a sun.nio.ch.NativeThreadSet)
at sun.nio.ch.FileChannelImpl.implCloseChannel(FileChannelImpl.java:130)
  1. Looking at the code for NativeThreadSet.signalAndWait, it appears this is waiting until all threads are removed from its set (see the NativeThreadSet snippet below).
  2. Looking at the code for FileChannelImpl, it appears the thread set is being used to track all uses of the file channel (see the FileChannelImpl.java snippet below).
  3. Calls to FileChannelImpl’s read(...) and write(...) methods (and others) call threads.add() and threads.remove()
  4. Thread “Thread-1” is calling sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:159), therefore holding a place in the thread set. This traces back to io.fabric8.maven.docker.access.hc.win.NamedPipe$1.read(NamedPipe.java:118)
  5. Thread “main” is calling NativeThreadSet.signalAndWait(NativeThreadSet.java:101). This traces back to io.fabric8.maven.docker.access.log.LogRequestor.finish(LogRequestor.java:228)

So - given all of this, I believe the attempt to close the named pipe in LogRequestor.finish() needs to make sure that all other threads listening to the same log are terminated, or it needs to not attempt to close the named pipe. I haven’t taken the time to dig through that code, so the solution is unclear. What does seem clear based on this - it is not a JDK bug.

NativeThreadSet.java snippet (https://github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/nio/ch/NativeThreadSet.java)

    synchronized void signalAndWait() {
        boolean interrupted = false;
        while (used > 0) {
            int u = used;
            int n = elts.length;
            for (int i = 0; i < n; i++) {
                long th = elts[i];
                if (th == 0)
                    continue;
                if (th != -1)
                    NativeThread.signal(th);
                if (--u == 0)
                    break;
            }
            waitingToEmpty = true;
            try {
                wait(50);                             //// <<<< this is line 101
            } catch (InterruptedException e) {
                interrupted = true;
            } finally {
                waitingToEmpty = false;
            }
        }
        if (interrupted)
            Thread.currentThread().interrupt();
    }

FileChannelImpl.java snippet ()

        // signal any threads blocked on this channel
        threads.signalAndWait();                      //// <<<< this is line 130

Hi, try using 0.24.0 version. Probably due to https://github.com/fabric8io/docker-maven-plugin/pull/904 being lost in further updates.

Also running into this issue after migrating from Docker Toolbox to Docker Desktop: the plugin hangs after the pattern has been matched.

In case this helps in determining the root cause: the pattern I’m waiting for indicates the container has been started successfully, and is the last line in the log file (at that moment). However, when I invoke an operation on the application that generates an additional log message, the process unblocks and the plugin continues again as normal.

The suggested workaround with DOCKER_HOST=tcp://localhost:2375 also fixes the problem for me, however the Docker Desktop warning for enabling this is quite scary.

image

@ostecke’s workaround works well but as this is an environmental issue I’d suggest putting it in an automatically activated profile in the settings.xml file so that you don’t have to modify project pom.xml files:

<!--
 | Direct the docker-maven-plugin to connect to the Docker Host using TCP.
-->
<profile>
    <id>set-docker-host</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <docker.host>tcp://localhost:2375</docker.host>
    </properties>
</profile>
</profiles>

I have the same problem using OSX and java version “1.8.0_162” On our CI-servers with version 1.8.0_131 there is no problem.