Kotlin Multiplatform library unresolved dependency at runtime - gradle

I'm making a private Kotlin Multiplatform library that will be in a private repo hosted on Bitbucket.
My library depends on another library, called Krypto.
So, naturally, I have the following dependency in the common module of the library:
val commonMain by getting {
dependencies {
api("com.soywiz.korlibs.krypto:krypto:2.2.0")
}
}
Now, when I import the library via Cocoapods to an iOS project, it works perfectly fine. However when I insert the .jar file to my Android project as a dependency:
implementation files('libs/MyLibrary-jvm-1.0.0.jar')
it compiles, but at runtime crashes with the following error:
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/soywiz/krypto/SHA256Kt
If I add the Krypto dependency to my Android project, everything works fine, however I would like the dependencies to be already included in my library. How to do that?
I also tried adding the java-library plugin and adding the dependency in a java build block, but it didn't change anything.

The solution was in the documentation all along... https://kotlinlang.org/docs/multiplatform-build-native-binaries.html#export-dependencies-to-binaries
In the Gradle configuration of the binaries of a specific platform we need to use export() to include dependencies. To also include dependencies of the dependencies, we need to do export(dep, transitiveExport = true).
kotlin {
sourceSets {
commonMain by getting {
dependencies {
api(project(":dependency"))
}
}
}
java().binaries {
framework {
export(project(":dependency"), transitiveExport = true)
}
}
}

Related

javax.json module not found building JavaFX application with Gradle

I am trying to run a modular JavaFX application, with few other modular and non modular dependencies, using Gradle, but I am stuck with dependencies resolution.
The project is in Eclipse, using OpenJDK 14-. I have been able ot run, build and package the same application as non-modular using the org.beryx.runtime pluging https://badass-runtime-plugin.beryx.org/releases/latest/ , but I would like to go a step forward and make it modular, so now I am using the Badass JLink Plugin https://badass-jlink-plugin.beryx.org
To go step by step, I downloaded and tested this example: https://github.com/beryx-gist/badass-jlink-example-log4j2-javafx which is similar to my project and I succesfully ran it. Anyway, Eclipse marks lots of errors due to unresolved imports, which I would like to understand how to remove, but indeed the project compiles and runs.
The next step have been to modify this working example by adding the dependencies I need for my real project, which are mainly javax.json and jOpenDocument. The latter cannot be found as a module.
Here is the modified module-info.java
module hellofx {
requires javafx.controls;
requires org.apache.logging.log4j;
requires javax.json;
requires org.glassfish;
exports org.openjfx;
}
and the build.gradle
plugins {
id 'application'
id 'org.javamodularity.moduleplugin' version '1.8.9'
id 'org.openjfx.javafxplugin' version '0.0.10'
id "org.beryx.jlink" version "2.24.1"
}
repositories {
mavenCentral()
}
sourceCompatibility = "11"
targetCompatibility = "11"
dependencies {
implementation 'org.apache.logging.log4j:log4j-core:2.11.1'
implementation 'javax.json:javax.json-api:1.1.4'
implementation 'org.glassfish:javax.json:1.1.4'
implementation 'org.jopendocument:jOpenDocument:1.3'
}
javafx {
version = 16
modules = ['javafx.controls']
}
application {
mainClass = "org.openjfx.HelloFX"
mainModule = "hellofx"
}
The compileJava task fails with the following errors:
C:\Users\xxx\badass-jlink-example-log4j2-javafx-master\src\main\java\module-info.java:5: error: module not found: javax.json
requires javax.json;
^
C:\Users\xxx\badass-jlink-example-log4j2-javafx-master\src\main\java\module-info.java:6: error: module not found: org.glassfish
requires org.glassfish;
does anybody have a hint to start solving this issue?
The problem seemed to be related to the module-info.class file included in the older javax.json imported as org.glassfish:javax.json:1.1.4. The library has been relocated to jakarta and the new one org.glassfish:jakarta.json:2.0.1 does not show the original problem anymore. So the solution is to switch to the newer library.

Gradle repositories conflict forces me to use repository in two places

