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);
^
Gradle can be integrated with many different third-party tools such as IDEs and continuous integration platforms.
Android Gradle plugin requires Java 11 to run.
wheres Gradle is a build system that packages the code for you and makes it ready for compilation. If you take an example from android, under the hood, Gradle downloads the defined dependencies and packages everything for you without messing up and simplifies the development flow.
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:
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
@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.)
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):
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.com.vinaysshenoy.types.Types
has a static import of com.vinaysshenoy.types.util.Util.GenericArrayTypeImpl
, so the compiler looks at the nested GenericArrayTypeImpl
class.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With