Android gradle JAR dependency ends up declared as native - android

In my Android projects build.gradle file I have:
dependencies {
compile 'org.apache.directory.studio:org.apache.commons.io:2.4'
compile 'org.apache.commons:commons-collections4:4.0'
}
When I run aapt dump badging I see:
native-code: 'commons-io-2.4.jar'
Clearly commons-io is not native code but the Android Gradle plugin thinks it is. How can I tell the Android Gradle plugin this library does not contain native code? Also curious how did it decide what architecture this library is? It seems to have picked some variety of arm since the APK won't install on a intel-based Android emulator, it gives the error: INSTALL_FAILED_CPU_ABI_INCOMPATIBLE.

You may be using the incorrect Commons IO library. Try:
http://mvnrepository.com/artifact/commons-io/commons-io/2.4
The version you're using seems to be specific to Apache Directory Studio 2.4 which seems to be a desktop app.

I once had troubles introducing a dependency on commons-io:2.4 into my build code. The problem is that Gradle itself comes with a version of commons-io. In my case it could be fixed with this:
sourceSets {
main {
compileClasspath = configurations.compile.minus files("$gradle.gradleHomeDir/lib/commons-io-1.4.jar")
}
}
I took this snippet from My Gradle project depends on commons-io 2.4, but Gradle puts $GRADLE_HOME/commons-io-1.4.jar into the classpath, causing failures
But be aware that it is not recommended to use different versions of libraries to come with Gradle.
You can find more information about this here: https://discuss.gradle.org/t/unable-to-use-commons-io-2-4-because-gradle-forces-the-loading-of-commons-io-1-4/8021
This might aswell be completely unrelated :)

Related

AndroidX migrate dependency / libraries

I have successfully migrated my project to AndroidX. App is running perfectly, but I am getting compile time errors, because my dependencies use support package.
Reason of this error
Because PhotoView is a dependency class, which uses android.support.v7.widget.AppCompatImageView which is no more available in my project. Because it is now androidx.appcompat.widget.AppCompatImageView
Project still run?
Yes, android.enableJetifier convert this dependency to AndroidX at runtime, but I want to get rid of compile time errors.
Is there a quick fix for now?
If you depend on a library that references the older Support Library, Android Studio will update that library to reference androidx instead via dependency translation. Dependency translation is automatically applied by the Android Gradle Plugin 3.2.0-alpha14, which rewrites bytecode and resources of JAR and AAR dependencies (and transitive dependencies) to reference the new androidx-packaged classes and artifacts. We will also provide a standalone translation tool as a JAR.
I see (using ./gradlew app:dependencies) that rxbinding's design dependency is updated to the new com.google.android.material dependency. Passing com.google.android.material.snackbar.Snackbar to a library function that references android.support.design.widget.Snackbar themselves makes Android Studio show a compiler error, but actually compiling and running the app works. I assume AS can't really handle these changes yet.
It seems there are some caching issues, removing .idea/libraries and performing a Gradle sync makes the errors disappear.
I solved this issue by deleting .idea folder and syncing project again.
This seems a bug of IDE not Jetifier, it does not re-sync dependencies after migrating.
Jetifier does its work well. It converts all dependencies support libraries into androidx at building time. See #this post for good explaination.
My fix for this was converting the library with the compile time error to AndroidX and submitting a pull request to the library.

Android app getting crashed : com.android.support.constraint:constraint-layout : Error

I have started to learn Android. I am trying to work on Google Map APIs. My app is crashing every time I am trying to launch it, upon investigation I found one notification in build.gradle file.
Please refer this image to see the message from compiler
I changed com.android.support.constraint:constraint-layout:1.0.0-alpha7 to com.android.support.constraint:constraint-layout:1.0.0-alpha9 to support compileSdkVersion 26. I am not finding any relevant links on Google to fix this issue.
Your compile sdk version is greater than your support libraries,
try modifying your gradle as
android {
...
compileSdkVersion 25
...
}
and within the dependency you can add
compile 'com.android.support.constraint:constraint-layout:1.0.2'
Please refer to this post, if you run the Gradle command you can see what of your dependencies has a different buildtools version.
From the post:
Run a Gradle dependency report to see what your full tree of
dependencies is. From there, you will see which one of your libraries
is asking for a different version of the Android Support libraries.
For whatever it is asking for, you can ask for it directly with the
25.2.0 version, or use Gradle's other conflict resolution approaches to arrange to get the same version.
Run:
./gradlew -q dependencies <module-name>:dependencies --configuration compile
Example:
./gradlew -q dependencies app:dependencies --configuration compile

