Cannot compile a java library with Gradle, works with the IDE

gradle java-library example
gradle dependencies
gradle build library jar with dependencies
gradle build jar without dependencies
gradle unable to resolve dependency intellij
gradle tutorial
create java library intellij
gradle download

I’m running into a weird problem when I try to build my project via Gradle.

The build works fine when I import the project into IntelliJ and build/run tests via the IDE. However, if I run ./gradlew test, the build fails and it’s unable to resolve symbols in the JDK (like GenericArrayType).

If I delegate IntelliJ’s build/run actions to Gradle, I see the same problems in my IDE as well, so something seems to be up with my Gradle build, and I can’t figure out what. Other projects work fine, so it seems to be a problem with this specific project.

I have tried this on different machines (one running Ubuntu and the other running macOS) as well as different Gradle versions (4.10.2, 5.1.1), but the problem persists. I copied and pasted the source code to another project that already works perfectly fine, and then it started failing with the same errors as well, when I ran the unit tests.

Can someone help me figure out what’s going wrong here?

Here's what my settings.gradle looks like:

rootProject.name = 'types'

And build.gradle:

group 'com.vinaysshenoy'
version '1.0.0'

buildscript {
  ext.junit_version = '4.12'
  ext.assertj_version = '3.11.1'
  ext.jsr305_version = '3.0.2'

  repositories {
    mavenCentral()
  }
}

apply plugin: 'java-library'

java {
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8
}

repositories {
  mavenCentral()
}

dependencies {
  implementation "com.google.code.findbugs:jsr305:$jsr305_version"
  testImplementation "junit:junit:$junit_version"
  testImplementation "org.assertj:assertj-core:$assertj_version"
}

