chrome-devtools-java-client
chrome-devtools-java-client copied to clipboard
ChromeDevTools hangs indefinately when running inside a Docker Container.
Ok, this is a wierd one. I've spent an entire day trying to figure out what's going on. I am using ChromedevTools to get the source code of a page once I get a "firstMeaningfulPaint".
The code snippet is as follows:
final ChromeLauncher launcher = new ChromeLauncher();
final ChromeService chromeService = launcher.launch(chromeArguments);
log.info(String.format("Entering chromeStrategy for %s", link.getUrl()));
final Instant startTime = Instant.now();
final ChromeTab tab = chromeService.createTab();
final ChromeDevToolsService devToolsService = chromeService.createDevToolsService(tab);
final var latch = new CountDownLatch(1);
final var page = devToolsService.getPage();
page.setLifecycleEventsEnabled(true);
page.onLifecycleEvent(x -> {
log.info(String.format("Got event from chrome: %s", x.getName()));
if (x.getName().equals(LATCH_NAME)) {
latch.countDown();
}
});
page.enable();
final var dom = devToolsService.getDOM();
dom.enable();
final var network = devToolsService.getNetwork();
network.enable();
network.setBypassServiceWorker(true);
network.setCacheDisabled(true);
var blah = Try.of(() -> page.navigate(link.getUrl()))
.andThenTry(() -> latch.await(10, TimeUnit.SECONDS))
.mapTry(x -> dom.getOuterHTML());
chromeService.closeTab(tab);
launcher.close();
devToolsService.waitUntilClosed();
Now here comes the really strange part. When I try this from my local machine, either with gradle or IntelliJ it works fine. When I try it in a docker container it dies after a few tries.
Yourkit reports the following stackframes, which don't really mean that much to me:
jdk.internal.misc.Unsafe.park(boolean, long) Unsafe.java (native)
java.util.concurrent.locks.LockSupport.park(Object) LockSupport.java:194
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt() AbstractQueuedSynchronizer.java:885
java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(int) AbstractQueuedSynchronizer.java:1039
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(int) AbstractQueuedSynchronizer.java:1345
java.util.concurrent.CountDownLatch.await() CountDownLatch.java:232
com.github.kklisura.cdt.services.impl.ChromeDevToolsServiceImpl$InvocationResult.waitForResult(long, TimeUnit) ChromeDevToolsServiceImpl.java:396
com.github.kklisura.cdt.services.impl.ChromeDevToolsServiceImpl.invoke(String, Class, MethodInvocation) ChromeDevToolsServiceImpl.java:138
com.github.kklisura.cdt.services.invocation.CommandInvocationHandler.invoke(Object, Method, Object[]) CommandInvocationHandler.java:80
com.sun.proxy.$Proxy129.getOuterHTML()
Mostly it hangs, but sometimes it crashes with the following stacktrace:
java.lang.IllegalStateException: The connection has been closed.
at org.glassfish.tyrus.core.TyrusSession.checkConnectionState(TyrusSession.java:530) ~[tyrus-core-1.13.1.jar:na]
at org.glassfish.tyrus.core.TyrusSession.getBasicRemote(TyrusSession.java:212) ~[tyrus-core-1.13.1.jar:na]
at com.github.kklisura.cdt.services.impl.WebSocketServiceImpl.send(WebSocketServiceImpl.java:114) ~[cdt-java-client-1.3.3.jar:na]
at com.github.kklisura.cdt.services.impl.ChromeDevToolsServiceImpl.invoke(ChromeDevToolsServiceImpl.java:135) ~[cdt-java-client-1.3.3.jar:na]
at com.github.kklisura.cdt.services.invocation.CommandInvocationHandler.invoke(CommandInvocationHandler.java:80) ~[cdt-java-client-1.3.3.jar:na]
at com.sun.proxy.$Proxy129.getOuterHTML(Unknown Source) ~[na:na]
Whether it works, hangs or crashes does not seem to be deterministic, or rather I have not been able to determine the cause. Any help is appreciated. I'm using the openjdk:11.0.1-slim Docker image.
@FlameDuck could be because of insufficient shmSize parameter set to Docker container (Docker default is 64M, reasonable value for Chrome - 256M).
I had the same issue and fixed it by setting shm_size: 1gb.