Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-36779

Upgrade Guava or properly isolate core Guava dependency from plugins

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Resolved (View Workflow)
    • Priority: Major
    • Resolution: Fixed
    • Component/s: core
    • Labels:
      None
    • Similar Issues:
    • Released As:
      2.320

      Description

      For a while, we could use a newer version of Guava in a plugin than in core - see, for example, jclouds plugin version 2.5, which uses Mask-Classes on the manifestEntries for maven-hpi-plugin to mask com.google.common. That worked fine with core's Guava 11.0 and jclouds' Guava 14.0.1. But moving to a newer jclouds version, with a dependency on Guava 15.0, made things go horribly wrong. I don't remember off the top of my head exactly what went wrong, but I'll reproduce that and add the relevant logs as attachments here. What finally fixed things there was moving to a shaded Guava jar and depending on that - see the state of the code as of here.

      Given that context...I know people are still hitting problems due to Guava incompatibilities - anything with a newer Guava version could fail horribly due to API methods that have since been removed being called by Jenkins itself and borking due to the newer Guava being in the classpath. So something needs to be done here - either better isolation of Guava (either as part of a general improvement to classloader isolation or possibly a more Guava-specific solution) or upgrading Guava...though upgrading Guava means breaking plugins that use/depend on Guava. So...not simple. But some solution is needed eventually.

        Attachments

          Issue Links

            Activity

            Hide
            danielbeck Daniel Beck added a comment -

            Probably best to tackle JENKINS-30685.

            Show
            danielbeck Daniel Beck added a comment - Probably best to tackle JENKINS-30685 .
            Hide
            jglick Jesse Glick added a comment -

            See artifact-manager-s3 #83 for an example (again based on the jclouds library, but not using jclouds-plugin) of a case where the bundled Guava made it impossible to do an otherwise straightforward refactoring.

            Show
            jglick Jesse Glick added a comment - See artifact-manager-s3 #83 for an example (again based on the jclouds library, but not using jclouds-plugin ) of a case where the bundled Guava made it impossible to do an otherwise straightforward refactoring.
            Hide
            cleclerc Cyrille Le Clerc added a comment -

            FYI the requirement of an outdated version of Guava (v11) blocks the usage of gRPC (requires Guava v20) and transitively blocks the usage of the OpenTelemetry SDK (1) to instrument  and observe Jenkins and its jobs.

            (1) the OpenTelemetry SDK requires gRPC for both the official OpenTelemetry Protocol exporter and the Jaeger exporter

            Error message happening with all the grpc libs: grpc-okhttp, grpc-netty and grpc-shded-netty: 

            java.lang.NoSuchMethodError: 'void com.google.common.base.Preconditions.checkArgument(boolean, java.lang.String, char, java.lang.Object)'
                    at io.grpc.Metadata$Key.validateName(Metadata.java:742)
                    at io.grpc.Metadata$Key.<init>(Metadata.java:750)
                    at io.grpc.Metadata$Key.<init>(Metadata.java:668)
                    at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:959)
                    at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:954)
                    at io.grpc.Metadata$Key.of(Metadata.java:705)
                    at io.grpc.Metadata$Key.of(Metadata.java:701)
                    at io.grpc.internal.GrpcUtil.<clinit>(GrpcUtil.java:81)
                    at io.grpc.netty.shaded.io.grpc.netty.Utils.<clinit>(Utils.java:77)
                    at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.<clinit>(NettyChannelBuilder.java:79)
                    at io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForTarget(NettyChannelProvider.java:42)
                    at io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForTarget(NettyChannelProvider.java:23)
                    at io.grpc.ManagedChannelBuilder.forTarget(ManagedChannelBuilder.java:76)
                    at io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder.build(OtlpGrpcSpanExporterBuilder.java:105)
            
            

            See https://guava.dev/releases/20.0/api/docs/com/google/common/base/Preconditions.html#checkArgument-boolean-java.lang.String-char-java.lang.Object-

            Show
            cleclerc Cyrille Le Clerc added a comment - FYI the requirement of an outdated version of Guava (v11) blocks the usage of gRPC (requires Guava v20) and transitively blocks the usage of the OpenTelemetry SDK (1) to instrument  and observe Jenkins and its jobs. (1) the OpenTelemetry SDK requires gRPC for both the official OpenTelemetry Protocol exporter and the Jaeger exporter Error message happening with all the grpc libs: grpc-okhttp, grpc-netty and grpc-shded-netty:  java.lang.NoSuchMethodError: 'void com.google.common.base.Preconditions.checkArgument( boolean , java.lang. String , char , java.lang. Object )' at io.grpc.Metadata$Key.validateName(Metadata.java:742) at io.grpc.Metadata$Key.<init>(Metadata.java:750) at io.grpc.Metadata$Key.<init>(Metadata.java:668) at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:959) at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:954) at io.grpc.Metadata$Key.of(Metadata.java:705) at io.grpc.Metadata$Key.of(Metadata.java:701) at io.grpc.internal.GrpcUtil.<clinit>(GrpcUtil.java:81) at io.grpc.netty.shaded.io.grpc.netty.Utils.<clinit>(Utils.java:77) at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.<clinit>(NettyChannelBuilder.java:79) at io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForTarget(NettyChannelProvider.java:42) at io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForTarget(NettyChannelProvider.java:23) at io.grpc.ManagedChannelBuilder.forTarget(ManagedChannelBuilder.java:76) at io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder.build(OtlpGrpcSpanExporterBuilder.java:105) See  https://guava.dev/releases/20.0/api/docs/com/google/common/base/Preconditions.html#checkArgument-boolean-java.lang.String-char-java.lang.Object-
            Hide
            jglick Jesse Glick added a comment -

            As shown in artifact-manager-s3, it is possible to use a newer Guava version from a plugin, but it is not straightforward.

            Show
            jglick Jesse Glick added a comment - As shown in artifact-manager-s3 , it is possible to use a newer Guava version from a plugin, but it is not straightforward.
            Hide
            cleclerc Cyrille Le Clerc added a comment -

            Thanks Jesse Glick, your solution works. My pom.xml includes:

            <dependencies>
                <dependency> <!-- see maskClasses config -->
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                    <version>20.0</version>
                </dependency>
                ...
            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.jenkins-ci.tools</groupId>
                        <artifactId>maven-hpi-plugin</artifactId>
                        <configuration>
                            <!-- JENKINS-50520: since we need a custom version of Guava -->
                            <maskClasses>com.google.common.</maskClasses>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
            
            Show
            cleclerc Cyrille Le Clerc added a comment - Thanks Jesse Glick , your solution works. My pom.xml includes: <dependencies> <dependency> <!-- see maskClasses config --> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>20.0</version> </dependency> ... </dependencies> <build> <plugins> <plugin> <groupId>org.jenkins-ci.tools</groupId> <artifactId>maven-hpi-plugin</artifactId> <configuration> <!-- JENKINS-50520: since we need a custom version of Guava --> <maskClasses>com.google.common.</maskClasses> </configuration> </plugin> </plugins> </build>
            Hide
            teilo James Nord added a comment -

            using a newer Guice using similar tricks however has shown to be a problem -> JENKINS-65757

            Show
            teilo James Nord added a comment - using a newer Guice using similar tricks however has shown to be a problem -> JENKINS-65757
            Hide
            jglick Jesse Glick added a comment -

            Basil Crow I think this can be In Review?

            Show
            jglick Jesse Glick added a comment - Basil Crow I think this can be In Review ?
            Hide
            basil Basil Crow added a comment -

            Indeed it can.

            Show
            basil Basil Crow added a comment - Indeed it can.

              People

              Assignee:
              basil Basil Crow
              Reporter:
              abayer Andrew Bayer
              Votes:
              4 Vote for this issue
              Watchers:
              11 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: