Skip to content
This repository has been archived by the owner on Mar 21, 2022. It is now read-only.

version 8.9.1 (and 8.9.2-SNAPSHOT) shaded jar not working #900

Closed
sanjaypujare opened this issue Oct 4, 2017 · 4 comments · Fixed by #922
Closed

version 8.9.1 (and 8.9.2-SNAPSHOT) shaded jar not working #900

sanjaypujare opened this issue Oct 4, 2017 · 4 comments · Fixed by #922
Labels

Comments

@sanjaypujare
Copy link
Contributor

Description

I used 8.9.1 (or 8.9.2-SNAPSHOT version built locally from latest sources) shaded jar but it is not working. Could this be caused by the relocation added for glassfish jar? What's the solution/workaround?

How to reproduce

Used the following test to verify:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.log4j.Level;
import org.apache.log4j.LogManager;

import com.spotify.docker.client.DefaultDockerClient;
import com.spotify.docker.client.DockerClient;
import com.spotify.docker.client.DockerClient.LogsParam;
import com.spotify.docker.client.LogStream;
import com.spotify.docker.client.exceptions.DockerCertificateException;
import com.spotify.docker.client.exceptions.DockerException;
import com.spotify.docker.client.messages.ContainerConfig;
import com.spotify.docker.client.messages.ContainerCreation;
import com.spotify.docker.client.messages.ContainerInfo;
import com.spotify.docker.client.messages.HostConfig;
import com.spotify.docker.client.messages.PortBinding;

public class DockerClientTest2
{
  private static final Logger log = LoggerFactory.getLogger(DockerClientTest2.class);
  
  public static void main(String[] args) throws DockerCertificateException, DockerException, InterruptedException
  {
  //Create a client based on DOCKER_HOST and DOCKER_CERT_PATH env vars
    LogManager.getRootLogger().setLevel(Level.INFO);
    final DockerClient docker = DefaultDockerClient.fromEnv().build();
    
   // final DockerClient docker = DefaultDockerClient.builder().
    
 // Pull an image
    docker.pull("hello-world:latest");

    // Bind container ports to host ports
    final String[] ports = {"80", "23"};
    final Map<String, List<PortBinding>> portBindings = new HashMap<>();
    for (String port : ports) {
      List<PortBinding> hostPorts = new ArrayList<>();
      hostPorts.add(PortBinding.of("0.0.0.0", port));
      portBindings.put(port, hostPorts);
    }

    // Bind container port 443 to an automatically allocated available host port.
    List<PortBinding> randomPort = new ArrayList<>();
    randomPort.add(PortBinding.randomPort("0.0.0.0"));
    portBindings.put("443", randomPort);

    final HostConfig hostConfig = HostConfig.builder().portBindings(portBindings).build();

    // Create container with exposed ports
    final ContainerConfig containerConfig = ContainerConfig.builder()
        .hostConfig(hostConfig)
        .image("hello-world:latest").exposedPorts(ports)
        .cmd("/hello")
        .build();

    final ContainerCreation creation = docker.createContainer(containerConfig);
    final String id = creation.id();

    // Inspect container
    final ContainerInfo info = docker.inspectContainer(id);

    // Start container
    docker.startContainer(id);

    LogStream logStream = docker.logs(id, LogsParam.stdout());

    log.info(logStream.readFully());

    // Kill container
    docker.killContainer(id);

    // Remove container
    docker.removeContainer(id);

    // Close the docker client
    docker.close();
    
  }
}

What do you expect

Expected the test to succeed (as it does with my own docker-client library which is 8.9.0 plus my own changes which are present in 8.9.1) and produce output from hello-world:latest

What happened instead

I see the following console output/trace:

Oct 03, 2017 5:17:29 PM com.spotify.docker.client.shaded.org.glassfish.hk2.utilities.reflection.Logger warning
WARNING: Cannot find a default implementation of the HK2 ServiceLocatorGenerator
Exception in thread "main" java.lang.RuntimeException: java.lang.ClassNotFoundException: Provider com.spotify.docker.client.shaded.org.glassfish.jersey.internal.RuntimeDelegateImpl could not be instantiated: java.lang.IllegalStateException: No generator was provided and there is no default generator registered
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:152)
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:120)
	at com.spotify.docker.client.shaded.javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:95)
	at com.spotify.docker.client.shaded.javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:106)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.client.JerseyWebTarget.<init>(JerseyWebTarget.java:81)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:297)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:76)
	at com.spotify.docker.client.DefaultDockerClient.resource(DefaultDockerClient.java:2599)
	at com.spotify.docker.client.DefaultDockerClient.pull(DefaultDockerClient.java:1239)
	at com.spotify.docker.client.DefaultDockerClient.pull(DefaultDockerClient.java:1224)
	at com.spotify.docker.client.DefaultDockerClient.pull(DefaultDockerClient.java:1218)
	at com.datatorrent.gateway.DockerClientTest2.main(DockerClientTest2.java:39)
Caused by: java.lang.ClassNotFoundException: Provider com.spotify.docker.client.shaded.org.glassfish.jersey.internal.RuntimeDelegateImpl could not be instantiated: java.lang.IllegalStateException: No generator was provided and there is no default generator registered
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.FactoryFinder.newInstance(FactoryFinder.java:122)
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.FactoryFinder.find(FactoryFinder.java:225)
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:135)
	... 11 more
