Pure Java 8 Library module in Android Studio/Gradle Project - java

I have an Android Studio project with a pure Java 8 library module. Here is the complete gradle.build file for that library:
apply plugin: 'java-library'
dependencies {
testImplementation 'junit:junit:4.12'
}
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
The code is tested and works fine.
The problem I am having is that I have built the project, and then tried to use the built .jar file in another Android project that doesn't uses Java 7 (not 8). Obviously, the code does not work. However, I am surprised that there are no compile-time errors indicating that the library is not compatible. Instead, I only first notice the incompatibility when a runtime function is called.
Am I doing something wrong in how I am compiling the Java module? Or is it expected behavior that you will only get runtime errors that the library is not compatible? I expected compile-time errors.
Also, please tell me how to compile properly so that I can get compile-time errors in Android Studio indicating that a library was compiled with a newer Java version.
For completeness, I am getting the following runtime error when I use my Java 8 library module
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/Base64;

java.util.Base64 added in API level 26 (https://developer.android.com/reference/java/util/Base64.html).
You must use android.util.Base64 (https://developer.android.com/reference/android/util/Base64.)
For universal library I use Google Guava.
<dependency>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
<type>jar</type>
<version>14.0.1</version>
</dependency>

Related

Failed to resolve project: Android library and Java library module dependency

I'm trying to create a project which includes an Android library and a Java library in Android Studio (3.1). The Java library depends on the Android library. Both are modules in my project like this:
MyProject
|-android
|-java
Both appear in settings.gradle:
include ':android', ':java'
And the Java library depends on the Android library like this:
java (build.gradle):
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':android')
}
...
android (build.gradle):
apply plugin: 'com.android.library'
...
When trying to sync the project I'm getting the following error:
Failed to resolve: project::android
Why?
P.S. The other way around (Android depending on Java) works just fine.
First let's try to fix the build error. Let's run ./gradlew build --stacktrace to see a more detailed output:
Caused by: org.gradle.internal.component.AmbiguousConfigurationSelectionException:
Cannot choose between the following configurations of project :androidLibrary:
debugApiElements
releaseApiElements
AGP is confused which variant to choose. After inspecting this answer, we can find how to overcome the issue:
implementation project(path: ':androidLibrary', configuration: 'default')
After trying to sync the project with that setup you'll see following output in console:
Ignoring dependency of module 'androidLibrary' on module 'javaLibrary'. Java modules cannot depend on Android modules
Thus, seems like what you try to do is not supported by the plugin.
Refer to similar question, where Nick Cardoso tries to clarify the case.

How to use lombok with Kapt3

