Could not Resolve koin while transfering from jcenter to maven - android

I am working on a project which I used koin but I had the dependencies added from jcenter and not maven.
Since jcenter is going to get deprecated I want to transfer to maven.
So i removed Jcenter and I added mavenCentral().
The thing is that when i try to sync my project this error occures :
Could not resolve io.insert-koin:koin-androidx-scope:2.2.3.
Possible solution:
Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
Firstly, I followed the tutorial of insert-koin.io but nothing helped. When I try to press Run then the error of course still occurs.
Execution failed for task ':domain:compileKotlin'.
Could not resolve all files for configuration ':domain:compileClasspath'.
Could not resolve io.insert-koin:koin-androidx-scope:2.2.3.
Required by:
project :domain
> No matching variant of io.insert-koin:koin-androidx-scope:2.2.3 was found. The consumer was configured to find an API of a library compatible with Java 11, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but:
- Variant 'releaseApiPublication' capability io.insert-koin:koin-androidx-scope:2.2.3 declares an API of a library, and its dependencies declared externally:
- Incompatible because this component declares a component, with the library elements 'aar' and the consumer needed a component, preferably in the form of class files
- Other compatible attributes:
- Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
- Doesn't say anything about its target Java version (required compatibility with Java 11)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'jvm')
- Variant 'releaseRuntimePublication' capability io.insert-koin:koin-androidx-scope:2.2.3 declares a runtime of a library, and its dependencies declared externally:
- Incompatible because this component declares a component, with the library elements 'aar' and the consumer needed a component, preferably in the form of class files
- Other compatible attributes:
- Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
- Doesn't say anything about its target Java version (required compatibility with Java 11)
- Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'jvm')
Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
Does anybody have any idea what i should do ?

Still you should be able to use jcenter (read only) in gradle file if your artifacts not present in other repositories.

You should check the section in your build.gradle.
You need mavenCentral()
// Add Maven Central to your repositories if needed
repositories {
mavenCentral()
}