Caused by: java.lang.IllegalStateException: No generator was provided and there is no default generator registered
	at com.spotify.docker.client.shaded.org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.internalCreate(ServiceLocatorFactoryImpl.java:308)
	at com.spotify.docker.client.shaded.org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.create(ServiceLocatorFactoryImpl.java:293)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.internal.inject.Injections._createLocator(Injections.java:138)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.internal.inject.Injections.createLocator(Injections.java:109)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.internal.RuntimeDelegateImpl.<init>(RuntimeDelegateImpl.java:63)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.FactoryFinder.newInstance(FactoryFinder.java:118)
	... 13 more

Software:

  • docker version:
Client:
 Version:      17.06.1-ce
 API version:  1.30
 Go version:   go1.8.3
 Git commit:   874a737
 Built:        Thu Aug 17 22:53:38 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.06.1-ce
 API version:  1.30 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   874a737
 Built:        Thu Aug 17 22:54:55 2017
 OS/Arch:      linux/amd64
 Experimental: true
  • Spotify's docker-client version: 8.9.1

Full backtrace

Oct 03, 2017 5:17:29 PM com.spotify.docker.client.shaded.org.glassfish.hk2.utilities.reflection.Logger warning
WARNING: Cannot find a default implementation of the HK2 ServiceLocatorGenerator
Exception in thread "main" java.lang.RuntimeException: java.lang.ClassNotFoundException: Provider com.spotify.docker.client.shaded.org.glassfish.jersey.internal.RuntimeDelegateImpl could not be instantiated: java.lang.IllegalStateException: No generator was provided and there is no default generator registered
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:152)
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:120)
	at com.spotify.docker.client.shaded.javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:95)
	at com.spotify.docker.client.shaded.javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:106)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.client.JerseyWebTarget.<init>(JerseyWebTarget.java:81)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:297)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:76)
	at com.spotify.docker.client.DefaultDockerClient.resource(DefaultDockerClient.java:2599)
	at com.spotify.docker.client.DefaultDockerClient.pull(DefaultDockerClient.java:1239)
	at com.spotify.docker.client.DefaultDockerClient.pull(DefaultDockerClient.java:1224)
	at com.spotify.docker.client.DefaultDockerClient.pull(DefaultDockerClient.java:1218)
	at com.datatorrent.gateway.DockerClientTest2.main(DockerClientTest2.java:39)
Caused by: java.lang.ClassNotFoundException: Provider com.spotify.docker.client.shaded.org.glassfish.jersey.internal.RuntimeDelegateImpl could not be instantiated: java.lang.IllegalStateException: No generator was provided and there is no default generator registered
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.FactoryFinder.newInstance(FactoryFinder.java:122)
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.FactoryFinder.find(FactoryFinder.java:225)
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:135)
	... 11 more
Caused by: java.lang.IllegalStateException: No generator was provided and there is no default generator registered
	at com.spotify.docker.client.shaded.org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.internalCreate(ServiceLocatorFactoryImpl.java:308)
	at com.spotify.docker.client.shaded.org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.create(ServiceLocatorFactoryImpl.java:293)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.internal.inject.Injections._createLocator(Injections.java:138)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.internal.inject.Injections.createLocator(Injections.java:109)
	at com.spotify.docker.client.shaded.org.glassfish.jersey.internal.RuntimeDelegateImpl.<init>(RuntimeDelegateImpl.java:63)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at com.spotify.docker.client.shaded.javax.ws.rs.ext.FactoryFinder.newInstance(FactoryFinder.java:118)
	... 13 more

@bjcohen
Copy link

bjcohen commented Oct 19, 2017

I'm also having this issue. It seems to be an issue with a provider-configuration file that's included as part of HK2 -- since HK2 is shaded, the provider interface is relocated but the provider configuration is not. Specifically, if I include a provider-configuration file com.spotify.docker.client.shaded.org.glassfish.hk2.extension.ServiceLocatorGenerator that points to the correct provider implementation, I no longer get this error.

This issue is known to the Maven developers but not prioritized: https://issues.apache.org/jira/browse/MSHADE-221. ServicesResourceTransformer unfortunately does not help with this particular case. I'm not sure what course the library authors would prefer (custom Shade transformer, hack the relocated provider-configuration into the library resources, etc) but the user workaround exists as well.

@mhagnumdw
Copy link

@bjcohen What correct provider implementation? Tks!

@bjcohen
Copy link

bjcohen commented Oct 23, 2017

@mhagnumdw I created a file called com.spotify.docker.client.shaded.org.glassfish.hk2.extension.ServiceLocatorGenerator with the line org.jvnet.hk2.external.generator.ServiceLocatorGeneratorImpl in the META-INF/services directory (see https://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html) for more info.

geowarin added a commit to geowarin/docker-junit-rule that referenced this issue Nov 13, 2017
(it now works on mac with docker for mac)

Fix #10, fix #8

We no longer use the shaded version of the jar because of
spotify/docker-client#900.
davidxia added a commit that referenced this issue Nov 13, 2017
and use ServicesResourceTransformer to relocate class names in
META-INF/services/.

fixes #900
@davidxia
Copy link
Contributor

@mhagnumdw @bjcohen @sanjaypujare Can you test out #922?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants