Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kotlinlib example/module examples #3585

Merged
merged 5 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions example/kotlinlib/module/1-compilation-execution-flags/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//// SNIPPET:BUILD
package build
import mill._, kotlinlib._

object `package` extends RootModule with KotlinModule {

def kotlinVersion = "1.9.24"

def mainClass = Some("foo.FooKt")

def forkArgs = Seq("-Xmx4g", "-Dmy.jvm.property=hello")
def forkEnv = Map("MY_ENV_VAR" -> "WORLD")

def kotlincOptions = super.kotlincOptions() ++ Seq("-Werror")
}

//// SNIPPET:END
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package foo

fun main() {
val jvmProperty = System.getProperty("my.jvm.property")
val envVar = System.getenv("MY_ENV_VAR")
println("$jvmProperty $envVar")
}
20 changes: 20 additions & 0 deletions example/kotlinlib/module/10-downloading-non-maven-jars/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//// SNIPPET:BUILD
package build
import mill._, kotlinlib._

object `package` extends RootModule with KotlinModule {

def kotlinVersion = "1.9.24"

def mainClass = Some("foo.FooKt")

def unmanagedClasspath = T {
os.write(
T.dest / "fastjavaio.jar",
requests.get.stream(
"https://github.com/williamfiset/FastJavaIO/releases/download/1.1/fastjavaio.jar"
)
)
Agg(PathRef(T.dest / "fastjavaio.jar"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package foo

import com.williamfiset.fastjavaio.InputReader

import java.io.FileInputStream
import java.io.IOException

fun main(args: Array<String>) {
val filePath = args[0]
val fi = try {
InputReader(FileInputStream(filePath))
} catch (e: IOException) {
e.printStackTrace()
null
}

var line: String? = fi?.nextLine()
while (line != null) {
println(line)
line = fi?.nextLine()
}

try {
fi?.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
I am cow
hear me moo
I weigh twice as much as you
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bar Application Conf
27 changes: 27 additions & 0 deletions example/kotlinlib/module/11-assembly-config/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//// SNIPPET:BUILD
package build
import mill._, kotlinlib._
import mill.javalib.Assembly._

object foo extends KotlinModule {

def kotlinVersion = "1.9.24"

def mainClass = Some("foo.FooKt")

def moduleDeps = Seq(bar)
def assemblyRules = Seq(
// all application.conf files will be concatenated into single file
Rule.Append("application.conf"),
// all *.conf files will be concatenated into single file
Rule.AppendPattern(".*\\.conf"),
// all *.temp files will be excluded from a final jar
Rule.ExcludePattern(".*\\.temp"),
// the `shapeless` package will be shaded under the `shade` package
Rule.Relocate("shapeless.**", "shade.shapless.@1")
)
}

object bar extends KotlinModule {
def kotlinVersion = "1.9.24"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Foo Application Conf
15 changes: 15 additions & 0 deletions example/kotlinlib/module/11-assembly-config/foo/src/foo/Foo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package foo

import java.io.IOException
import java.io.InputStream

fun main(args: Array<String>) {
::main.javaClass
.classLoader
.getResourceAsStream("application.conf")
.use {
val conf = it.readAllBytes().toString(Charsets.UTF_8)
println("Loaded application.conf from resources: $conf")
}

}
40 changes: 40 additions & 0 deletions example/kotlinlib/module/12-repository-config/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//// SNIPPET:BUILD1
package build
import mill._, kotlinlib._
import mill.javalib.{ZincWorkerModule, CoursierModule}
import mill.define.ModuleRef
import coursier.maven.MavenRepository

val sonatypeReleases = Seq(
MavenRepository("https://oss.sonatype.org/content/repositories/releases")
)

object foo extends KotlinModule {

def mainClass = Some("foo.FooKt")

def kotlinVersion = "1.9.24"

def ivyDeps = Agg(
ivy"com.github.ajalt.clikt:clikt-jvm:4.4.0",
ivy"org.jetbrains.kotlinx:kotlinx-html-jvm:0.11.0"
)

def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases }
}

//// SNIPPET:BUILD2

object CustomZincWorkerModule extends ZincWorkerModule with CoursierModule {
def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases }
}

object bar extends KotlinModule {

def kotlinVersion = "1.9.24"

def zincWorker = ModuleRef(CustomZincWorkerModule)
// ... rest of your build definitions

def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases }
}
18 changes: 18 additions & 0 deletions example/kotlinlib/module/12-repository-config/foo/src/foo/Foo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package foo

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.required
import foo.main as fooMain
import kotlinx.html.h1
import kotlinx.html.stream.createHTML

class Foo : CliktCommand() {
val text by option("--text").required()

override fun run() {
println(createHTML(prettyPrint = false).h1 { text(text) }.toString())
}
}

fun main(args: Array<String>) = Foo().main(args)
78 changes: 78 additions & 0 deletions example/kotlinlib/module/13-jni/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package build
import mill._, kotlinlib._, util.Jvm

object `package` extends RootModule with KotlinModule {

def mainClass = Some("foo.HelloWorldKt")

def kotlinVersion = "1.9.24"

// Additional source folder to put C sources
def nativeSources = T.sources(millSourcePath / "native-src")

// Compile C
def nativeCompiled = T{
val cSourceFiles = nativeSources().map(_.path).flatMap(os.walk(_)).filter(_.ext == "c")
val output = "libhelloworld.so"
os.proc(
"clang", "-shared", "-fPIC",
"-I" + sys.props("java.home") + "/include/", // global JVM header files
"-I" + sys.props("java.home") + "/include/darwin",
"-I" + sys.props("java.home") + "/include/linux",
"-o", T.dest / output,
cSourceFiles
)
.call(stdout = os.Inherit)

PathRef(T.dest / output)
}

def forkEnv = Map("HELLO_WORLD_BINARY" -> nativeCompiled().path.toString)

object test extends KotlinModuleTests with TestModule.Junit5 {
def ivyDeps = super.ivyDeps() ++ Agg(
ivy"io.kotest:kotest-runner-junit5-jvm:5.9.1"
)
def forkEnv = Map("HELLO_WORLD_BINARY" -> nativeCompiled().path.toString)
}
}

// This is an example of how use Mill to compile C code together with your Kotlin
// code using JNI. There are three two steps: defining the C source folder,
// and then compiling the C code using `clang`. After that we have the
// `libhelloworld.so` on disk ready to use, and in this example we use an
// environment variable to pass the path of that file to the application
// code to load it using `System.load`.
//
// The above builds expect the following project layout:
//
// ----
// build.mill
// src/
// foo/
// HelloWorld.kt
//
// native-src/
// HelloWorld.c
//
// test/
// src/
// foo/
// HelloWorldTest.kt
// ----
//
// This example is pretty minimal, but it demonstrates the core principles, and
// can be extended if necessary to more elaborate use cases. The `native*` tasks
// can also be extracted out into a `trait` for re-use if you have multiple
// `KotlinModule`s that need native C components.

/** Usage

> ./mill run
Hello, World!

> ./mill test
Test foo.HelloWorldTestsimple started
Test foo.HelloWorldTestsimple finished...
...
*/
7 changes: 7 additions & 0 deletions example/kotlinlib/module/13-jni/native-src/HelloWorld.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <jni.h>
#include <string.h>

// Implementation of the native method
JNIEXPORT jstring JNICALL Java_foo_HelloWorld_sayHello(JNIEnv *env, jobject obj) {
return (*env)->NewStringUTF(env, "Hello, World!");
}
19 changes: 19 additions & 0 deletions example/kotlinlib/module/13-jni/src/foo/HelloWorld.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package foo

class HelloWorld {
// Declare a native method
external fun sayHello(): String

// Load the native library
companion object {
init {
System.load(System.getenv("HELLO_WORLD_BINARY"))
}
}
}


fun main(args: Array<String>) {
val helloWorld = HelloWorld()
println(helloWorld.sayHello())
}
10 changes: 10 additions & 0 deletions example/kotlinlib/module/13-jni/test/src/foo/HelloWorldTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package foo

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe

class HelloWorldTest : FunSpec({
test("simple") {
HelloWorld().sayHello() shouldBe "Hello, World!"
}
})
24 changes: 24 additions & 0 deletions example/kotlinlib/module/2-ivy-deps/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//// SNIPPET:BUILD
package build
import mill._, kotlinlib._

object `package` extends RootModule with KotlinModule {

def kotlinVersion = "1.9.24"

def mainClass = Some("foo.FooKt")

def ivyDeps = Agg(
ivy"com.fasterxml.jackson.core:jackson-databind:2.13.4",
)
}

//// SNIPPET:SCALAIVY

//// SNIPPET:USAGE
/** Usage

> ./mill run i am cow
JSONified using Jackson: ["i","am","cow"]

*/
9 changes: 9 additions & 0 deletions example/kotlinlib/module/2-ivy-deps/src/foo/Foo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package foo

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature

fun main(args: Array<String>) {
val value = ObjectMapper().writeValueAsString(args)
println("JSONified using Jackson: $value")
}
28 changes: 28 additions & 0 deletions example/kotlinlib/module/3-run-compile-deps/bar/src/bar/Bar.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package bar

import javax.servlet.ServletException
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.io.IOException
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.servlet.ServletContextHandler
import org.eclipse.jetty.servlet.ServletHolder

class BarServlet : HttpServlet() {
protected override fun doGet(request: HttpServletRequest, response: HttpServletResponse) {
response.setContentType("text/html")
response.setStatus(HttpServletResponse.SC_OK)
response.getWriter().println("<html><body>Hello World!</body></html>")
}
}

fun main(args: Array<String>) {
val server = Server(8079)
val context = ServletContextHandler()
context.setContextPath("/")
server.setHandler(context)
context.addServlet(ServletHolder(BarServlet()), "/*")
server.start()
server.join()
}
Loading
Loading