Gradle Build Failure: Couldn't find outer class - gradle

When trying to build, I get this stacktrace:
Exception in thread "main" java.lang.NullPointerException: Couldn't find outer class com/xxx/CheckListPresenter$onAttached$1$5 of com/xxx/CheckListPresenter$onAttached$1$5$1
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:1079)
at com.google.devtools.build.android.desugar.ClassVsInterface.isOuterInterface(ClassVsInterface.java:56)
at com.google.devtools.build.android.desugar.InterfaceDesugaring.visitOuterClass(InterfaceDesugaring.java:246)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:638)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
at com.google.devtools.build.android.desugar.Desugar.desugarClassesInInput(Desugar.java:477)
at com.google.devtools.build.android.desugar.Desugar.desugarOneInput(Desugar.java:361)
at com.google.devtools.build.android.desugar.Desugar.desugar(Desugar.java:314)
at com.google.devtools.build.android.desugar.Desugar.main(Desugar.java:711)
I checked the CheckListPresenter class and there doesn't appear to have any issues. I tried deleting the class just to see if it would build, but the error just moved on to another class stating the same issue.
The last time I touched this code was a good few months ago, so I am not sure what triggered the change.
Things that may matter: This is an Android project. This is written in Kotlin. This fails on the transformClassesWithDesugarForDebug gradle task
Edits
These are all just stabs in the dark I tried:
Creating a new project and moving in only my source code and gradle files.
Dropping from java 8 to 7.
Different version of JDK. I have tried 1.8.0_151 and 1.8.0_152.
Adding javaMaxHeapSize "4g" to build.gradle.
Upgrading everything: gradle wrapper and every dependency.
Removed Dagger in favor of Koin
Removed Kapt
Used both Preview and Stable releases of Android Studio
Here is my build scan for what good it will do
New discovery:
This is the snippet of code that is killing me:
view?.let { v ->
v.getCancelClicks()
.doOnSubscribe({ disposables.add(it) })
.subscribe({
v.showExitDialog()
.filter { it }
.subscribe({
cancel()
}, this::onError)
}, this::onError)
}
What is strange, is neither one of these alone will give me issues
view?.let { v ->
v.getCancelClicks()
.doOnSubscribe({ disposables.add(it) })
.subscribe({
//removed
}, this::onError)
}
}
or
view?.let { v ->
v.showExitDialog()
.filter { it }
.subscribe({
cancel()
}, this::onError)
}
But together they are a problem.
Something else of note, view is defined in the base class and is a generic.
Currently, my work around is to remove view?.let{ and just use view!!. This is obviously a bug, but I am not sure who to report it to. Gradle, Kotlin, JetBrains, God?

The problem resolved itself when I added android.enableD8.desugaring = true to gradle.properties

I have a way to work around this error: java.lang.NullPointerException: Couldn't find outer class com/iconfitness/iconaudit/common/fragments/SettingsFragment$onCreate$1$1 of com/iconfitness/iconaudit/common/fragments/SettingsFragment$onCreate$1$1$1.
Just move this block code
v.showExitDialog()
.filter { it }
.subscribe({
cancel()
oo other method. I don't meet this problem anymore. I hope this will help you.

The issue is filed here https://issuetracker.google.com/issues/72750890.
Both solutions mentioned there worked for me:
adding classpath 'com.android.tools.build:gradle:3.0.1' to build.gradle or adding android.enableD8.desugaring=true to gradle.properties

As a workaround you can substitute let by null checking. At least code started to compile after this
if (view!=null)
view.showExitDialog()
.filter { it }
.subscribe({
cancel()
}, this::onError)
}

Related

Configuring a custom Gradle sourceSet using a closure

I'm trying to develop a Gradle plugin for a language I use (SystemVerilog). I'm still experimenting and figuring things out. Before I write the entire thing as a plugin, I thought it would be best to try out the different parts I need inside a build script, to get a feel of how things should work.
I'm trying to define a container of source sets, similar to how the Java plugin does it. I'd like to be able to use a closure when configuring a source set. Concretely, I'd like to be able to do the following:
sourceSets {
main {
sv {
include '*.sv'
}
}
}
I defined my own sourceSet class:
class SourceSet implements Named {
final String name
final ObjectFactory objectFactory
#Inject
SourceSet(String name, ObjectFactory objectFactory) {
this.name = name
this.objectFactory = objectFactory
}
SourceDirectorySet getSv() {
SourceDirectorySet sv = objectFactory.sourceDirectorySet('sv',
'SystemVerilog source')
sv.srcDir("src/${name}/sv")
return sv
}
SourceDirectorySet sv(#Nullable Closure configureClosure) {
configure(configureClosure, getSv());
return this;
}
}
I'm using org.gradle.api.file.SourceDirectorySet because that already implements PatternFilterable, so it should give me access to include, exclude, etc.
If I understand the concept correctly, the sv(#Nullable Closure configureClosure) method is the one that gives me the ability to write sv { ... } to configure via a closure.
To add the sourceSets property to the project, I did the following:
project.extensions.add("sourceSets",
project.objects.domainObjectContainer(SourceSet.class))
As per the Gradle docs, this should give me the possibility to configure sourceSets using a closure. This site, which details using custom types, states that by using NamedDomainObjectContainer, Gradle will provide a DSL that build scripts can use to define and configure elements. This would be the sourceSets { ... } part. This should also be the sourceSets { main { ... } } part.
If I create a sourceSet for main and use it in a task, then everything works fine:
project.sourceSets.create('main')
task compile(type: Task) {
println 'Compiling source files'
println project.sourceSets.main.sv.files
}
If I try to configure the main source set to only include files with the .sv extension, then I get an error:
sourceSets {
main {
sv {
include '*.sv'
}
}
}
I get the following error:
No signature of method: build_47mnuak4y5k86udjcp7v5dkwm.sourceSets() is applicable for argument types: (build_47mnuak4y5k86udjcp7v5dkwm$_run_closure1) values: [build_47mnuak4y5k86udjcp7v5dkwm$_run_closure1#effb286]
I don't know what I'm doing wrong. I'm sure it's just a simple thing that I'm forgetting. Does anyone have an idea of what that might be?
I figured out what was going wrong. It was a combination of poor copy/paste skills and the fact that Groovy is a dynamic language.
First, let's look at the definition of the sv(Closure) function again:
SourceDirectorySet sv(#Nullable Closure configureClosure) {
configure(configureClosure, getSv());
return this;
}
Once I moved this code to an own Groovy file and used the IDE to show me what is getting called, I noticed that it wasn't calling the function I expected. I was expecting a call to org.gradle.util.ConfigureUtil.configure. Since this is part of the public API, I expected it to be imported by default in the build script. As this page states, this is not the case.
To solve the issue, it's enough to add the following import:
import static org.gradle.util.ConfigureUtil.configure
This will get rid of the cryptic closure related error. It is replaced by the following error, though:
Cannot cast object 'SourceSet_Decorated#a6abab9' with class 'SourceSet_Decorated' to class 'org.gradle.api.file.SourceDirectorySet'
This is caused by the copy/paste error I mentioned. When I wrote the SourceSet class, I drew heavily from org.gradle.api.tasks.SourceSet (and org.gradle.api.internal.tasks.DefaultSourceSet). If we look at the java(Closure) method there, we'll see it has the following signature:
SourceSet java(#Nullable Closure configureClosure);
Notice that it returns SourceSet and not SourceDirectorySet like in my code. Using the proper return type fixes the issue:
SourceSet sv(#Nullable Closure configureClosure)
With this new return type, let's look again at the configuration code for the source set:
sourceSets {
main {
sv {
include '*.sv'
}
}
}
Initially, I thought it was supposed to work as follows: pass main { ... } as a Closure to sourceSets, pass sv { ... } as a Closure to main, and handle the include ... part inside sourceDirectorySet. I banged my head against the wall for a while, because I couldn't find any code in that class hierarchy that takes closures like this.
Now, I think the flow is slightly different: pass main { ... } as a Closure to sourceSets (as initially thought), but call the sv(Closure) function on main (of type sourceSet), passing it { include ... } as the argument.
Bonus: There was one more issue that wasn't related to the "compile" errors I was having.
Even after getting the code to run without errors, it still wasn't behaving as expected. I had some files with the *.svh extension that were still getting picked up. This is because, when calling getSv(), it was creating a new SourceDirectorySet each time. Any configuration that was done previously was getting thrown away each time that this function was called.
Making the sourceDirectorySet a class member and moving its creation to the constructor fixed the issue:
private SourceDirectorySet sv
SourceSet(String name, ObjectFactory objectFactory) {
// ...
sv = objectFactory.sourceDirectorySet('sv',
'SystemVerilog source')
sv.srcDir("src/${name}/sv")
}
SourceDirectorySet getSv() {
return sv
}

How can I fix Unresolved reference: Gson?

I'm trying to follow a tutorial about Android application. I'm using an dependency Fuel (which has a dependency to com.google.Gson deserializer). But Gson() is not imported by IDE.
I've tried to specify lower version of gson. I've re-synchronized all project gradle. I've tried to write import manually (import com.google.gson.Gson), but I can't use Gson() constructor. I've read manual about using Gson, but nothing seem to be changed. It's always the same way. Call constructor Gson() and after all static method... Gson().fromJson(....)
Here is section in my build.gradle (module:app)
// Fuel HTTP Client
implementation 'com.github.kittinunf.fuel:fuel:2.2.0'
implementation 'com.github.kittinunf.fuel:fuel-android:2.2.0'
implementation 'com.github.kittinunf.fuel:fuel-gson:2.2.0'
and In code, I'm using in ArticleDataProvider.kt:
class WikipediaDataDeserializer : ResponseDeserializable<WikiResults> {
override fun deserialize(reader: Reader): WikiResults? {
return Gson().fromJson(reader, WikiResults::class.java)
}
}
Normally, I would to have Gson() recognised by IDE and I wound be able to call .fromJson() normally. Gradle was downloaded properly. (I don't have any message error about).
Using this Lib in your gradle:
dependencies{
implementation 'com.google.code.gson:gson:2.8.2'
}
The problem is probably in dependency of fuel-gson:2.2.0
To bypass it, I added a new dependency to my build.gradle manually and problem is solved.
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
}
Its may happen due to different versions of gson in External Libraries. To resolve it I have added following resolveStrategy in app module build.gradle.
configurations.all {
resolutionStrategy.preferProjectModules()
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.google.code.gson') {
details.useVersion "2.8.5"
}
}
}

Find all tasks associated with buildType?

I am using the android experimental plugin 0.4 ( gradle 2.8 ) and would like to modify all tasks that are associated with a buildType; debug in my case.
Currently, I am using the following "hack":
tasks.all {
if( it.name.contains("Debug") ) {
print it.name
}
}
Is there a more typesafe way ?
I don't know much about this specific plugin, but a better way to do this with the Gradle API might be:
tasks.withType(AndroidTask).all {
print it.name
}
Where AndroidTask is a Class reference. You'll have to look at the sources of the plugin to figure out the exact class. They also provide tasks.matching {}. Check out the TaskCollection GroovyDocs for specific usage.

How do I compile against local file in gradle?

For each sub-project in our build, we have a structure like this:
apply from: '../dependencies.gradle'
dependencies {
... omitting other dependencies ...
compile libraries.poi
}
These libraries are defined in dependencies.gradle, which looks like this:
ext.libraries = [
... omitting other libraries ...
poi: [
'poi:poi:3.9.custom.1',
'poi:poi-ooxml:3.9.custom.1',
'poi:poi-ooxml-schemas:3.9.custom.0',
'poi:poi-scratchpad:3.9.custom.0',
],
... omitting other libraries ...
]
A few days ago I wanted to try something against a nightly build of POI. Nightly builds don't go into their repository, so I'm forced to try and get it to work with local files.
Looking in the docs, you're supposed to use files(...) for this, so I tried this:
poi: [
files('/path/to/poi-3.14-beta1/poi-3.14-beta1-20151027.jar'),
files('/path/to/poi-3.14-beta1/poi-3.14-ooxml-20151027.jar'),
files('/path/to/poi-3.14-beta1/poi-3.14-ooxml-schemas-20151027.jar'),
files('/path/to/poi-3.14-beta1/poi-3.14-scratchpad-20151027.jar'),
],
When I run this, I get an error:
* What went wrong:
A problem occurred evaluating root project 'product'.
> Cannot convert the provided notation to an object of type ModuleVersionSelector: file collection.
The following types/formats are supported:
- Instances of ModuleVersionSelector.
- String or CharSequence values, for example 'org.gradle:gradle-core:1.0'.
- Maps, for example [group: 'org.gradle', name:'gradle-core', version: '1.0'].
- Collections or arrays of any other supported format. Nested collections/arrays will be flattened.
So really it seems like files() does not actually work, as it doesn't return one of the things listed here.
What is the correct way to do it? (Assuming it's even possible!)
Edit: More information
Now that I updated to Gradle 2.8, I get a line number pointing at the problem. It points at some custom build code which we put in to work around Gradle sucking at dependency resolution:
resolutionStrategy {
libraries.each {
libraryName, libraryList ->
libraryList.each {
library -> force library // 👈 this line
}
}
failOnVersionConflict()
}
So I take it the problem is that force doesn't support all the same things that other methods support?
My crap workaround for a workaround is to filter out elements of type FileCollection:
resolutionStrategy {
libraries.each { libraryName, libraryList ->
[libraryList].flatten()
.findAll { library ->
!(library instanceof FileCollection)
}
.each { library -> force library }
}
failOnVersionConflict()
}
Maybe there is a better way.

Gradle plugin for XML Beans

I am trying to write a Gradle plugin for XML Beans. I have started with one of the 'Hello from Gradle' plugin examples, and also a plugin published by R. Artavia here. That plugin went straight to jar - I am trying to only generate source. The generated source must then be compiled with other project source and included in a single jar. Other goals include
- full plugin - all I should need is "apply plugin: 'xmlbean'"
- I can configure source/code gen location and some features if I want to
- It detects whether it needs to be rebuilt. (well, eventually!!!)
I am off to a pretty good start, but am blocked defining a new sourceSet. I am getting an error "No such property 'srcDirs'" (or 'srcDir'). It seems there is something I have to define someplace to make a new sourceSet work but I cannot find it. I have tried several different syntaxes (with/without equal sign, brackets, srcDir/srcDirs, etc. - nothing is working...
What do I need to do inside a plugin to make a new sourceSet entry be properly recognized?
Thank you!
JKE
File: xmlbean.gradle (includes greeting plugin for the moment for debugging)
apply plugin: xmlbean
apply plugin: 'java'
xmlbean {
message = 'Hi'
greeter = 'Gradle'
}
class xmlbean implements Plugin<Project> {
void apply(Project project) {
project.extensions.create("xmlbean", xmlbeanExtension)
Task xmlbeanTask = project.task('xmlbean')
xmlbeanTask << {
project.configurations {
xmlbeans
}
project.dependencies {
xmlbeans 'org.apache.xmlbeans:xmlbeans:2.5.0'
}
project.sourceSets {
main {
java {
srcDirs += '$project.buildDir/generated-source/xmlbeans'
}
}
xmlbeans {
srcDirs = ['src/main/xsd']
}
}
ant.taskdef(name: 'xmlbean',
classname: 'org.apache.xmlbeans.impl.tool.XMLBean',
classpath: project.configurations.xmlbeans.asPath)
ant.xmlbean(schema: project.sourceSets.xmlbean.srcDir,
srconly: true,
srcgendir: "$project.buildDir/generated-sources/xmlbeans",
classpath: project.configurations.xmlbeans.asPath)
println "${project.xmlbean.message} from ${project.xmlbean.greeter}"
}
project.compileJava.dependsOn(xmlbeanTask)
}
}
class xmlbeanExtension {
String message
String greeter
}
File: build.gradle
apply from: '../gradle/xmlbeans.gradle'
dependencies {
compile "xalan:xalan:$ver_xalan",
":viz-common:0.0.1",
":uform-repository:0.1.0"
}
Console: Error message:
:idk:xmlbean FAILED
FAILURE: Build failed with an exception.
* Where:
Script 'C:\jdev\cpc-maven\try.g2\comotion\gradle\xmlbeans.gradle' line: 32
* What went wrong:
Execution failed for task ':idk:xmlbean'.
> No such property: srcDirs for class: org.gradle.api.internal.tasks.DefaultSourceSet_Decorated
...
BUILD FAILED
Gradle info: version 2.5 / groovy 2.3.10 / JVM 7u55 on Windows 7 AMD64
You should try to become familiar with the Gradle DSL reference guide, because it's a huge help in situations like this. For example, if you click on the sourceSets { } link in the left navigation bar, you're taken to this section on source sets.
From there, you'll discover that the sourceSets {} block is backed by a class, SourceSetContainer. The next level of configuration nested inside is backed by a SourceSet object, and then within that you have one or more SourceDirectorySet configurations. When you follow the link to SourceDirectorySet, you'll see that there are getSrcDirs() and setSrcDirs() methods.
So how does this help? If you look closely at the exception, you'll see that Gradle is saying it can't find a srcDirs property on DefaultSourceSet_Decorated, which you can hopefully infer is an instance of SourceSet. That interface does not have an srcDirs property. That's because your xmlbeans {} block is configuring a SourceSet, not a SourceDirectorySet. You need to add another nested configuration to gain access to srcDirs.
At this point, I'm wondering whether a new source set is the appropriate solution. Unfortunately it's not clear to me exactly what the plugin should be doing, so I can't offer any alternatives at this point.

Resources