How Do Transitive Dependencies in KMM and iOS work? - kotlin

Lets say I have a package, Shared Package that is shared with two KMM projects: KMM Project A and KMM Project B.
So we have Shared Package -> KMM Project A and Shared Package -> KMM Project B.
Now I want to use both KMM Project A and KMM Project B in my iOS app. How does that work? Is Shared Package bundled with both frameworks (i.e. I am including the same dependency twice?). Furthermore, does the Shared Package need to be a KMM Project to allow KMM Project A and B to generate the relevant iOS frameworks? Or can it be a pure Kotlin project?
Here is a diagram that might give more explanation of the situation I am trying to understand.

You need a wrapper "unbrella" module that depends on KMM Project A and KMM Project B, and have that generate your Xcode Framework.
You can technically generate 2 frameworks, one for each of the KMM Project A and B, but they will both have a copy of "Shared Package", along with relevant portions of the Kotlin standard lib, and most importantly, those 2 frameworks will be distinct on a binary level, so they can't communicate.
By that I mean, if "Shared Package" has a data class Foo, and you get that as a result from a call to "KMM Project A", say fun makeAFoo():Foo, and you have a function in "KMM Project B" that's defined as fun takeAFoo(foo:Foo), the Foo instance you get from makeAFoo() cannot be passed into takeAFoo(foo:Foo).
So, the short answer is you need a wrapper module that pulls in both of the "Shared Package" modules. You'll also need to export them through the umbrella.
See: https://touchlab.co/multiple-kotlin-frameworks-in-application/ and https://kotlinlang.org/docs/mpp-build-native-binaries.html#export-dependencies-to-binaries

Related

hide one library in another library for application in kotlin

I have a kotlin .aar library A is depency on another library B for extention functions, and my application require to only use library A as dependency. Any suggestion to achieve that the application just add library A as dependency and library B is totally hidden to application.
I was looking at fat aar plugin, but looks like it's not maintained and no longer available.
Right now from my experiment, if library B is not added to application dependency, the application will get exception complain the class in library B is not found.

How should I create my Kotlin multi-module project with Intellij Idea?

I want to create a Kotlin project with Gradle as a build tool that has 3 modules:
A core module that contains the "business logic" (the entities that I will use and all the stuff I need to implement the logic of my app) used by the other modules
A cli module that uses picocli to create a command line utility
A desktop module that uses Jetpack Compose for Desktop to build the UI
Is this a use case for Kotlin Multiplatform?
What (and how) can I do with some kind of wizard and what do I have to do by hand?
And if not Kotlin Multiplatform, how do I setup the whole thing?
Yes, this very much is a use case for Kotlin Multiplatform.
In IntelliJ use the menu to create a new project and select "Kotlin Multiplatform App". That will create the basic structure for you. After that, study study study.

Using kotlinx.coroutines in IntelliJ IDEA project

I am trying to learn coroutines and so I fire up IntelliJ and create a scratch file. But when I type in my coroutines I get compiler complaints such as runBlocking is an unresolved reference. So this is not an android project or any such thing. Just a scratch file in a basic Kotlin project.
How do I bring in the coroutine stuff so I stop getting errors?
runBlocking and other high-level coroutine utilities are not in the Kotlin standard library, but instead are a part of the library kotlinx.coroutines.
To use this library in your project you must download its binaries and add a dependency on them to the project. Usually declaring a library dependency is a line or couple of lines in a build file, if you use build systems like Gradle or Maven. However in a plain IntelliJ project it's possible to get that library from Maven Central almost without hassle:
Open project structure
In the "Modules" page select a module which you use as a context of the scratch file (I suppose there will be just one module).
Switch to "Dependencies" tab and hit the plus button.
then in a context menu select "Library" -> "From Maven"
paste maven coordinates of the kotlinx.coroutines library artifact:
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3
where 1.3.3 is the version of that library. You can find the latest available version here: https://github.com/Kotlin/kotlinx.coroutines/blob/master/README.md
be sure to check "Transitive dependencies" and "Sources" boxes.
After hitting OK the library will be downloaded from Maven Central repository with all its dependencies and added to your module. Then it will be possible to use runBlocking in your project or scratch files.
You should add kotlin coroutines library to your project. The simplest way to do it is to get it from Maven repo. At this moment actual version of library is 1.3.2 The address of library in maven repo you could find here
At moment of writing the address of library is
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2
In plain IDEA IntelliJ project you should make following steps:
1) Go to project structure
2) Then go to Modules page and Dependencies Tab
3) Press "+" button. Select library from "Maven"
4) In search bar use address org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2 of library in maven repo and add it.
5) Press OK then Apply. And recompile your project. That is it. Now you could use coroutines in your project.

