Guava classes are copied to my "classes" folder

I see google guava’s classes in my productmodel/build/classes/main folder when I execute “gradle compileJava”:

  • com/google/common/annotations

  • com/google/common/base

  • com/google/common/collect

while I’d only expect to see my own classes in this folder.

These Guava files end up in -warfile-/WEB-INF/lib/productmodel.jar. While I also have -warfile-/WEB-INF/lib/guava-12.0.jar and I’d expect the Google Guava classes to be loaded from there.

so why are these Google Guava classes copied to my “classes” folder? why only them and not all the other libraries I’m using?

my productmodel/build.gradle:

import org.apache.tools.ant.filters.ReplaceTokens
  apply plugin: 'war'
  def gwtVersion = '2.4.0'
def gwtModules = ['ProductModel']
def gwtStartupUrls = ['/']
  dependencies {
    compile project(':common')
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
//
  compile group: 'com.google.guava', name: 'guava-gwt', version: '12.0'
    // DO NOT use the latest 2011.1.297684 version: it leads to GWT application deadlock on startup!
    compile group: 'com.perforce', name: 'p4java', version: '2010.1.269249'
      def slf4j_version = "1.6.6"
      // Compile GWT libs, needed for gwtCompile and the javaCompile
    // Also includes the servlet-api
    providedCompile "com.google.gwt:gwt-user:$gwtVersion"
    providedCompile "com.google.gwt:gwt-dev:$gwtVersion"
      // Needed for GWT compile and at runtime for RequestBuilder
    // Specify two artifacts as workaround for GRADLE-1934
    compile('javax.validation:validation-api:1.0.0.GA') {
        artifact {
            name = 'validation-api'
            type = 'jar'
        }
        artifact {
            name = 'validation-api'
            type = 'jar'
            classifier = 'sources'
        }
    }
      // Runtime GWT libraries, should be included in WAR
    runtime 'com.google.gwt:gwt-servlet:2.4.0'
    runtime 'org.json:json:20090211'
      compile(
            ["com.sencha.gxt:gxt:3.0.4"],
            ["com.google.gwt:gwt-user:$gwtVersion"],
            ["com.google.gwt:gwt-servlet:$gwtVersion"],
            ["com.allen-sauer.gwt.log:gwt-log:3.1.8"],
            ["com.allen-sauer.gwt.dnd:gwt-dnd:3.1.2"],
              ["com.google.code.gson:gson:2.2.2"],
            ["org.slf4j:slf4j-api:$slf4j_version"],
            // Use jdk1.4 logging with SLF4J
            ["org.slf4j:slf4j-log4j12:$slf4j_version"],
            ["log4j:log4j:1.2.16"],
            //Jbcrypt is used to encrypt users' passwords.
            ["org.mindrot:jbcrypt:0.3m"],
            ["com.googlecode.json-simple:json-simple:1.1"],
            ["com.mycompany.pc:pc-pm-client:8.0.0"]
    )
      testCompile(
            ["org.easytesting:fest-assert:1.4"],
            ["org.mockito:mockito-core:1.9.5"]
    )
}
  // read environment variables, including variables passed by jenkins continuous integration server
def env = System.getenv()
def buildNumber = env.BUILD_NUMBER
     // set by Jenkins server
  if (buildNumber) {
    println "Found build number (usually set by Jenkins): $buildNumber. Will add it to the version info."
} else {
    buildNumber = ""
}
  processResources {
    // Uncomment this to force "processResources" step even if there are no modified files.
    // This is useful if you want to force Gradle to update version.properties file.
    // outputs.upToDateWhen { false }
    filter ReplaceTokens, tokens: [
            timestamp: new Date().dateTimeString,
            build_number: buildNumber
    ]
}
  def buildDir = "${project.buildDir}/gwt"
def extraDir = "${project.buildDir}/extra"
  task compileGwt(dependsOn: classes, type: JavaExec) {
      inputs.source sourceSets.main.java.srcDirs
    inputs.dir sourceSets.main.output.resourcesDir
    outputs.dir buildDir
      // Workaround for incremental build (GRADLE-1483)
    outputs.upToDateSpec = new org.gradle.api.specs.AndSpec()
      doFirst {
        file(buildDir).mkdirs()
    }
      main = 'com.google.gwt.dev.Compiler'
      classpath {
        [
                sourceSets.main.java.srcDirs,
         // Java source
                sourceSets.main.output.resourcesDir,
  // Generated resources
                sourceSets.main.output.classesDir,
    // Generated classes
                sourceSets.main.compileClasspath,
     // Deps
        ]
    }
      args =
        [
                'com.mycompany.abc.ProductModel', // Your GWT module
                '-war', buildDir,
                '-logLevel', 'INFO',
                '-localWorkers', '2',
                '-style', 'DETAILED',
                '-compileReport',
                '-extra', extraDir,
                // '-draftCompile' // Speeds up compile with 25%
        ]
      maxHeapSize = '1000M'
}
  // pack the classes into the Jar file
jar.enabled = true
  war.dependsOn compileGwt
war {
    baseName = PD_WAR_FILE_NAME_PREFIX
    from buildDir
    classpath = jar.outputs.files + configurations.runtime - configurations.providedRuntime
}

my common/build.gradle:

dependencies {
    compile group: 'com.google.guava', name: 'guava-gwt', version: '12.0'
}

my root level build.gradle:

subprojects {
      apply plugin: 'java'
      sourceCompatibility = 1.7
      repositories {
        ................
    }
      dependencies {
        testCompile 'junit:junit:4.11'
    }
}

root level settings.gradle:

include "common", "launcher", "productmodel"

Not sure why this would be happening.

Can you please try reproducing with a small, simple, build that I can also run?

I reproduced it with some minimal configuration with just 1 java class in 1 module. how can I send you the ZIP file?

here’s my only java class:

mymodule/src/main/java/my/shared/sevice/AppVersionBuilder.java:

package my.shared.service;
  import com.google.common.base.Strings;
  public class AppVersionBuilder {
  public static String getFullVersionString() {
    String fullString = "stub here";
    if (!Strings.isNullOrEmpty(fullString)
            && !"@build_number@".equals(fullString)) {
      fullString += "-" + fullString;
    }
    return fullString;
  }
}

settings.gradle:

include "mymodule"

mymodule/build.gradle:

apply plugin: 'war'
  dependencies {
    compile group: 'com.google.guava', name: 'guava-gwt', version: '12.0'
}

Do some of the (Guava) Jars on your compile class path (additionally) contain Java sources? Note that javac will, by default, compile source files found on its compile class path just like “regular” source files.

yes, I see guava-gwt-12.0.jar has some java source files in it. same with guava-gwt-14.0.1.jar (both loaded from Maven Central).

what can we do to avoid having those Guava classes in our jar file?

Try ‘compileJava.options.compilerArgs = ["-implicit:none"]’.

this helped, thank you!