Here's what I see when I run it via the command line:

      public static final class GenericArrayTypeImpl implements GenericArrayType {
                                                                ^
      symbol:   class GenericArrayType
      location: class Util
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:230: error: cannot find symbol
      public static final class ParameterizedTypeImpl implements ParameterizedType {
                                                                 ^
      symbol:   class ParameterizedType
      location: class Util
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:340: error: cannot find symbol
      public static final class WildcardTypeImpl implements WildcardType {
                                                            ^
      symbol:   class WildcardType
      location: class Util
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/Types.java:54: error: incompatible types: ParameterizedTypeImpl cannot be converted to ParameterizedType
        return new ParameterizedTypeImpl(null, rawType, typeArguments);
               ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/Types.java:63: error: incompatible types: ParameterizedTypeImpl cannot be converted to ParameterizedType
        return new ParameterizedTypeImpl(ownerType, rawType, typeArguments);
               ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/Types.java:68: error: incompatible types: GenericArrayTypeImpl cannot be converted to GenericArrayType
        return new GenericArrayTypeImpl(componentType);
               ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/Types.java:78: error: incompatible types: WildcardTypeImpl cannot be converted to WildcardType
        return new WildcardTypeImpl(new Type[] { bound }, EMPTY_TYPE_ARRAY);
               ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/Types.java:86: error: incompatible types: WildcardTypeImpl cannot be converted to WildcardType
        return new WildcardTypeImpl(new Type[] { Object.class }, new Type[] { bound });
               ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/Types.java:153: error: incompatible types: ParameterizedType cannot be converted to ParameterizedTypeImpl
          Type[] aTypeArguments = pa instanceof ParameterizedTypeImpl
                                  ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/Types.java:154: error: incompatible types: ParameterizedType cannot be converted to ParameterizedTypeImpl
              ? ((ParameterizedTypeImpl) pa).typeArguments
                                         ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/Types.java:156: error: incompatible types: ParameterizedType cannot be converted to ParameterizedTypeImpl
          Type[] bTypeArguments = pb instanceof ParameterizedTypeImpl
                                  ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/Types.java:157: error: incompatible types: ParameterizedType cannot be converted to ParameterizedTypeImpl
              ? ((ParameterizedTypeImpl) pb).typeArguments
                                         ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:52: error: incompatible types: bad type in conditional expression
          return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType())) : c;
                               ^
        GenericArrayTypeImpl cannot be converted to Type
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:55: error: incompatible types: Type cannot be converted to ParameterizedTypeImpl
          if (type instanceof ParameterizedTypeImpl) { return type; }
              ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:57: error: incompatible types: ParameterizedTypeImpl cannot be converted to Type
          return new ParameterizedTypeImpl(p.getOwnerType(),
                 ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:61: error: incompatible types: Type cannot be converted to GenericArrayTypeImpl
          if (type instanceof GenericArrayTypeImpl) { return type; }
              ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:63: error: incompatible types: GenericArrayTypeImpl cannot be converted to Type
          return new GenericArrayTypeImpl(g.getGenericComponentType());
                 ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:66: error: incompatible types: Type cannot be converted to WildcardTypeImpl
          if (type instanceof WildcardTypeImpl) { return type; }
              ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:68: error: incompatible types: WildcardTypeImpl cannot be converted to Type
          return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds());
                 ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:118: error: incompatible types: bad type in conditional expression
                ? new ParameterizedTypeImpl(newOwnerType, original.getRawType(), args)
                  ^
        ParameterizedTypeImpl cannot be converted to Type
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:260: error: method does not override or implement a method from a supertype
        @Override
        ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:265: error: method does not override or implement a method from a supertype
        @Override
        ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:270: error: method does not override or implement a method from a supertype
        @Override
        ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:279: error: incompatible types: ParameterizedTypeImpl cannot be converted to Type
              && Types.equals(this, (ParameterizedType) other);
                              ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:313: error: method does not override or implement a method from a supertype
        @Override
        ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:321: error: incompatible types: GenericArrayTypeImpl cannot be converted to Type
              && Types.equals(this, (GenericArrayType) o);
                              ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:363: error: method does not override or implement a method from a supertype
        @Override
        ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:368: error: method does not override or implement a method from a supertype
        @Override
        ^
    /Users/vinay/Dev/IdeaProjects/types/src/main/java/com/vinaysshenoy/types/util/Util.java:376: error: incompatible types: WildcardTypeImpl cannot be converted to Type
              && Types.equals(this, (WildcardType) other);
                          ^
Solution

@Zgurskyi’s answer is a good workaround, however, I believe it only cures the symptom of the actual problem (see below). Here’s another, IMHO cleaner way to fix the underlying issue: make the imports of the nested types of com.vinaysshenoy.types.util.Util from com.vinaysshenoy.types.Types non-static:

diff --git a/src/main/java/com/vinaysshenoy/types/Types.java b/src/main/java/com/vinaysshenoy/types/Types.java
index e3a44d8..92ac237 100644
--- a/src/main/java/com/vinaysshenoy/types/Types.java
+++ b/src/main/java/com/vinaysshenoy/types/Types.java
@@ -17,9 +17,9 @@ package com.vinaysshenoy.types;


 import static com.vinaysshenoy.types.util.Util.EMPTY_TYPE_ARRAY;
-import static com.vinaysshenoy.types.util.Util.GenericArrayTypeImpl;
-import static com.vinaysshenoy.types.util.Util.ParameterizedTypeImpl;
-import static com.vinaysshenoy.types.util.Util.WildcardTypeImpl;
+import com.vinaysshenoy.types.util.Util.GenericArrayTypeImpl;
+import com.vinaysshenoy.types.util.Util.ParameterizedTypeImpl;
+import com.vinaysshenoy.types.util.Util.WildcardTypeImpl;
 import static com.vinaysshenoy.types.util.Util.getGenericSupertype;
 import static com.vinaysshenoy.types.util.Util.resolve;

(BTW, other than @Zgurskyi I can also reproduce this with a manual javac call. I only have one JDK installed; maybe @Zgurskyi’s javac on the command line is not from the same JDK that Gradle uses.)

Actual Problem

You statically import nested classes (not just class members), although this should never be necessary. I’m actually surprised that this seems to usually work, but apparently some Java compilers at least choke on it under certain circumstances.

In your case, the Java compiler used by Gradle couldn’t correctly resolve the imports in the following scenario (only a rough, not very technical description of what the compiler does):

  1. when processing com.vinaysshenoy.types.util.Util, the compiler finds a static import of com.vinaysshenoy.types.Types.arrayOf, so the compiler looks at the com.vinaysshenoy.types.Types class.
  2. com.vinaysshenoy.types.Types has a static import of com.vinaysshenoy.types.util.Util.GenericArrayTypeImpl, so the compiler looks at the nested GenericArrayTypeImpl class.
  3. com.vinaysshenoy.types.util.Util.GenericArrayTypeImpl uses (java.lang.reflect.)GenericArrayType, however, the import for that type was not yet processed at this point which leads to the "cannot find symbol" error.

Arguably, it could also be considered to be a JDK bug that this works with some compilers but not with others.

Not able to create JAR file for gradle project, I was using 'gradle clean' and 'gradle build' instead of 'gradlew clean' and ' gradlew build'. gradlew commands worked for me. I am working with a Java project that has a large number of local dependencies. My library folder is in the following format: projectroot\lib\com\google\code\gson\gson\2.8.0\gson-2.8.0.jar projectr

In order to build the project, use fully qualified names for implemented interfaces for static nested classes defined in com.vinaysshenoy.types.util.Util:

  public static final class ParameterizedTypeImpl implements java.lang.reflect.ParameterizedType { ... }

  public static final class GenericArrayTypeImpl implements java.lang.reflect.GenericArrayType { ... }

  public static final class WildcardTypeImpl implements java.lang.reflect.WildcardType { ... }

Also, if you don't want to use fully qualified names, then just extract static nested classes to top level.

Notes:

  1. The project compiles without errors, when JDK compiler is used:
javac -cp path_to_jsr305-3.0.2.jar -d bin src/main/java/com/vinaysshenoy/types/Types.java src/main/java/com/vinaysshenoy/types/util/Util.java
  1. This problem seems to be dependent on platform. I've tried to build project on Windows 10/Oracle JDK 1.8.0_111 - and no issues were observed. However, the issue reproduced exactly as described on Ubuntu 16.04/Oracle JDK 1.8.0_201 & Ubuntu 16.04/OpenJDK 1.8.0_191.

Cannot compile a java library with Gradle, works with the IDE, Cannot compile a java library with Gradle, works with the IDE. Vis Team Februari 03, 2019. I'm running into a weird problem when I try to build my project via� In External Libraries in my project I can see (which is located in my local maven repo) External Libraries <1.8> /Library/Java/.. Gradle: com.foo:cordapp-settlement:0.1 cordapp-settlement-0.1.jar com.foo.analytics state SettlementInstruction. However in the IDE Editor I have the following

Building Java Libraries, You'll generate a Java library that follows Gradle's conventions. A text editor or IDE Gradle comes with a built-in plugin called the Build Init plugin. To confirm that these changes work as expected, run the jar task again, and this time also� The Android Gradle plugin provides built-in support for using certain Java 8 language features and third-party libraries that use them. As shown in figure 1, the default toolchain implements the new language features by performing bytecode transformations, called desugar , as part of the D8/R8 compilation of class files into dex code.

after having built the project, I've come to a whole other conclusion: it seems the system-wide JDK has corrupted files - and that it works with the IDE, that is because it uses an embedded version.

in case Gradle cannot use that JDK, it can be defined in the gradle.properties file (the path to the IDE's embedded JDK should work, better than the one installed system-wide, as used by default):

# replace this path with the path to the IDE's embedded JDK:
org.gradle.java.home = /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home

... and this should already make it build.

Gradle resolve dependecies and build/run fine but IntelliJ does not , It has to build with gradle and from the command line, it works fine, both build and . Please restart IntelliJ IDEA The problem in the project is that when I am writing the java code the parser resolves all the classes, however, at the moment of But the external libraries are resolved and installed by gradle. Gradle Inc., the company behind the Gradle build framework provides Gradle tooling for the Eclipse IDE. This tooling allows to create and import Gradle enabled projects into the Eclipse IDE. It also allows to run Gradle tasks and monitor it execution.

Getting Started, This guide walks you through using Gradle to build a simple Java project. A favorite text editor or IDE Either way, you end up with working code. At this point, the project doesn't have any library dependencies, so there's nothing in the � Generate a Java library, learn how it is structured. Adapt the generated build.gradle and sample Java files. Run the build and view the test report. Customize the name of the JAR file and the content of its manifest. Generate API documentation, including making a JAR for it

Using the Gradle build system in the Eclipse IDE - Tutorial, This triggers the gradle init --type java-library command and imports the project. Press the Next > button to get a� Isolate and simplify code for determining the current version and name. This is now located in 'module-identity', defining a plugin that is. individually applied by all subproject

The Gradle build system- Tutorial, A task represents a piece of work which a build performs, e.g., compile the Other IDEs like IntelliJ and Android Studio already include also good Gradle support. The usage of Gradle requires an JDK (Java Development Kit) installation. Without additional parameters, this task creates a Gradle project, which contains the gradle wrapper files, a build.gradle and settings.gradle file. When adding the --type parameter with 'java-library' as value, a java project structure is created and the build.gradle file contains a certain Java template with JUnit.

Comments
  • Downloading your project and running it as is with ./gradlew, both ./gradlew build and ./gradlew test run successfully. (just to let you know that at another machine it seems to work correctly)
  • Thank you for the detailed write-up! This stupefied me for a week! Weird that this isn't flagged as an error or something in the IDE.
  • i can confirm that by changing the final class declarations the build works fine on mac too.
  • Whoa, I didn't know this could be a problem. I shall try this out in a few hours when I get back home from work and see!
  • This fixed the problem, but @chriki has a far more detailed answer, so I am going to award the bounty to them. Thanks for your help!
  • This was something that I thought of, and running echo $JAVA_HOME does output a path: /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home.
  • Does 'java -version' work in console?
  • Yes. It prints java version "1.8.0_181" as expected.
  • The 'java' command is part of the JRE and does not indicate any presence of the JDK. javac -version on the other hand would at least confirm the presence of the JDK, but not if JAVA_HOME was properly set. @VinaySShenoy: can you check for the presence of the 'bin' and 'lib' folders within the path you posted in the commend, and also check if the javac executable is present in the 'bin' folder?
  • Yes, the javac command is present and prints javac 1.8.0_181 too. The bin and lib folders are present as well.