arquillian / arquillian-cube

Control (docker, kubernetes, openshift) containers in your tests with ease!
http://arquillian.org/arquillian-cube/
121 stars 98 forks source link

Cube Docker depends on Jersey, but if my test already depends on RESTEasy, everything breaks #879

Open Ladicek opened 6 years ago

Ladicek commented 6 years ago
Issue Overview

Cube Docker depends the docker-java library for talking to the Docker daemon, and that in turn depends on Jersey.

However, if my test already depends on RESTEasy for various reasons (in my case, I'm starting the Keycloak Docker container and the keycloak-admin-client library uses RESTEasy to talk to the Keycloak server), things break.

Basically, I have two implementations of JAX-RS [Client] on classpath and suffering from dependency hell.

I don't think there's a "proper" solution, but ... dare I say ... uberjar?

Expected Behaviour

Able to use RESTEasy in a test with Arquillian Cube Docker.

Current Behaviour

Not able to use RESTEasy in a test with Arquillian Cube Docker.

Steps To Reproduce
  1. git clone https://github.com/Ladicek/cube-docker-example
  2. mvn clean test

The commit history in that repo might be informative too.

Additional Information

The output of the commands above clearly shows that RESTEasy is used, which docker-java isn't prepared for:

<details>
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running cz.ladicek.KeycloakTest
Lis 28, 2017 12:38:41 ODP. org.arquillian.spacelift.Spacelift$SpaceliftInstance <init>
INFO: Initialized Spacelift from defaults, workspace: /home/lthon/projects/cube-docker-example, cache: /home/lthon/.spacelift/cache
CubeDockerConfiguration: 
  serverUri = unix:///var/run/docker.sock
  tlsVerify = false
  dockerServerIp = localhost
  definitionFormat = CUBE
  clean = false
  removeVolumes = true
  dockerContainers = containers:
  keycloak:
    alwaysPull: false
    await: {match: 'WFLYSRV0025: Keycloak', occurrences: 1, stdErr: false, stdOut: true,
      strategy: log, timeout: 600}
    env: [KEYCLOAK_USER=admin, KEYCLOAK_PASSWORD=admin]
    image: jboss/keycloak:2.5.5.Final
    killContainer: false
    manual: false
    portBindings: [8180->8080/tcp]
    readonlyRootfs: false
    removeVolumes: true
networks: {}

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.865 sec <<< FAILURE!
cz.ladicek.KeycloakTest  Time elapsed: 0.865 sec  <<< ERROR!
java.lang.RuntimeException: Could not auto start container keycloak
        at org.arquillian.cube.docker.impl.client.CubeSuiteLifecycleController.waitForCompletion(CubeSuiteLifecycleController.java:107)
        at org.arquillian.cube.docker.impl.client.CubeSuiteLifecycleController.startAllSteps(CubeSuiteLifecycleController.java:80)
        at org.arquillian.cube.docker.impl.client.CubeSuiteLifecycleController.startAutoContainers(CubeSuiteLifecycleController.java:57)
        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.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:86)
        at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:103)
        at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:90)
        at org.jboss.arquillian.test.impl.TestContextHandler.createSuiteContext(TestContextHandler.java:69)
        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.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:86)
        at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:95)
        at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:133)
        at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:105)
        at org.jboss.arquillian.test.impl.EventTestRunnerAdaptor.beforeSuite(EventTestRunnerAdaptor.java:70)
        at org.jboss.arquillian.junit.Arquillian.run(Arquillian.java:103)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
        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.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.arquillian.cube.spi.CubeControlException: Could not create keycloak
        at org.arquillian.cube.spi.CubeControlException.failedCreate(CubeControlException.java:15)
        at org.arquillian.cube.docker.impl.model.DockerCube.create(DockerCube.java:117)
        at org.arquillian.cube.impl.client.CubeLifecycleController.create(CubeLifecycleController.java:15)
        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.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:86)
        at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:103)
        at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:90)
        at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:133)
        at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:105)
        at org.jboss.arquillian.core.impl.EventImpl.fire(EventImpl.java:62)
        at org.arquillian.cube.docker.impl.client.CubeSuiteLifecycleController$StartCubes.call(CubeSuiteLifecycleController.java:146)
        at org.arquillian.cube.docker.impl.client.CubeSuiteLifecycleController$StartCubes.call(CubeSuiteLifecycleController.java:130)
        at org.jboss.arquillian.core.impl.threading.ThreadedExecutorService$ContextualCallable.call(ThreadedExecutorService.java:88)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        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)
Caused by: javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request
        at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:287)
        at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:436)
        at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:471)
        at org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.post(ClientInvocationBuilder.java:201)
        at com.github.dockerjava.jaxrs.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:34)
        at com.github.dockerjava.jaxrs.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:15)
        at com.github.dockerjava.jaxrs.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:23)
        at com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:35)
        at com.github.dockerjava.core.command.CreateContainerCmdImpl.exec(CreateContainerCmdImpl.java:177)
        at org.arquillian.cube.docker.impl.docker.DockerClientExecutor.createContainer(DockerClientExecutor.java:510)
        at org.arquillian.cube.docker.impl.model.DockerCube.create(DockerCube.java:109)
        ... 18 more
Caused by: org.apache.http.client.ClientProtocolException
        at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:867)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
        at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:283)
        ... 28 more
Caused by: org.apache.http.HttpException: Scheme 'unix' not registered.
        at org.apache.http.impl.conn.DefaultHttpRoutePlanner.determineRoute(DefaultHttpRoutePlanner.java:109)
        at org.apache.http.impl.client.DefaultRequestDirector.determineRoute(DefaultRequestDirector.java:762)
        at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:381)
        at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
        ... 31 more
</details>
lordofthejars commented 6 years ago

This issue is not under our control sadly it is a requirement from docker-java project to use Jersey. I am not sure exactly how to find a clean solution for that. Obviously we will need some kind of classpath isolation but currently I am not totally aware a possible solution for this case.

Ladicek commented 6 years ago

Yea I'm not asking for a solution right here right now. This specific case is a test suite where we use the Fabric8 Docker Maven plugin to run Docker containers and wanted to move to Cube. We'll keep using the Maven plugin for the time being, so it's not blocking us in any way.