Not able to view Dagger generated classes source code in IDE - android

I'm having trouble seeing the generated dagger classes in my project. The app builds, dagger injects the classes just fine, etc. but I can't actually view the dagger classes in my IDE - they show up as red (indicating an error), and trying to step into the class while debugging and/or viewing the source code to see how they are doing things doesn't work.
Here's a sample project that doesn't work for me: https://github.com/erikcaffrey/Dagger2-MVP-Sample
All I did was pull it, run it, and then went to the CategoryApplication class and tried to see the source for the DaggerAppComponent class, but I am not able to.
For reference, here's what I see:
Some additional information: On other computers I do not have this problem (Windows 10, MacBook Pro #2) but my main development MacBook Pro if affected by this. The dagger generated files exist in my project structure and I can view them manually - but ideally the IDE can pick these up and not show this as an error visually. I am using Android Studio 3.1.4 but this was also occurring in older versions (not sure on the exact numbers though)
The sample project I am using has the following gradle dependencies setup:
annotationProcessor 'com.google.dagger:dagger-compiler:2.15'
implementation 'com.google.dagger:dagger:2.15'
It doe snot use the android dagger components, nor the android support components, FWIW.
Update: I noticed that my Android Studio instance on my dev MacBook Pro does not list the dagger generated files in the app/build/generated/source/apt/ directory when viewing the project files in the 'Project' setting. The files on the hard drive do exist, but they do not show up in the IDE... so I doubt this is a dagger issue - just something wrong with the IDE not picking up these files.

def daggerVer = 2.12 // or latest version
implementation "com.google.dagger:dagger:$daggerVer"
implementation "com.google.dagger:dagger-android-support:$daggerVer"
annotationProcessor "com.google.dagger:dagger-android-processor:$daggerVer"
annotationProcessor "com.google.dagger:dagger-compiler:$daggerVer"

In your build.gradle file, add this line:
dependencies {
apt 'com.google.dagger:dagger-compiler:2.0'
}
which will make the generated sources visible in android studio.

I noticed this was not an issue on Android Studio 3.2 beta, so I figured it was a configuration issue. I went ahead and uninstalled Android Studio and deleted all references to Android Studio from my machine and then reinstalled Android Studio 3.1.4. The issue is no longer occurring.

Related

Android Databinding build fail after Gradle plugin update with migration to annotationProcessor

To support Instant Run in my version of Android Studio, I needed to upgrade my Gradle plugin from version 2.2.3 to 2.3.3
I'm aware I'm supposed to migrate to annoationProcessor and I believe I've followed that guide correctly
after doing so, the Android DataBinding code generation fails
The migration guide linked earlier states that all I need is to
Make sure you are on the Android Gradle 2.2 plugin or newer
Remove the android-apt plugin from your build scripts
Change all apt, androidTestApt and testApt dependencies to their new format
This should be all that's needed to successfully build the project. Yet it doesn't build.
Build output
Gradle build finished with 101 error(s) and 23 warning(s) in 12s 481ms
All of the errors follow the same pattern:
C:\Users...\FooAdapter.java
error: package com.example.app.databinding does not exist
error: cannot find symbol class ItemFooBinding
An interesting message can be found in the build console:
Warning:The following options were not recognized by any processor: '[android.databinding.minApi, android.databinding.enableDebugLogs, android.databinding.sdkDir, android.databinding.bindingBuildFolder, android.databinding.enableForTests, android.databinding.modulePackage, android.databinding.generationalFileOutDir, android.databinding.xmlOutDir, android.databinding.artifactType, android.databinding.printEncodedErrors, android.databinding.isTestVariant]'
I would like to point out that...
I presume I don't have an error in some XML file, binding expression or a naming issue. The same set of sources and XML build when I switch back to the Git branch with the old gradle plugin version (and all of the other source files up-to-date)
I did increase the limit of output build errors as discussed here, although this doesn't seem to be relevant right now, since as you can see, I currently have "only" 101 errors. :)
Additional info
The following diffs show how I've modified my gradle files:
build.gradle DiffChecker link
app/build.gradle DiffChecker link
Also, as a quick overview, here is the list of some of the "more interesting" plugins & libraries used by the project:
Kotlin
Android DataBinding
Realm
Retrofit
Dagger
ButterKnife (I know...)
Multidex Support Library
Does anyone have a clue what could be the issue? Any help or idea will be greatly apprecitated!
I had exactly the same warning. This line in gradle solved the issue:
kapt "com.android.databinding:compiler:3.0.1"
Hopefully, it will help somebody
Update:
3.0.1 is Android Plugin Version.
When you see innumerable build errors mentioning databinding as in this case, the problem usually lies somewhere else. Databinding just gets stopped in its tracks by unrelated build problems and complains exceedingly loudly. The only way to deal with it is to locate the build errors that are not tied to databinding. Once they are fixed, databinding can do its thing again and be silent. Unfortunately you often have to repeat this approach several times until you have found all non-databinding issues. It's an arduous task for sure, but unfortunately there is nothing else you can do until Google manages to provide a saner build environment.
This is the reason why you are advised to increase the build error limit beyond 100 - you would not see the actual errors causing your problems, because they commonly do not show up early in the list.
I will chance a guess - Dagger 2 is a common source of triggering this problem, which could be related to your annotationProcessor change; so look out for Dagger errors. But your issues could be caused by other things, like other annotation processors as you mentioned - you wouldn't know for sure until you diligently dig through your build errors.
It seems it all comes down to my project using Kotlin. Actually we have it mixed: some classes use plain old Java while others are written in Kotlin. An incomplete migration. :)
I assume that without Kotlin, replacing apt with annotationProcessor would be enough and I wouldn't have ran into this issue at all.
Solution
Annotations need to be processed by both annotationProcessor and kapt, which seems to be Kotlin's own annotation processor.
For each Gradle dependency that uses annotations, you should have both of the following in your app-level build.gradle:
annotationProcessor 'com.example.my.library:x.y.z
kapt 'com.example.my.library:x.y.z

