Ray Rahke
04/18/2024, 6:40 AMgradle init
. All good, except I dislike the default directory structure. I don't want src/main/kotlin/ whatever. I just want src/main.kt.
I've forgotten how to do that. And I don't know how to quickly find the answer.
This seems like a real problem with gradle, that it is so dependent on memory.
I really wish kotlin had it's own build tool. like swift.Vampire
04/18/2024, 6:51 AMkotlin.sourceSets.main.kotlin.srcDir("src")
.
What would you win with an own build tool? The Kotlin developers could not concentrate on Kotlin as they also had to maintain the build tool. It's development would any way be less active than Gradle`s, as there the build tool is the main product. Everyone starting with Kotlin would have to learn a new tool instead of using the existing knowledge. You would loose it split all the plugin development out there. I honestly only see drawbacks if Kotlin had it's own build tool.Ray Rahke
04/18/2024, 6:56 AMRay Rahke
04/18/2024, 6:56 AMRay Rahke
04/18/2024, 6:56 AMRay Rahke
04/18/2024, 6:57 AMRay Rahke
04/18/2024, 6:57 AMRay Rahke
04/18/2024, 6:58 AMhfhbd
04/18/2024, 7:11 AMRay Rahke
04/18/2024, 7:14 AMRay Rahke
04/18/2024, 7:15 AMapplication {
// Define the main class for the application.
mainClass = "org.example.AppKt"
}
i dont understand main class. what if my main does not have a class?hfhbd
04/18/2024, 7:22 AMapp
. I guess, the init project is structured in this way to easily add more subprojects in the future.
If you don’t need an app subproject, you could also use the root project.hfhbd
04/18/2024, 7:23 AMhfhbd
04/18/2024, 7:26 AMhfhbd
04/18/2024, 7:28 AMMainKt
, because the Kotlin compiler creates an JVM class under the hood.Ray Rahke
04/18/2024, 7:33 AMBTW regarding main class: If you want to write a top level main function in Kotlin, you need to specify the Kotlin file name in PascalCase and add a Kt suffix: likestuff like this is why gradle is so hard. Where and when would I have ever learned that?, because the Kotlin compiler creates an JVM class under the hood.MainKt
Ray Rahke
04/18/2024, 7:33 AMhfhbd
04/18/2024, 7:35 AMstuff like this is why gradle is so hard.That's unrelated to Gradle but to Kotlin. Yes, JetBrains could create another Gradle plugin:
kotlin-application
, but this adds another complexity 🙂Ray Rahke
04/18/2024, 7:37 AMRay Rahke
04/18/2024, 7:37 AMRay Rahke
04/18/2024, 7:38 AMhfhbd
04/18/2024, 7:43 AMVampire
04/18/2024, 7:46 AMapp
instead of having the source directly in the root project.
But also here, it just is a sane default where you then can easily add other subprojects without moving things around.
> this dir structure is complete overkill
I usually just use init
to generate a basic
project, so practically the wrapper files and nearly empty settings and build script in the root project
and then just configure the build like I want or need it.
> and have my own organization ?
It's just best practice to use a namespace for own classes in each and every JVM code you write, be it Java or Kotlin.
And common convention to use some Domainname you own and reverse it for the beginning of the package name,
or similar io.github.youusername....
assuming you do not change your username.
> You don’t need package folders in Kotlin, you can remove them. It’s even the official code style.
Which is insane imho. 😄
> why is build.gradle.kts inside of app/ instead of root, when settings.gradle.kts is in root?
Like I said above. The init
creates the app
subproject that is then included in the settings script, so that you can easily add other subproject like one dedicated for docs, or for systemtests, or whatever else you need. If you don't like it, just change it.
Just move all stuff from app
up one level and remove the include from the settings script.
> i dont understand main class. what if my main does not have a class?
It always has.
In the example the main function is directly top-level in org/example/App.kt
which makes it part of the class AppKt
after compilation.
This is not about Kotlin class, but about JVM class where it ultimately ends so that you can start it when invoking the runtime.
This is simply releated to the target environment for which you code the Kotlin which in your case is the JVMRay Rahke
04/18/2024, 7:46 AMBut you do want to target the JVM and use the Java stdlib? Without knowledge of the JVM/Java?no, not really. I picked Kotlin because it had a language feature set and syntax that I found very attractive. I have little interest in JVM compatibility and android development.
Ray Rahke
04/18/2024, 7:47 AMVampire
04/18/2024, 7:47 AMVampire
04/18/2024, 7:48 AMRay Rahke
04/18/2024, 7:55 AM/*
* This file was generated by the Gradle 'init' task.
*
* This is a general purpose Gradle build.
* To learn more about Gradle by exploring our Samples at <https://docs.gradle.org/8.6/samples>
* This project uses @Incubating APIs which are subject to change.
*/
Ray Rahke
04/18/2024, 7:55 AMRay Rahke
04/18/2024, 7:56 AMsourceSets {
main {
kotlin.srcDir("src/")
}
}
Adam S
04/18/2024, 7:57 AMVampire
04/18/2024, 7:58 AMRay Rahke
04/18/2024, 7:59 AMAdam S
04/18/2024, 8:01 AMVampire
04/18/2024, 8:01 AMbasic
the build script of course is empty, you told it to create a basic Gradle build without any opinion.
You can then follow the Kotlin documentation what to configure.
Unless the issue for Gradle is resolved that custom init-task-templates can be used, you have to live with either minimal project or opinionated project that you don't like.
If Kotlin would provide an own build tool it would be the same though.
Conventions and defaults are never liked by all users.Ray Rahke
04/18/2024, 8:03 AMRay Rahke
04/18/2024, 8:03 AMRay Rahke
04/18/2024, 8:03 AMRay Rahke
04/18/2024, 8:03 AMRay Rahke
04/18/2024, 8:04 AMAdam S
04/18/2024, 8:04 AMsourceSets {
main {
kotlin.setSrcDirs(listOf("src"))
resources.setSrcDirs(listOf("resources"))
java.setSrcDirs(emptyList<String>())
}
test {
kotlin.setSrcDirs(listOf("testSrc"))
resources.setSrcDirs(listOf("testResources"))
java.setSrcDirs(emptyList<String>())
}
}
It's nicer to use setSrcDirs
because it means that it will remove the default (e.g. src/main/kotlin). And if you don't have Java, then it's nice to remove the Java dirs by setting an empty list.Ray Rahke
04/18/2024, 8:05 AMBuild file '/Users/ray/test/build.gradle.kts' line: 1
* What went wrong:
Script compilation errors:
Line 1: sourceSets {
^ Unresolved reference: sourceSets
Ray Rahke
04/18/2024, 8:05 AMAdam S
04/18/2024, 8:06 AMplugins {}
block)?Ray Rahke
04/18/2024, 8:06 AMplugins {
kotlin("jvm") version "1.9.23"
}
sourceSets.main {
java.srcDirs("src/main/myJava", "src/main/myKotlin")
}
hfhbd
04/18/2024, 8:08 AMRay Rahke
04/18/2024, 8:09 AMRay Rahke
04/18/2024, 8:09 AMAdam S
04/18/2024, 8:10 AMAdam S
04/18/2024, 8:10 AMRay Rahke
04/18/2024, 8:10 AM------------------------------------------------------------
Gradle 8.6
------------------------------------------------------------
Build time: 2024-02-02 16:47:16 UTC
Revision: d55c486870a0dc6f6278f53d21381396d0741c6e
Kotlin: 1.9.20
Groovy: 3.0.17
Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM: 21.0.2 (Homebrew 21.0.2)
OS: Mac OS X 14.2.1 aarch64
Adam S
04/18/2024, 8:12 AMRay Rahke
04/18/2024, 8:13 AMplugins {
kotlin("jvm") version "1.9.23"
}
sourceSets.main {
java.srcDirs("src/main/myJava", "src/main/myKotlin")
}
Ray Rahke
04/18/2024, 8:14 AMplugins {
kotlin("jvm") version "1.9.23"
}
sourceSets {
main {
java.srcDirs("src/main/myJava", "src/main/myKotlin")
}
}
gives
* What went wrong:
Task 'run' not found in root project 'test'.
* Try:
> Run gradlew tasks to get a list of available tasks.
Adam S
04/18/2024, 8:14 AMRay Rahke
04/18/2024, 8:15 AMAdam S
04/18/2024, 8:15 AMRay Rahke
04/18/2024, 8:15 AMAdam S
04/18/2024, 8:16 AMgradle run
you need to add the application plugin, and specify a main class
https://kotlinlang.org/docs/get-started-with-jvm-gradle-project.html#explore-the-build-scriptRay Rahke
04/18/2024, 8:17 AMhfhbd
04/18/2024, 8:17 AMRay Rahke
04/18/2024, 8:17 AMAdam S
04/18/2024, 8:17 AMplugins {
kotlin("jvm") version "1.9.23"
application
}
sourceSets.main {
java.srcDirs("src/main/myJava", "src/main/myKotlin")
}
application {
mainClass.set("my.package.MainKt") // The main class of the application
}
This assumes you have a file src/main/myKotlin/main.kt
, with package my.package
at the top, and a fun main() {}
Ray Rahke
04/18/2024, 8:17 AMAdam S
04/18/2024, 8:18 AM.kt
files into .class
files, and packages them into a .jar
Ray Rahke
04/18/2024, 8:18 AMjava.srcDirs("src/main/myJava", "src/main/myKotlin")
why is this in java.srcDirsRay Rahke
04/18/2024, 8:18 AMAdam S
04/18/2024, 8:19 AMjava.srcDirs()
example is? I agree, it's confusing without context.Adam S
04/18/2024, 8:21 AMKotlin sources and Java sources can be stored in the same directory, or they can be placed in different directories.So I think the point of the example is to demonstrate how the directory names don't have to be strict. It's not an example of best practice. But the example doesn't make that clear, so I'm not sure...
Ray Rahke
04/18/2024, 8:24 AMRay Rahke
04/18/2024, 8:24 AMAdam S
04/18/2024, 8:30 AMRay Rahke
04/18/2024, 8:30 AMRay Rahke
04/18/2024, 8:30 AMRay Rahke
04/18/2024, 8:31 AMAdam S
04/18/2024, 8:31 AMRay Rahke
04/18/2024, 8:31 AMRay Rahke
04/18/2024, 8:31 AMRay Rahke
04/18/2024, 8:32 AMRay Rahke
04/18/2024, 8:32 AMRay Rahke
04/18/2024, 8:32 AMRay Rahke
04/18/2024, 8:33 AM* What went wrong:
Execution failed for task ':run'.
> Could not resolve all files for configuration ':runtimeClasspath'.
> Cannot resolve external dependency org.jetbrains.kotlin:kotlin-stdlib:1.9.23 because no repositories are defined.
Required by:
project :
Ray Rahke
04/18/2024, 8:34 AMRay Rahke
04/18/2024, 8:34 AMRay Rahke
04/18/2024, 8:35 AMRay Rahke
04/18/2024, 8:35 AMRay Rahke
04/18/2024, 8:38 AMVampire
04/18/2024, 8:41 AMalso I still dont understandjava.srcDirs("src/main/myJava", "src/main/myKotlin")
why is this in java.srcDirsI guess this is meant for when you mix Java and Kotlin and want to also have them side-by-side, so putting your Java classes into
src/main/myKotlin
too.
But that's something to complain to the Kotlin docs that they don't make clear for which situation that snippet is meant.