Add mavenCentral() if it is not in settings.gradle as below.
pluginManagement {
repositories {
...
mavenCentral()
}
If your impl is like implementation "org.koin:koin-android:$XX", replace it with implementation "io.insert-koin:koin-android:$koin_version" in app build.gradle.

Koin packages are now on maven central.
please refer to the new setup instructions for it
https://insert-koin.io/docs/setup/v3.2
So the gradle group name changed from org.koin to io.insert-koin
And here is an example :
implementation "io.insert-koin:koin-core:$koin_version"

Related

How can I resolve Android Studio 4.2 build errors after removing jcenter()?

I have upgraded Android Studio from 4.1.3 to 4.2, using latest gradle and gradle plugin. Now references to using jcenter() in the build script are deprecated due to jcenter being end-of-lifed:
The suggestion is to "migrate" to mavenCentral(). I have various dependencies that are seemingly not on mavenCentral(), because gradle cannot find them, for example:
I Googled the artifact ("materialsearchview" in this case) and found it on the search platform "MVNrepository":
So here is what I have tried (all unsuccessful) to put a reference into my build script to have gradle find this artifact:
I added a reference to the mvnrepository to my project level build.gradle file (which I didn't expect to work given that mvnrepository is a search mechanism) highlighted in the red box in the pic, i.e.:
maven { url 'https://mvnrepository.com/artifact/' }
I added a reference to the repository identified in the blue box at the bottom where mvnrepository says the artifact is located, i.e.
maven {url 'https://repo.spring.io/plugins-release/'}
This generated a slightly different error:
Could not HEAD 'https://repo.spring.io/plugins-release/com/miguelcatalan/materialsearchview/1.4.0/materialsearchview-1.4.0.pom'. Received status code 401 from server: Unauthorized
I found the .aar file for this dependency, added it to my 'libs' directory and updated my app module level build.gradle file like this:
implementation fileTree(include: ['.jar','.aar'], dir: 'libs')
I did an 'invalidate caches and restart' at this point, thinking AS needed to index the newly added .aar file before gradle would recognize it. No joy.
I specifically added the .aar file to the libs directory, then added a reference to it in the app module build.gradle:
implementation(name:'materialsearchview-1.4.0', ext:'aar')
then did another invalidate cache/restart. No joy.
So I guess I have three questions:
Once I find a reference to an artiface in mvnrepository, is there a proper way to reference it in my gradle script so that the build system can reconcile what it needs?
What other ways are there to find what other repositories that gradle CAN address to see if the item is there?
Why is using the .aar file in the libs directory as I am doing it failing? Why can't Gradle see it there?
Thanks!
After discussing this with Mark Murphy of CommonsWare, I realized I was under a misunderstanding about the relationship between the repositories section of the project level build.gradle file, and the implementation statements of the module level build.gradle file.
Here is a good way to think of it thanks to Mark:
Project level build.gradle, i.e.:
repositories {
google()
mavenCentral()
maven { url 'https://maven.preemptive.com/' }
maven { url 'https://jitpack.io' }
//jcenter()
}
Think of these as "Gradle, look into these repositories to reconcile all the 'implementation' statements."
Then in the module level build.gradle I had this:
implementation fileTree(include: ['*.jar','*.aar'], dir: 'libs')
Think of this as "Oh yeah, grab all these things too, even if I didn't mention them as specific dependencies".
My mistake #1 was in thinking I could have an .aar file in the libs directory which ALSO had a corresponding 'implementation' statement. You can't.
My mistake #2 was that I had an implementation statement that referenced a .aar file that was in maven (which is fine since maven is in my repositories block) which itself referenced an .aar file that was not in maven but only in jcenter (which is not since I just removed jcenter from the repositories block). When I removed the reference to jcenter in the repositories block this dependency ("transitive dependency") was not reconciled and the build failed.
So lessons learned:
Any resource referenced in an 'implementation' statement AND ANY RESOURCE THAT IS IN ITS POM THAT IT DEPENDS ON must ALL be in repositories that you define in the repositories block.
If ANY of the dependencies were in jcenter, since I got rid of jcenter then I must:
Find another repository instead of jcenter that has the same resources needed to satisfy the ALL dependencies associated with the resource in question OR
Gather all the .jar/.aar files that represent that resource (the one you want and all the ones it references), place them in the /libs directory (under the module you are building), make sure your have your fileTree statement correctly formed, and REMOVE references to all those same resources from your 'implementations' statements.
How does one identify all the dependencies you ask? Well you can do it the slow way (like I did at first) and keep finding/adding them until the build doesn't break anymore. Or you can be more clever about it and let Gradle tell you which it will do if you ask it (see the docs here).
Finally - don't forget that it is not enough to make sure the referenced .aar file is in libs. In other words, Gradle does not work like: "I will look first at the repositories to satisfy your implementation dependencies and any dependency they reference, and if they are not there then I will look through all the .jar and .aar files in the spot you told me to look in the fileTree statement". Instead, note that any dependency that is referenced by an item in an 'implementation' statement needs to ALSO be able to be found within the repositories. If it can't then your only choice is to use that dependency graph, determine ALL the dependencies, and put all the .aar files into /libs AND remove any from your 'implementation' statements.
Much easier if you can find another repository instead of messing with all the individual .aar files!
For those who want to try the easier way, just go here Android Studio Archive and download the Android Studio v4.1 (Oct 12, 2020) and install it. It is working fine, I have checked it myself.

Cannot choose between the following variants of project :features:myDynamicFeatureModule:

I am experimenting with Android's Dynamic Feature Modules (a.k.a. on demand modules) on the side of the project I am working on.
In my PoC (proof-of-concept) project, Dynamic Feature Modules (DFM) work fine and gradle builds the project with no issue. After finishing with my PoC, I decided to apply it to an existing project. However, gradle failed building the project with:
Could not determine the dependencies of task ':my-app:checkSomeBuildFlavorDebugLibraries'.
> Could not resolve all task dependencies for configuration ':my-app:someBuildFlavorDebugMetadataValues'.
> Could not resolve project :features:myDynamicFeatureModule.
Required by:
project :my-app
> Cannot choose between the following variants of project :features:myDynamicFeatureModule:
- anotherBuildFlavorDebugAndroidTestCompile
- anotherBuildFlavorDebugAndroidTestRuntime
- ...
All of them match the consumer attributes:
- Variant 'anotherBuildFlavorDebugAndroidTestCompile' capability myproject.features:myDynamicFeatureModule:unspecified:
- Unmatched attributes:
- Required com.android.build.api.attributes.BuildTypeAttr 'debug' but no value provided.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Metadata' but no value provided.
- Required endpoint 'someBuildFlavor' but no value provided.
- Found org.jetbrains.kotlin.localToProject 'local to :features:myDynamicFeatureModule' but wasn't required.
- Found org.jetbrains.kotlin.platform.type 'androidJvm' but wasn't required.
- Variant ...
Note that this error is quite long, iterating through all possible flavors.
What I have tried, but did not work:
I added exactly the same flavors that base module (my-app) has in my dynamic module
In build.gradle of my DFM, I tried to set configuration explicitly like : implementation project(path: ':my-app', configuration: 'default') and also configuration: 'someFlavor'
In build.gradle of the base module (my-app) I used missingDimensionStrategy 'mydimension', 'myflavor'
Building from Android Studio and also from terminal
Removing dependencies and other code from build.gradle files
What I have tried and it worked:
Removing the dependency of base app (my-app) from DFM (i.e. removing implementation project(':my-app',) ) - but I need it. Just to clarify, the DFM applies the following gradle plugins: com.android.dynamic-feature and kotlin-android
Removing all flavors from the base app and DFM - but I need them in the base app.
The PoC I made works fine and gradle compiles the project even with the same flavors I use in my actual project
Notes:
I use DexGuard (but I disabled it to make sure it isn't interfering)
I don't have any custom build types, only 'debug' and 'release'
Gradle version is 3.5.2
Gradle wrapper is 5.5.1
Both the PoC and my actual project use the same versions of gradle, gradle wrapper, build types and flavors
Unfortunately I could not reproduce the problem in a separate project. I tried removing as much of things as possible from my project but I could not resolve the issue.
Do you have any idea what could be causing this issue and how could I possibly fix it? Thank you!
I had this issue and it was due to not removing the implementation project(':features:myDynamicFeatureModule') line from my app module's gradle file.

How to set dependency of android gradle project to different versions of library?

I have small log library and it is published to jcenter. I need to have two versions of the library - debug and release. To do this I found flag publishNonDefault true and pushed new version of library.
Structure of files in repository before flag was set:
Structure of files in repository after flag was set:
And now
dependencies {
compile 'me.shikhov:wlog:1.3.1'
}
gives me error
Error:A problem occurred configuring project ':Project'.
Could not find wlog.jar (me.shikhov:wlog:1.3.1).
Searched in the following locations:
https://jcenter.bintray.com/me/shikhov/wlog/1.3.1/wlog-1.3.1.jar
I have found syntax for local dependency, for example:
debugCompile project(path: ':myLocalLibrary', configuration: 'debug')
releaseCompile project(path: ':myLocalLibrary', configuration: 'debug')
How to set remote library dependency?
The extra string after the version in the artifact name is the classifier.
The classifier allows to distinguish artifacts that were built from
the same POM but differ in their content. It is some optional and
arbitrary string that - if present - is appended to the artifact name
just after the version number. As a motivation for this element,
consider for example a project that offers an artifact targeting JRE
1.5 but at the same time also an artifact that still supports JRE 1.4. The first artifact could be equipped with the classifier jdk15 and the
second one with jdk14 such that clients can choose which one to use.
Another common use case for classifiers is the need to attach
secondary artifacts to the project's main artifact. If you browse the
Maven central repository, you will notice that the classifiers sources
and javadoc are used to deploy the project source code and API docs
along with the packaged class files.
From here.
Gradle dependency declaration takes the form:
[organisation]:[module]:[revision]:[classifier]#[ext]
so you should be consuming the dependency as:
compile 'me.shikhov:wlog:1.3.1:release#aar'

Studio failed to download library from gradle repository

I already saw this question, but it is not helping me. First of all, I tried to add google play services in my project using:
dependencies{
compile 'com.google.android.gms:play-services:6.5.87'
}
It was showing me error:
Then I updated my studio to 1.0.1 and gradle to 1.0.0. And then I again synced the project with gradle. And it worked! It showed me another option despite of two options shown in above screenshot. It was "Install the library"(something like that). I clicked it and it popped up a dialog, and I installed the library(it was like downloadind using SDK manager and not like gradle downloads).
Now, I tried to download this library using:
compile('com.fortysevendeg.swipelistview:swipelistview:1.0-SNAPSHOT#aar') {
transitive = true
}
And it gives me error:
My android repository is updated:
Also, my internet connection is working fine. I tried to sync project many times, but same error all the time. I am not running gradle in offline mode:
How to fix this? And what is the permanent solution? And why is all this happening?
I found this question: Studio failed to download library from gradle repository which describes the exact same error, and that question had this bit of build script that you need to add to the build file that has the dependency statement in question:
repositories {
maven { url 'http://clinker.47deg.com/nexus/content/groups/public' }
}
When I do this, it works for me.
As to the general question of why this happens (and the better question of why the solution is different for different libraries):
Gradle, the build system that Android Studio uses, has the ability to automatically download library dependencies from the Internet. By and large this is a big boon for developers, because instead of having to manually download archive files, put them in the right place in your project, check them into source control, and repeat the process for new versions, now you just have to add a line of build script and the build system takes care of the housekeeping for you. The major downsides are Internet connectivity woes, which affect different developers to different degrees, and some added confusion about what it means when you get an error.
How does Gradle know where to download dependencies? Most Gradle build scripts contain a block that looks like this:
repositories {
jcenter()
}
or it may be mavenCentral() instead of jcenter(). This tells the build system to look in the JCenter or Maven Central global repositories (and JCenter is in a simplistic way of thinking about it a value-added mirror of MavenCentral); these contain archives of many versions of many, many, many libraries and are very convenient to use.
You can specify other repositories as well. This swipelistview library hasn't been uploaded to Maven Central, so the developer has made a repository for it available via a URL: if you add that URL to your repositories block, it will look for it there.
I was worried about the fact that you're accessing a SNAPSHOT version of the library -- these are supposed to be unpublished by definition. But adding a dependency on the snapshot version of the library in my test project worked for me, and looking around that URL in a web browser reveals that there's only a "1.0-" (trailing dash included) version of the library, so there's some subtletly there I'm missing; if you know more, please edit my answer or comment.
In any event, there are a couple caveats to this explanation. Some libraries aren't on Maven Central or on any Internet-accessible archive (at least they're not officially published by Android), but are instead published as part of the Android SDK download and maintained via the SDK manager. The Android support libraries and Google libraries fall under this category. If you get errors about those not being found, you have to fix it via the SDK manager.
How does the build system know to look in the SDK for those, since you didn't tell it via the repositories block? This behavior is hardcoded into the Android Gradle plugin.
The other caveat is that there's a detail that trips up a lot of people, which is that you actually have two repositories blocks, though with the usual Android Studio setup they're often in different files. One is in a buildscript block, which usually lives in the top-level build.gradle file and looks like this:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
The other often also lives in the top-level build.gradle, but you can augment it with another block in your module's build.gradle file. The top-level one looks like this:
allprojects {
repositories {
jcenter()
}
}
and a module-level one would look like one of the previous examples in this answer. What do all of these mean?
The buildscript block tells Gradle where to find build system plugins. These are plugins that enhance the functionality of the build system itself but don't say anything about your actual project. In Android projects, the Android Gradle plugin is in this category, and unlike the Android/Google libraries, this one does live on Maven Central. The repositories block (in coordination with the dependencies block, which is not the same as the dependencies block for your project, keep reading) in buildscript tells the build system where to go look for these plugins.
The allprojects block in the top-level build file tells the build system to apply the bit of contained script to all build files in the project. In this example, it's telling it to add a repositories block pointing to JCenter to all subprojects. This is a convenience so you don't have to copy/paste it into multiple build files in your modules.
In your modules, you also have a repositories block, which in conjunction with the allprojects thingy, tells the build system where to go to get library dependencies for your project, as was previously discussed.

Gradle: resolve SNAPSHOT-dependency based on most recent version in either Maven Local or Remote repository

I want to have gradle intelligently use the most recent SNAPSHOT for a given dependency which is available.
Assuming i have a build file like this:
mavenCentral()
// if (gradle.startParameter.refreshDependencies == false) {
mavenLocal()
// }
maven {
url "my_local_repo.com
}
}
With a dependency listed like this:
compile (group: 'com.mystuff', name: 'my-library', version: '1.0.0-SNAPSHOT', changing: 'true')
Which may exist both in Maven Local and in the Remote repo "my_local_repo.com" how do I ensure that Gradle always compiles with the most recent snapshot?
My reading here:
http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
Specifically point 8.5:
A project can have multiple repositories. Gradle will look for a
dependency in each repository in the order they are specified,
stopping at the first repository that contains the requested module.
makes me believe that the mavneLocal version will always be preferred, however my reading of
51.7 here:
http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:repositories
Given a required dependency, Gradle first attempts to resolve the
module for that dependency. Each repository is inspected in order,
searching first for a module descriptor file (POM or Ivy file) that
indicates the presence of that module. If no module descriptor is
found, Gradle will search for the presence of the primary module
artifact file indicating that the module exists in the repository.
...
Once each repository has been inspected for the module, Gradle will
choose the 'best' one to use. This is done using the following
criteria:
and 51.2.4
Alternatively, sometimes the module you request can change over time,
even for the same version. An example of this type of changing module
is a Maven SNAPSHOT module, which always points at the latest artifact
published. In other words, a standard Maven snapshot is a module that
never stands still so to speak, it is a “changing module”.
Muddies that substantially. It appears to say that all repo's are checked and the "best" choice is made (in this case presumably the most recent).
The bit I think you forgot to highlight from section 51.7 is this:
When the dependency is declared by a static version and a module descriptor file is found in a repository, there is no need to continue searching later repositories and the remainder of the process is short-circuited.
Which aligns with what is stated in section 8.5. But yes, for changing modules (ie. snapshots), Gradle will check every repo to find the latest artifact. For static modules, it will simply take the first one it finds.

Categories

Resources