Build error with Android Studio 3.0 Canary 4

I am currently in the process of developing an Instant app, for which I have restructured my monolithic app into feature modules.
Everything was up and running till Android Studio canary 3, but after an update to Android Studio Canary 4 my project fails to build with the following error:
A problem was found with the configuration of task ':minimoBase:dataBindingExportBuildInfoDebugAndroidTest'.
> Directory '/Users/nayak.vishal/projectData/minimo_instant_app_project/putica-client-android-
native/minimoBase/build/intermediates/data-binding-info/androidTest/debug'
specified for property 'xmlOutFolder' does not exist.
The following procedure worked as a workaround for this issue:
Execute the following build commands on the gradle command line
1) gradlew clean
2) gradlew :appModule:assembleDebug
here appModule is the name of the app module for building the installable apk
the build is successful and the debug apk generated in the output folder can be installed successfully
3) gradlew :instantAppModule:assembleDebug
here instantAppModule is the name of the instant app module
the build is successful and the instant app apks can be installed and launched via deep link
Once the above command line builds are successful, building via Android Studio Canary 4 also stops throwing the build error.
I got similar error when I turn on data-binding for library module. When I turn it off and move all classes that require data-binding to app module, it works. So I guess there is a problem that DataBinding doesn't work on Library module any more ( Gradle 2.x fine with this).
dataBinding {
enabled = false
}
I am using com.android.tools.build:gradle:3.0.0-alpha5 and Android Studio 3.0 Preview Canary5
UPDATE
Although the original answer worked, I really want to turn on data-binding on my library module, where I implement some base classes using binding technique. I move them back to library module and upgrade kotlin version to the latest one 1.1.3-2. Suddenly it works also. I am not sure which one is the better but both ways work for me.
UPDATE 2
I am using com.android.tools.build:gradle:3.0.0-alpha9 and kotlin 1.1.3-2 at this time and suddenly the problem re-appear.
Now I think the problem doesn't come from Kotlin. My library module turned dataBiding { enabled=true}, but it doesn't have any layout file. I tried to create a fake layout file wrapped by <layout> tag and it works
<?xml version="1.0" encoding="utf-8"?>
<layout>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</layout>
In your gradle.properties file , add the following line
android.enableAapt2=false
Recent versions of AS3.0 switched to using AAPT2 by default.
You can disable AAPT2 in your gradle.propertіes fіle with above mentioned line of code, and continue developing on AS3 canary 4.
This was an issue for me when I had a "base" feature module without any layouts (all my actual layouts are in separate features)
Adding a dummy layout XML file in the base feature (e.g. as base/src/res/layout/dummy.xml) meant the missing directory was created and the app compiled.
(this is using com.android.tools.build:gradle:3.0.0-alpha6)
I've had the same problem, seems like a bug in Canary 4.
For now, as a workaround, I downgraded to Android Studio 3.0.0 Canary 3 (This is an archive of all Android Studio releases) and also downgraded the Android Gradle plugin to 3.0.0-alpha3:
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
...
}
Updated:
Just check the Canary version after update. For that see Android Studio version just above the toolbar (File..Edit..View..line) where name at end like "Canary X".-> X is number like 3,4,5,etc.
For example suppose updated version(X) is 5.
Try to change that classpath in build.gradle(applicationName) to 3.0.0-alpha5 and sync(/Try) again:
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha5'
}
Means that updated version(X):-
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alphaX'
}

