Jitpack builds successfuly, but jars are empty for every module - android

In recent release of our library we decided to add some kotlin-dsl features to our build, though for now we've added buildSrc build.gradle.kts and Dependencies.kts file containing libraries versions for easier use across all modules.
The problem is that this version builds successfuly on jitpack, but downloaded jars are empty. How do I fix this? Also all the resource files are present. The build log file also differs much from previous ones.
Problematic build log file
Working build log file
A link to library on jitpack: https://jitpack.io/#netigenkluzowicz/api_android
Github link
branch to reproduce these build problems is feature/kotlin, we're working to fix it on fix/jitpack-build branch
To Reproduce
Add this dependency to an Android project, sync and check classes.jars
implementation 'com.github.netigenkluzowicz:api_android:2.4.1'
What we did before this problem started to occur:
Added buildSrc directory with build.gradle.kts and Dependencies.kts.
We also extracted android { } block from our modules build.gradle files, it is now applied from android.gradle file.
I've already went through jitpack issues on github, all I found so far are build errors with kotlin-dsl from late 2018. Was following this guide to make a use of kotlin-dsl, though due to having issues with android { } block I didn't migrate all of our gradle files.

Related

Android Library on Bintray missing sources and javadoc

I am trying to publish an Android library written in Kotlin as an AAR on Bintray to distribute it. I have already configured the whole project following various resources that I found online, and the publishing via bintrayUpload goes smoothly. Here's my build.gradle.kts.
However, when I import the library in another project, I can reference all the classes correctly but:
My library depends on RxJava 3, but that (and other dependencies) are not automatically downloading when importing my library in Gradle, resulting in Android Studio complaining about all the Rx classes.
I can't see the sources and the JavaDoc.
On Bintray, everything looks normal: I can see two JAR files (-Javadoc and -sources`), one AAR, and the usual POM file. I've inspected all of them, and they contain everything I'm expecting, including the dependencies in the POM file.
You can inspect the full source code here and the Bintray artifact here.
What am I doing wrong?
I had the same problem with maven-publish plugin. Sources were uploaded to maven repository but could not be downloaded together with aar. Sources were not included in .module.
I have found this plugin: https://plugins.gradle.org/plugin/xyz.tynn.android.sources - with this, sources are included in .module and are automatically downloaded together with aar.
This plugin doens't require any extra tasks for generating sources neither adding extra artifacts.
To use it all what has to be done is apply plugin: "xyz.tynn.android.sources" and publication configured according to official Android documentation
https://developer.android.com/studio/build/maven-publish-plugin
There is also plugin for JavaDoc https://github.com/tynn-xyz/BuildSrc/blob/master/README.md

Minimum Necessary files for an android build

Trying to find the bare minimum source and build files needed to build an android project in Android Studio. I want to publish to github and avoid uploading generated build files or binaries.
I do have a Android.gitignore from but I still see some more files getting pushed into the repo which may not be necessary. I understand the few obvious ones but about others, do I need them and if so kindly explain the usage.
So the question, do I need the following and if so then a short description of why?
root
build.gradle
gradle.properties
gradlew
gradlew.bat
settings.gradle
/app
app/build.gradle
app/proguard-rules.pro
/gradle (tested, android can re-download/generate following it if not present)
gradle/wrapper/gradle-wrapper.jar
gradle/wrapper/gradle-wrapper.properties
This question can have two different answers based on the meaning of the word needed.
First (the real one)
Assuming your project has currently those files, if your question is:
Should I commit these files on my Git repo?
The answer is yes, all of them, and I'm explaining why:
root
build.gradle -> defines the configuration for all the Gradle modules in your project (e.g. use the same remote repositories to download some Gradle plugins)
gradle.properties -> defines some optional flags used when building the app (e.g. enabling the incremental KAPT, enabling the AndroidX jetifier)
gradlew -> invokes the Gradle wrapper (which can be found under gradle/wrapper/gradle-wrapper.jar) to avoid to have Gradle installed when building your project on Darwin/Linux
gradlew.bat -> the same of gradlew but for Windows
settings.gradle -> defines the list of modules which are part of your project
app/
app/build.gradle -> defines the configuration only for your app module (e.g. its build types, its flavors, its version code and version name)
app/proguard-rules.pro -> defines the obfuscation rules when your app enables the minification
gradle/
gradle/wrapper/gradle-wrapper.jar -> provides the same version of the Gradle wrapper jar for all the users. This is very important because it forces the users to use the same version of the Gradle wrapper to compile your app
gradle/wrapper/gradle-wrapper.properties -> same as above, it defines which version of the Gradle wrapper you need
Second (the useless one)
Now, I'll give you the answer to the question:
Are these files strictly needed to compile an Android project?
To successfully compile an Android project with Gradle you just need the root build.gradle if you have Gradle installed on your machine or build.gradle + the wrapper files if you have not Gradle installed on your machine.
Theoretically you can:
put your application code in the root project and that avoids you one build.gradle and settings.gradle
disable the obfuscation and that avoids you proguard-rules.pro
remove gradle.properties and set the properties via command line
Obviously this solution won't happen on a real project scenario.

Android - create uber/fat aar, error on implementation

I want to create a single uber/fat aar. I have a library (libA) which is dependant on another library (libB) and I would like to bundle them together, preferably using gradle. This uber/fat aar will then be used in an app.
Initially I looked at 2 similar gradle plugins, shadowJar and fataar but due to version incompatibilities they were a no go. So to do this, I've created a custom configuration in my gradle file and added the dependencies:
configurations { privateLibs }
privateLibs ('libB.1.0.0#aar') {
transitive=true
}
compile configurations.privateLibs.asFileTree
I can then run gradle install to produce libA-1.0.0.aar.
When I inspect libA.aar and look at it's contents using
jar tvf libA-1.0.0.aar
I can see LibB listed under the libs folder:
BST 2018 libs/libB-1.0.0.aar
I've now created an app inclduing my new library libA-1.0.0.aar as a local dependency. Later it will be resolved through an external repository.
implementation files('libs/libA-1.0.0.#aar')
The app compiles and appears to be ready to run. However when I try to run the app in the android simulator it throws up an error message:
error: cannot access ExampleClass class file for com.sample.ExampleClass
ExampleClass is a class created in libB and implemented in libA. It appears as though libA has no knowledge of libB despite it being available in the libs folder of the libA aar. Is the build steps here wrong? Should this be done another way? Thanks in advance!

OSS license plugin doesn't include library module licenses

After migrating to Android plugin for Gradle 3.0 the OSS license plugin (https://developers.google.com/android/guides/opensource) no longer includes the licenses from the project's library modules dependencies. Only the "app" module.
I'm using com.google.gms:oss-licenses:0.9.1 and com.google.android.gms:play-services-oss-licenses:11.8.0
If I 'apply' the plugin to all my modules, the third_party_license data is generated in the raw folder for each module. But in the end only the data from the app module end up in the APK.
Is there any workaround for this problem?
Yes that is correct.
Based on my search on how the plugin works, the plugin would generate the data into the res/raw folder of the artifact (aar or apk, but not jar files) based on POM files it can get from the libraries. Then the rest of merging is done by Gradle Android Plugin, and not by the OSS License Plugin, which merges the res folders from all of the sources (dependency libs, modules, main app etc.). However here's is the issue, upon merging, the Android Gradle Plugin would choose one if there are duplicates of the same resource (link to explanation), and the one that is chosen is based on a priority, meaning since both the app module and the lib module are generating the R.raw.third_party_license resource which are duplicates, the one from the app module has a higher priority of being included than the one from the module hence the license information from the module are not included.
There are several ways of fixing this:
Include the same dependencies from your library module in your app module. This is probably the worst idea to do but it does not affect your app since Gradle would automatically resolve the dependencies without any issues especially if they will be of the same version, if they were of different versions then Gradle would choose the latest.
Rather than using a module dependency, publish the module to a maven repo (locally or remotely, here's a link to show how it could be done locally), and add it's dependency as such: implementation 'com.mygroup:library:1.0'. Don't forget to remove it from the project build.settings file. This would generate the POM file of the library module and hence get the plugin to read it and include it's library licenses. This means that the library should be compiled and published before compiling the app module, but also it could lead to some weird compiling issues and confusions when errors happen.
Unfortunately there is one more way that I thought would work however it didn't. It is by changing the dependencies in your library module to api instead of implementation. This would expose the library dependencies into the app module dependencies but would increase the build time of the project. But finally it didn't generate the raw resources properly because it seems that the OSS License Plugin only reads the dependencies from a POM file of library and in this case the POM file is not being generated even if the library module dependencies were exposed. Probably should post this as an enhancement or bug request to the developers of the plugin.

Android Studio: Resolving Duplicate Classes

When I try to run my android application on an Android device, the gradle console reports the following error:
Error:Execution failed for task ':app:transformClassesWithJarMergingForDebug'.
> com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: com/loopj/android/http/AsyncHttpClient$1.class
When I search for the "AsyncHttpClient" class, I see that it's indeed being found in two separate locations:
/Users/Afflatus/.gradle/caches/modules-2/files-2.1/com.loopj.android/android-async-http/1.4.9/5d171c3cd5343e5997f974561abed21442273fd1/android-async-http-1.4.9-sources.jar!/com/loopj/android/http/AsyncHttpClient.java
/Users/Afflatus/.ideaLibSources/android-async-http-1.4.9-sources.jar!/com/loopj/android/http/AsyncHttpClient.java
The first path seems to suggest it's a "cache" file... so I've tried invalidating & restarting my cache, but both files are still there after the gradle gets rebuilt and I try to run the application. I've read in alternate posts that it can be resolved by deleting one of the files... So I went to the cache location and deleted all the files found in the "1.4.9" folder... unfortunantly after reopening Android Studio, a new cache file gets created and I get the same error.
Other posts (here, here,here, and here) suggest if I add "./gradlew clean" to the root directory it would rebuild the gradle again just for the run (as far as I understand). So I tried doing that as well:
Which made my app's folder look like this:
But unfortunantly, that didn't help things I still get the same error. What am I doing wrong? What should I be doing?
I added this line to my gradle.properties file and my app worked
android.enableJetifier=true
Sometimes duplicate classes exception means that one of your dependencies uses implicitly the older or newer (with +) version of some library you also use in your project,
To resolve this issue you may add such block of code (put your library version after 'force') to your build.gradle file (Module:app):
configurations {
all {
resolutionStrategy {
// do not upgrade above 3.12.0 to support API < 21 while server uses
// COMPATIBLE_TLS, or okhttp3 is used in project
force 'com.squareup.okhttp3:okhttp:3.12.0'
force 'com.squareup.okhttp3:logging-interceptor:3.12.0'
}
}
}
You may also exclude some group from your dependencies.
For a single dependency you way write:
dependencies {
// example
implementation('log4j:log4j:1.2.15') {
exclude group: 'javax.jms', module: 'jms'
}
}
Tested to work on Android Studio with Gradle Plugin version 3.4.2 and Gradle version 5.4.1.
Credits go to Dimitar Dimitrov and Schalk Cronjé from gradle org discussion group
That's because you have added some library two times in libs folder, this could happen sometimes when you have multiple versions of the same library in the libs folder. Check it and remove any duplicate jar files.
And the second option could be you have also added the dependency in gradle.build and also have a jar in libs folder.
So check both places and remove duplicate entries and then clean and build APK again.
Delete files with duplicate jar extensions in the libs folder. However, if there are no duplicate files and there is still a "Duplicate classes" error, look for the name in the rest of the "Duplicate classes ...." clause in the error section. For example, "duplicated classes 'dagger' bla bla". Delete the file named 'dagger' from the libs folder. (Be careful not to delete it with shift.)
In my case, I am using sensorocloud.jar and the compile 'com.loopj.android:android-async-http:1.4.9' in my gradle which caused the same error as yours. Because sensoro cloud SDK used loopj's async-http.
I managed to solve it by manually removing the duplicate .class files in the jar file. (i.e.
changing the extension from jar to zip
extract it
remove the com.loopj.android .class files)
(P.S. I have tried to search through the web to see if I could exclude certain class of a jar in gradle, but not succeed, e.g. I referenced this SO post)
This error can be caused by several things;
misconfigured package name
Activity views that is not well binded. - simply go to your launcher activity view and ensure context is defined well e.g "com.yourdomain.package"
Re-create your BuildConfig and set it up well.
Check if your project build.gradle. There it might be some maven duplicate dependency
Here's another situation that can cause duplicate class during the mergeDexClasses task. This can happen with later versions of android gradle.
If your build.gradle.kts script has a dependency in the form:
implementation(project(":mylib", configuration="default"))
that can cause duplicate classes. The correction is simple. Just change it to:
implemenation(project(:mylib"))
Here's the Android Studio's Team explanation:
Having both project(":lib") and project(path: ":lib", configuration: "default") in the runtime classpath means that AGP gets both build/classes/java/main and build/libs/lib.jar (run ./gradlew :lib:outgoingVariants --all to verify). Because paths differ, we'll get 2 dexing transforms happening: 1 incremental that produces dex per class under build/.transforms (the one processing dir) and another one which produces single dex (the one processing jar). Later on during merging this causes failure.
AGP never publishes to the default configuration, in fact java-library plugin does it only so it does not break older build scripts. Having an explicit configuration name used in the dependency declaration is discouraged and Gradle attributes should be used instead.
In an older version of AGP, I ran into a problem where adding the configuration value "default" fixed some issue I was having. Well that no longer works, and adding the "default" configuration you can get duplicate classes.

Categories

Resources