When I try to run Java/Kotlin android application with Lombok while using Kapt3:
apply plugin: 'kotlin-kapt'
javac compilation fails with numerous
error: cannot find symbol
for generated methods.
It is probably caused by inability of kapt to generate stubs:
'kapt.generateStubs' is not used by the 'kotlin-kapt' plugin
All aforementioned forces me to use older kapt where I can use:
compileOnly "org.projectlombok:lombok:$lombokVer"
annotationProcessor "org.projectlombok:lombok:$lombokVer"
kapt "org.projectlombok:lombok:$lombokVer"
kapt {
generateStubs = true
}
This however results in fail during test compilation, because I am also using databinding library:
What went wrong:
Execution failed for task ':app:compileXDebugUnitTestJavaWithJavac'.
java.lang.RuntimeException: Failed to parse data binding compiler options. Params:
kapt.annotations : ...\app\build\tmp\kapt\xDebugUnitTest\wrappers\annotations.bscplayDebugUnitTest.txt
kapt.kotlin.generated : ...\app\build\tmp\kapt\xDebugUnitTest\kotlinGenerated
This, on the other hand, forces me to use Kapt3 as described here:
android databinding unit test error Failed to parse data binding compiler options.
Does anyone know how to resolve this issue with Lombok? All I was a hint to use my first solution, but it leads to the databinding problem (as per Kotlin Support · Issue #1169 · rzwitserloot/lombok · GitHub)
Note: Situation is same in Android studio 2.3.3 and in Android Studio 3 (with gradle build tools 3.0.0).
In your build.gradle, add this:
kapt {
keepJavacAnnotationProcessors = true
}
For more info check the JetBrains Kotlin documentation
As was explained by #yanex in comments:
Unfortunately, Kotlin is incompatible with Lombok because it uses the private javac API do to its job. Although kapt3 is built on top of the Java compiler, kapt generates Java stubs for Kotlin classes so what can Lombok process is the stubs, not the original classes. By the way, the original kapt is deprecated and will be removed soon after the Kotlin 1.2 release. So you have some time to migrate to Kotlin & kapt3.

Android Dependency Issue

Trying to run my app, this is an error I'm getting from the Gradle Build:
Error:A problem occurred configuring project ':app'.
Could not resolve all dependencies for configuration ':app:_debugApkCopy'.
Could not find any version that matches com.google.android.gms:play-services-vision:9.4.0.+.
Versions that do not match:
11.0.2
11.0.1
11.0.0
10.2.6
10.2.4
+ 17 more
Required by:
project :app
Here's what my dependencies look like:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
// Important - the CameraSource implementation in this project requires version 8.1 or higher.
compile 'com.android.support:support-v4:24.2.0'
compile 'com.google.android.gms:play-services-vision:9.4.0.+'
compile 'com.android.support:design:24.2.0'
compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4'
I've tried to update the play services through Tools>Android SDK>..
I've read some other posts and people have similar problems, but the fixes don't work. I was also hoping to understand the issue a bit more.
Thanks
Try :
A full clean and rebuild
Uninstalling/installing android support repository
Your specification of "9.4.0.+" is not correct. Maybe you meant something like "9.4.+", but at any rate dynamic dependencies aren't a great idea IMHO. The error message lists the most recent version available on your machine as "11.0.2" (which is the most recent version at the time of writing). Use that instead. According to your comment above, this part of your problem is clearly resolved.
As to your other problem ("support libraries must use the same version"), something (play-services-vision or constraint-layout) most likely pulls in a different version of some part of the support libraries. You should look at this SO question to track down where your dependencies are coming from. You will need to make sure and use compatible versions of everything. In the end, it may suffice to just make sure you have the latest version of each.

Gradle DSL Method not found: testCompile()

Hi I am working on a project and have reached a stage where it would be unwise to continue without unit testing. I thought unit testing in Android Studio would be straight forward but I can't run my tests.
Here are my dependencies. Everything works fine until I add the last line of code. I then receive the error message that is in the title.
How do I fix this and run my tests?
Here was the tutorial I was following: http://tools.android.com/tech-docs/unit-testing-support
Official Unit testing support was introduced in Android plugin starting from version 1.1. This means that testCompile configuration is not available on previous versions. Based on your comment, you are using Android Gradle plugin version 1.0.0. That's why your build complains about missing testCompile configuration.
As of today, the latest released Android Gradle plugin version is 1.3.0, so I would suggest moving to this version ASAP.
What you need to do - is in root level build.gradle file update com.android.tools.build:gradle version to 1.3.0:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
}
}
For me, the problem was solved by commenting out the following line in the top-level build.gradle:
testCompile() "org.robolectric:robolectric:3.3.2"

Google Cloud Storage Java Client Library with Gradle

Google promotes their new Java Client library here: https://developers.google.com/appengine/docs/java/googlecloudstorageclient/
Note: I am not talking about the native REST library. I want to work with the Java Client Library.
On the website, Google does not specify the import directive for Gradle. For Maven, pom.xml looks like this:
<dependency>
<groupId>com.google.appengine.tools</groupId>
<artifactId>appengine-gcs-client</artifactId>
<version>RELEASE</version>
</dependency>
When I change this to work with my Gradle project, it doesn't work:
dependencies {
compile 'com.google.appengine.tools:appengine-gcs-client:RELEASE'
}
It finds the tools there, but the com.google.appengine.tools.cloudstorage cannot be resolved (it resolves tools, though).
What I did then: I removed the library and seached for "gcs" in the Android Studio dependencies dialog; and it finds and adds the following directive to build.gradle:
dependencies {
compile 'com.google.appengine.tools:appengine-gcs-client:0.3.9#jar'
}
Same problem with that as before: tools is resolved, but not tools.cloudstorage.
What am I doing wrong? Where does the library live/which import statement will I need to add to Gradle?
I don't want to download the jar as I want my project to update jars automatically. mavenCentral() is set, and here is my full build.gradle file, just in case you need it:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.appengine.tools:appengine-gcs-client:0.3.9#jar'
compile 'com.google.http-client:google-http-client-android:1.18.0-rc'
}
Any help appreciated, thanks!
You can use the following to specify version 0.4.4 (the most recent as of 1/14/2015):
compile 'com.google.appengine.tools:appengine-gcs-client:0.4.4'
or specify the latest version with a plus sign:
compile 'com.google.appengine.tools:appengine-gcs-client:+'
Using the latter is the faster answer, but it may cause unintended compatibility issues in the future as updates are release.

Categories

Resources