Inferring Nullity runs forever

When I select Analyze - Infer nullity... in the android studio menu and select any scope (tried even running on a single file) message pops up and says:
The module ... doesn't refer to the existing 'support-annotations'
library with Android nullity annotations. Would you like to add
dependency now?
I click "OK" and then gradle sync starts and progress bar with "infer nullity annotations" title is shown. Then it runs forever like this
I tried adding manually this in gradle:
compile 'com.android.support:support-annotations:23.4.0'
But still have the same result.
I had the exact same issue, but I managed to solve it by manually adding the newest version of the annotations support library to the project through Android Studio build options (it's found on Build -> Edit Libraries and Dependencies on Mac).
The thing here is that Android Studio will probably give you some kind of a warning if you add a support library whose version number is higher than your target API build, but add it anyway. Not sure why, but that did the trick for me.

Dependency issues in reference project

I have an issue that dependencies of a project that is referenced as a dependency module in my android app seem not to be included into the .apk file of my android application.
Project Setup
Android App (Android studio & gradle)
Java desktop application (IntelliJ/maven/gradle project)
Java model (classes & features used by both android & desktop app)
The "Java model" is added as a dependency to both Android App and Java Desktop application.
When I run the desktop application, the dependencies of the JavaModel are resolved via maven, incuded into the application and everything runs smoothly.
From an Android Studio point of view, I have imported the JavaModel as a module into the android project and gradle is used to resolve the dependencies. I have set up the following gradle files:
Android App "settings.gradle"
include ':app'
include ':JavaModel'
project(':JavaModel').projectDir=new File('../../JavaModel')
Android App "build.gradle"
dependencies {
compile project(':JavaModel')
// and more...
}
Java Model "build.gradle"
dependencies {
compile(
'org.apache.httpcomponents:httpclient:4.4.1'
// and more ...
)
}
Everything compiles just fine without any errors and a .apk can be created and runs on my test device. However, as soon as I access features within the app that are provided by the "Java model" (in this example, I am using the HttpClient class from the org.apache.httpcomponents:httpclient:4.4.1 dependency), I get the following exception:
java.lang.ClassNotFoundException: Didn't find class
"org.apache.http.impl.client.HttpClients"
Plese note that this is just an example case and the issue also occurs with all other dependencies that are only referenced in the "JavaModel", but not in the Android app itself.
It seems to me like the dependencies of the "JavaModel" work just fine at compile time, since everything executes just fine, but are then not included into the .apk file and therefore cause this exeption.
The question is how can I (correctly) make sure that even dependencies of a dependency project are included into the .apk file?
Apache http client conflicts with android one, if you want to use recent one, you need to use android port https://hc.apache.org/httpcomponents-client-4.3.x/android-port.html
Regarding "JavaModel". If dependencies of JavaModel are compile dependencies it all must work fine (assuming dependency does not have fancy code like classloaders)

Mockito + Dexmaker on Android

I am trying to use Mockito in my Android project.
I have found very nice tutorial that deals with it: http://www.paulbutcher.com/2012/05/mockito-on-android-step-by-step/
Basically it uses new version of Mockito + Dexmaker and everything works as expected.
However, when I try to mock some Android specific object i.e:
Context context = mock(Context.class);
I receive this exception:
java.lang.IllegalArgumentException:
dexcache == null (and no default could be found;
consider setting the 'dexmaker.dexcache' system property)
at com.google.dexmaker.DexMaker.generateAndLoad(DexMaker.java:359)
at com.google.dexmaker.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:252)
at com.google.dexmaker.mockito.DexmakerMockMaker.createMock(DexmakerMockMaker.java:54)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
Any idea how to fix it?
From #rjath's comment of #MrChaz's answer, this works better for me:
System.setProperty(
"dexmaker.dexcache",
getInstrumentation().getTargetContext().getCacheDir().getPath());
I put it in my setUp() method.
I've managed to piece together a fix that seems to be working for me.
To the manifest I added read and write external storage.
To the test I added System.setProperty("dexmaker.dexcache", "/sdcard"); to the test.
To the emulator image I added an SD card.
I believe this works because by default mockito tries to use the apps cache directory but I never run an activity so I suspect the directory is never created by the OS
So the problem is with Dexmaker not being able to find the cache path on Android >= 4.3 as other people mentioned and as described in this dexmaker issue.
I went with implementing the workaround in a custom instrumented test runner instead of in every test (or their superclass) setUp(), because it feels a bit less hacky (it really is in only one place - and not inherited in every subclass) and more flexible.
For the sake of documentation these are the necessary changes to do this:
public class CustomInstrumentationTestRunner extends InstrumentationTestRunner {
#Override public void onCreate (final Bundle arguments) {
super.onCreate(arguments);
// temporary workaround for an incompatibility in current dexmaker (1.1) implementation and Android >= 4.3
// cf. https://code.google.com/p/dexmaker/issues/detail?id=2 for details
System.setProperty("dexmaker.dexcache", getTargetContext().getCacheDir().toString());
}
}
And set up your project (or test project) to use this class as the instrumented test runner in its AndroidManifest.xml when building with ant:
<instrumentation
android:name="my.package.CustomInstrumentationTestRunner"
android:targetPackage="my.target.package" />
or its build.gradle when building with gradle:
android {
defaultConfig {
// ...
testInstrumentationRunner 'my.package.CustomInstrumentationTestRunner'
}
// ...
}
If you have other instrumentation entries, you can switch between them either on the command line or select one in your IDE running configuration.
I had this issue for an Android Library project but NOT for the application project! Setting the System property "dexmaker.dexcache" as mentioned above worked around the issue.
I'm running Android 4.3 Nexus 4 device, building with 19.0.3 tools, target api 19,
my dependencies:
androidTestCompile "org.mockito:mockito-core:1.9.5"
androidTestCompile "com.google.dexmaker:dexmaker:1.0"
androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.0"
It looks like the dexmaker project has moved from Google Code to GitHub.
In the maven central repository there are versions 1.1 and 1.2 published in March 2014 and December 2014.
I've verified this "dexcache == null" issue still exists through version 1.2 - but only on certain devices. For example, a Galaxy S5 with Android 5.0 has the problem, and a Galaxy S4 with Android 4.4.2 does not.
I cloned the GitHub repository (last commit March 12th 2015 - ca74669), and ran locally, and the problem has been fixed (there are also commits in the history that back this up). So once there is a 1.3 release, hopefully this problem is gone for good!
Anyone else wanting to run a local copy of 1.3-SNAPSHOT, here's how I did that (on a Mac, but other platforms should work too, you'll need mvn, adb, and dx on PATH):
git clonehttps://github.com/crittercism/dexmaker.git
cd dexmaker
mvn install -Dmaven.test.skip=true
cp -R ~/.m2/repository/com/google/dexmaker $ANDROID_HOME/extras/android/m2repository/com/google
Then change version in app/build.gradle: androidTestCompile 'com.google.dexmaker:dexmaker:1.3-SNAPSHOT'
Or pom.xml if using maven to build, or overwrite your libs/dexmaker.jar with ~/.m2/repository/com/google/dexmaker/dexmaker/1.3-SNAPSHOT/dexmaker-1.3-SNAPSHOT.jar if you are using eclipse/ant
Also, FYI, the original issue report for the same issue on Google Code as well.
You can add the mockito core as a dependency instead. Then, that error will not happen and you won't need a workaround.
dependencies {
...
testCompile 'org.mockito:mockito-core:1.10.19'
}
I observed this issue when did manipulations with resources and folders inside test folder. Actually just restarting Android Studio helped. Simple, but worked.

Categories

Resources