Libraries, projects, modules and packages in Intellij Idea

I'm a beginner programmer and I'm learning how to work with Intellij IDEA. A project in IntelliJ IDEA has some different structures like libraries, modules and packages.
Can someone explain what the difference is between those structures and when to use a particular structure? e.g. I can't choose my package name (of a class) arbitrarily when it's already part of a module. What is the connection between those? I'm primarily having difficulties understanding the difference between a package and a module. (characters)
A project in intellij consists of modules. Modules can be java modules, or android modules or whatever. Modules contain your java code and all that stuff. A Module can reference a library which can be a project library or a global library. Global libraries have to be defined only once. Project library in every project you need them.
Packages are a java concept and are IDE independent.
Lets say I wanna do a little game. I would create a intellij Project called "mySuperGame". Then I would create two java modules from intellij, called "logic" and "ui". In the module settings of "ui" I would specify a project library to use opengl and a dep. to "logic". The package name of my logic classes would be "com.mysupergame.logic.XXX".
See http://confluence.jetbrains.com/display/IDEADEV/Structure+of+IntelliJ+IDEA+Project for more information.
IntelliJ IDEA supports everything eclipse has. But vise versa might not be true. Please check this table for the differences. IntelliJ support intelligent perspective and has many windows.
Read the documentation from IntelliJ idea.
Below comparison between Visual Studio (.NET) and IntelliJ (Java), which might be helpful for .NET developers migrating to Java:

How do I combine library code and a maven plugin in same project?

Can I make a single maven project that can be included as a dependency (to reference Java classes inside) and executed as a plugin?
I'm working on a library to help with hosting GWT on a LAMP stack. For someone to use this, they need to extend some Java classes (so it must be a dependency) and they need to invoke a maven plugin (so it needs to be a plugin). The plugin code references the same Java classes, so if they are seperate projects, the plugin one must depend on the library one.
As is, I have the library as a normal maven project, and the plugin as a maven plugin that depends on the library. This means that to do a release, I have to release two different artifacts, and the dependent project must update both version numbers for both artifacts. It'd be nice to have a single project.
You'd be better of by doing the following
project for the jar, Foo:Foo.jar
project that uses Foo:Foo.jar as a
dependency that builds the plugin
Maven parent project that
builds 1&2
The directory structure would look like this
\project\pom.xml
\project\foo\pom.xml
\project\foo\src\main\java\foo.java
\project\plugin\pom.xml
\project\plugin\src\main\resources
\project\plugin\src\main\java
From \project you can do a mvn clean package to build \project\foo\target\foo.jar and \project\plugin\target\plugin.jar
Hope this helps.
If you create a maven plugin it still has a artifactId/groupId/version. There's no reason it can't be references both in your section and in your section. On the other hand, if thats ugly, why not just make a library with the common code that both your main project and your maven plugin project depend on?
EDIT:
Sorry, wasn't clear on the second part. Look into composite maven projects, where there is a top level pom that defines a number of child modules. In this case, the maven plugin and the common library code could be separate children producing separate artifacts, but you only need one version number and one release command executed from the top level. I haven't done this but there are any number of open source projects that do. its often used as an idiom to put testing code into a single module that can be referenced by all the others, without having it go out in any distributable jar.
The best practice is to not do what you're suggesting. Examples of this include PMD, BND, JUnit/TestNG, and so on - no serious projects seem to package the maven plugin with the library proper.
One way to get both alternatives is to use maven assemblies to have two seperate maven projects for each the library proper and the plugin and then a separate packaging as a jar containing the classes from both.