I have a Gradle multi-project build. Which has a project myApplication that uses a library utils.
The library requires a JasperReports dependency with a custom repository. There is a particular Jasper dependency that produces an error when retrieved from mavenCentral().
If I build utils by itself, it works. Because it fetches the problem jar from the custom repo.
However, if I build myApplication it produces the maven repository error, because it tries to solve the dependency using its mavenCentral() repo.
myApplication/build.gradle.kts:
plugins {
id("application")
}
repositories {
mavenCentral()
}
application {
mainClass.set("com.myapp.SomeMainClass")
}
dependencies {
implementation(project(":utils"))
}
utils/build.gradle.kts:
plugins {
id ("java-library")
}
repositories {
maven {
url = uri("http://jaspersoft.jfrog.io/jaspersoft/third-party-ce-artifacts/")
isAllowInsecureProtocol = true
}
mavenCentral()
}
dependencies {
implementation("net.sf.jasperreports:jasperreports:6.18.1")
}
If I include the custom repository in myApplication/build.gradle.kts the project builds ok, but I think adding the custom repo seems like a bad practice, and I think Gradle documentation discourages it.
I think this is actually using a direct dependency in myApplication instead of fixing a transitive dependency. But of that I'm not so sure, and completely lost on how to solve it. I'm really struggling reading the documentation.
Is there a way for me to have Gradle just compile :utils first, and then have :myAplication use the dependency "as is"?

Gradle project that the dependencies cannot be imported or even not be existed at all

I create a simple Gradle project, then add some dependencies for test, it can build the project normally, but CANNOT use the APIs in class, the gradle.build file:
plugins {
id('java')
id('war')
}
repositories { mavenLocal() mavenCentral() }
// ... other code
dependencies {
providedCompile 'javax.servlet:servlet-api:2.5'
runtime 'javax.servlet:jstl:1.1.2'
}
By the way, it's an old-test Java project, in class file I cannot import the packages like this: import javax.servlet.*;, how to solve? Thanks for any help!
It's so weird, it works today, when I open the project, the all needed libraries appear in the External Libraries, and I can import the classes now.
Why? I already restarted the IDEA and project several times yesterday, but that did not work at all, however, it's automatically solved today.

How to tell Gradle to get sources from project instead of sources jar when adding project dependency?

I have an Android library module that depends on a Kotlin Multiplatform module via project dependency. My issue is that when I try to go to the source of a class, it takes me to the imported sources jar instead of the project that I am depending on. Is it possible to have it take me to the project's source instead of to the sources artifact? My setup:
android-local/build.gradle.kts
dependencies {
api(project(":android-remote", "jvmDefault"))
}
I don't know if this is possible with the multiplatform plugin, but thought I would ask just in case.
In order to get this working correctly first I had to add Kotlin's multiplatform plugin to my Android library module. Then I used the jvmDefault configuration in my dependencies instead of hooking up a specific Android target in my MP project. Here is the build file for my android-local now:
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.multiplatform")
}
android {
//setup
}
kotlin {
android()
sourceSets {
val androidMain by getting {
dependencies {
api(project(":android-remote", "jvmDefault"))
}
}
}
}
And now I can go to sources in the android-remote project (which is a MPP). A bit unintuitive, but it works.

Kissme/Kotlin Multiplatform: Unresolved reference: netguru, Unresolved reference: Kissme

I'm currently working on a Kotlin Multiplatform project (Kotlin 1.3.50, Gradle 3.6.0-beta04) and want to use the Kissme Storage library.
It works on Android as expected, but trying to compile on a Mac for the iOS target, I get
Unresolved reference: netguru
and
Unresolved reference: Kissme
It's mentioned on GitHub, that publishing to maven local could help. But after fetching the git repository, I can't build the library, because there is missing a secret.gradle file.
How can I bring it to work? Is anybody else using this library?
In app's build.gradle:
sourceSets {
commonMain {
dependencies {
implementation 'com.netguru.kissme:common:0.2.5'
}
}
androidMain {
dependencies {
implementation 'com.netguru.kissme:android:0.2.5'
}
}
iosMain {
dependencies {
implementation 'com.netguru.kissme:ios:0.2.5'
}
}

Resources