Can I Include an android library that uses an older gradle plugin in a newer project?

I have a newer android project that's using the 2.3 gradle plugin in Android Studio. I am trying to include an older android library that uses the 2.0.+ gradle plugin.
If I just compile the library by itself, it compiles successfully. When I include ':library' and put this library in the main project's dependencies{ compile project(':library') }, I get the following error on Gradle Sync:
Error:(50, 0) Could not get unknown property 'assembleDebug' for object of type com.android.build.gradle.LibraryExtension.
The library's build.gradle file has an assembleDebug block, and from this issue: https://code.google.com/p/android/issues/detail?id=219732#c21, it seems to be related to some change in the 2.2 gradle plugin.
I'm not the author of the library, so I don't to change anything in the library itself, just use it. Is it possible to include this older library in the newer project without having to modify the library's build.gradle file to work with the newer gradle version?

Gradle provided JAR dependency not working as expected

I've been stuck on this problem all day, I'm hoping someone can help me get my program running.
I am building an Annotation Processor for Android, it currently has two modules: "mymodule" and "mymodule-compiler"
mymodule-compiler depends on mymodule:
dependencies {
compile project(':mymodule')
...
}
mymodule uses the netflix "provided" plugin for Android:
apply plugin: 'nebula.provided-base'
dependencies {
provided 'com.google.android:android:4.1.1.4'
}
This actually works perfectly, however when I run my compiler unit test suite, a lot of tests fail because the Android dependency specified is v4.1.1.4 and I actually need v6.0. v6.0 is not available on Maven (and looks like it never will be because Google haven't updated it since 2012).
I found out that the Android SDK provides a "Unit Test" JAR version of Android for each release, which is the entire SDK "stubbed out". I assume the versions on Maven are stubbed out too(?). I can easily grab that JAR and put it in my project under libs/.
Now when I update the mymodule gradle file:
dependencies {
provided files('libs/android.jar')
}
My project still compiles correctly and I can see v23 files! However, when I run my unit tests, I see the following error:
!!! JUnit version 3.8 or later expected:
java.lang.RuntimeException: Stub!
at junit.runner.BaseTestRunner.<init>(BaseTestRunner.java:5)
at junit.textui.TestRunner.<init>(TestRunner.java:54)
at junit.textui.TestRunner.<init>(TestRunner.java:48)
at junit.textui.TestRunner.<init>(TestRunner.java:41)
at com.intellij.rt.execution.junit.JUnitStarter.junitVersionChecks(JUnitStarter.java:205)
at com.intellij.rt.execution.junit.JUnitStarter.canWorkWithJUnitVersion(JUnitStarter.java:188)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
It shouldn't matter that the Android JAR is stubbed out because I never execute Android code, I only need it for imports.
Does anyone have any ideas about what I'm seeing and how I could fix this?
EDIT 1: More info:
If I remove the Android dependencies from mymodule entirely, and instead put the following into mymodule-compiler.gradle:
dependencies {
testCompile files('libs/android.jar')
...
}
All my tests will pass. This is obviously not a fix though, as 'mymodule' does need the Android dependency.
EDIT 2:
Doing the same test as EDIT 1, but using the netflix provided scope instead of testCompile works too. If I use the provided scope in both projects though, I get the same Stub! exception.
[Worked out together with OP]
The local jar contains additional classes over the maven jar which seem to interfere.
To get it working delete these from the jar (specifically in this case: all junit classes).
Comparison of the two jars (left is maven jar, right is local jar):

patch support library using Android Studio

I've moved my project to Android Studio a month ago, and I'm glad I did, despite the need to switch to a new (and more powerful) build system (gradle). One thing I'd have known in Eclipse, but I can't figure out how to achieve now, is patching the support library. I know that it does not sound like a good practice, but a couple of code lines are driving me crazy, and the solution would be to simply modify it to solve my problem.
I've tried to modify the code in the sdk's ".\extras\android\m2repository\com\android\support" directory, but that does not seem to affect the code that is really used for compilation.
Any idea about how to achieve this ?
Edit:
I tried to create a module "SupportLibraryV4" in my project, and this is what gradle tells me when I try to build it :
Error Code:
1
Output:
trouble processing "java/android/support/v4/R$anim.class":
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
This is often due to inadvertently including a core library file
in your application's project, when using an IDE (such as
Eclipse). If you are sure you're not intentionally defining a
core class, then this is the most likely explanation of what's
going on.
However, you might actually be trying to define a class in a core
namespace, the source of which you may have taken, for example,
from a non-Android virtual machine project. This will most
assuredly not work. At a minimum, it jeopardizes the
compatibility of your app with future versions of the platform.
It is also often of questionable legality.
If you really intend to build a core library -- which is only
appropriate as part of creating a full virtual machine
distribution, as opposed to compiling an application -- then use
the "--core-library" option to suppress this error message.
If you go ahead and use "--core-library" but are in fact
building an application, then be forewarned that your application
will still fail to build or run, at some point. Please be
prepared for angry customers who find, for example, that your
application ceases to function once they upgrade their operating
system. You will be to blame for this problem.
If you are legitimately using some code that happens to be in a
core package, then the easiest safe alternative you have is to
repackage that code. That is, move the classes in question into
your own package namespace. This means that they will never be in
conflict with core system classes. JarJar is a tool that may help
you in this endeavor. If you find that you cannot do this, then
that is an indication that the path you are on will ultimately
lead to pain, suffering, grief, and lamentation.
1 error; aborting
impressive !
Android sdk doesn't have all required files for building support library.
You need to checkout additional repositories from https://android.googlesource.com:
platform/frameworks/support
platform/prebuilts/gradle-plugin
platform/prebuilts/maven_repo/android
platform/prebuilts/sdk
platform/prebuilts/tools
Please, keep the directory structure as in android repository.
Now you could change any code in support library. If you need to change support library for api v.4 do it in "platform\frameworks\support\v4". For building patched version of support library use gradle with next command:
platform\frameworks\support\v4\gradle clean jar
Resulted jar could be found in "platform\out\host\gradle\frameworks\support\v4\libs\". Put it to the libs folder of your project and add in build.gradle file.
Updated answer 2016 for Linux and OS X using the bundled gradle wrapper instead of the system's gradle installation:
Checkout the following repositories from https://android.googlesource.com and keep the directory structure:
platform/frameworks/support
platform/prebuilts/gradle-plugin
platform/prebuilts/maven_repo/android
platform/prebuilts/sdk
platform/prebuilts/tools
platform/tools/external/gradle
Modify files in the library:
Change files in platform/frameworks/support/
Build AAR
cd platform/frameworks/support
./gradlew jarRelease
The resulting .aar is in platform/out/host/gradle/frameworks/support/<module>/build/outputs/aar/
Add to project
Create a libs/ folder next to your app's build.gradle
Add libs folder to build.gradle: repositories{ flatDir{ dirs 'libs' } }
Copy the .aar file to libs/
Add aar to your dependencies section in build.gradle, e.g.: dependencies { compile(name:'my_custom_supportlib_module', ext:'aar') }
Module already in project
When you patches a support library module that other modules depend on, you'll have it twice in the build causing errors. This can be avoided by excluding the original dependency.
If you for example patch recyclerview-v7 and add
dependencies {
compile(name:'recyclerview-v7-release', ext:'aar')
}
you have to exclude the dependency like this. Change
compile "com.android.support:design:24.2.1"
to
compile("com.android.support:design:24.2.1") {
exclude group: 'com.android.support', module: 'recyclerview-v7'
}
for all modules that depend on the patched module.
Patch the SupportLib and add it manually as a jar:
Put the SupportLib jar into the libs folder
Right click it and hit 'Add as library'
Ensure that compile files('libs/supportlib.jar') is in your build.gradle file
Do a clean build
Disclaimer: Android Studio: Add jar as library?
Turns out that Ilya Tretyakov's answer only works for parts of the support library that don't have resources because they can't be put into a .jar.
The correct way to build for example the design-support-library is as follows:
checkout these repos from https://android.googlesource.com and keep the file structure:
platform/frameworks/support
platform/prebuilts/gradle-plugin
platform/prebuilts/maven_repo/android
platform/prebuilts/sdk
platform/prebuilts/tools
navigate to platform/frameworks/support/design and edit whatever file you want. Now rebuild everything with gradle clean assembleRelease
you can find the resulting library file support-design-release.aar in platform/out/host/gradle/frameworks/support/support-design/build/outputs/aar
create an app/libs folder in your project and edit the app/build.gradle:
repositories{
flatDir{
dirs 'libs'
}
}
dependencies {
compile(name:'support-design-release.aar', ext:'aar')
}
do a clean rebuild of your project and everything will work as intended

Categories

Resources