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
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.
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"?
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.
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.
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'
}
}