Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
22 changes: 6 additions & 16 deletions example/javalib/publishing/9-repackage-config/build.mill
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// An alternative way to produce self-executable assemblies is the `RepackageModule` which used the https://docs.spring.io/spring-boot/build-tool-plugin/index.html[Spring Boot Tools suite].
// Instead of copying and merging dependencies classes and resources into a flat jar file, it embeds all dependencies as-is in the final jar.
// One of the pros of this approach is, that all dependency archives are kept unextracted, which makes later introspection for checksums, authorship and copyright questions easier.

//// SNIPPET:BUILD
package build

import mill.*, javalib.*, publish.*
Expand Down Expand Up @@ -43,6 +40,10 @@ Foo.value: <h1>hello</h1>
Bar.value: <p>world</p>
Qux.value: 31337

> ./mill __.test
...Test run foo.FooTests finished: 0 failed, 0 ignored, 1 total, ...s
...Test run bar.BarTests finished: 0 failed, 0 ignored, 1 total, ...s

> ./mill show foo.repackagedJar
".../out/foo/repackagedJar.dest/out.jar"

Expand All @@ -62,15 +63,4 @@ Qux.value: 31337
...BOOT-INF/lib/bar-0.0.1.jar

*/

// *Futher notes:*
//
// * a small wrapper application needs to be added, which is run as entry point and transparently manages loading the embedded jars and running your `main` method.
// This works for all Java (also Scala or Kotlin) applications.
// * It's not necessary to use the Spring Framework in the application.
// * The resulting jar is a self-executable application, but it might not suitable to be used on the classpath of other applications.

// * Since the final jar produced with the `RepackageModule.repackagedJar` task often contains significantly less ZIP entries
// then the jar file produced with `.assembly`, it's possible to workaround
// an https://github.com/com-lihaoyi/mill/issues/2650[issue where `JavaModule.assembly` cannot produce executable assemblies]
// due to some JVM limitations in ZIP file handling of large files.
////SNIPPED:END
15 changes: 15 additions & 0 deletions example/kotlinlib/publishing/9-repackage-config/bar/src/bar/Bar.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package bar

import org.thymeleaf.TemplateEngine
import org.thymeleaf.context.Context

class Bar {
companion object {
@JvmStatic
fun value(): String {
val context = Context()
context.setVariable("text", "world")
return TemplateEngine().process("<p th:text=\"\${text}\"></p>", context)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package bar

import org.junit.Assert.assertEquals
import org.junit.Test

class BarTests {

@Test
fun test() {
assertEquals(Bar.value(), "<p>world</p>")
}
}
69 changes: 69 additions & 0 deletions example/kotlinlib/publishing/9-repackage-config/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//// SNIPPET:BUILD
package build

import mill.*, kotlinlib.*, publish.*
import mill.javalib.repackage.RepackageModule

trait MyModule extends KotlinModule, PublishModule {
def kotlinVersion = "2.2.20"

def publishVersion = "0.0.1"

def pomSettings = PomSettings(
description = "Hello",
organization = "com.lihaoyi",
url = "https://github.com/lihaoyi/example",
licenses = Seq(License.MIT),
versionControl = VersionControl.github("lihaoyi", "example"),
developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
)

def mvnDeps = Seq(mvn"org.thymeleaf:thymeleaf:3.1.1.RELEASE")

object test extends KotlinTests, TestModule.Junit4
}

object foo extends MyModule, RepackageModule { // <1>
def moduleDeps = Seq(bar, qux)
}

object bar extends MyModule {
def moduleDeps = Seq(qux)
}

object qux extends MyModule

// <1> Add the `mill.javalib.repackage.RepackageModule` to the executable module.

/** Usage

> ./mill foo.run
Foo.value: <h1>hello</h1>
Bar.value: <p>world</p>
Qux.value: 31337

> ./mill -j1 __.test
...Test run foo.FooTests finished: 0 failed, 0 ignored, 1 total, ...s
...Test run bar.BarTests finished: 0 failed, 0 ignored, 1 total, ...s

> ./mill show foo.repackagedJar
".../out/foo/repackagedJar.dest/out.jar"

> ./out/foo/repackagedJar.dest/out.jar
Foo.value: <h1>hello</h1>
Bar.value: <p>world</p>
Qux.value: 31337

> unzip -l ./out/foo/repackagedJar.dest/out.jar "BOOT-INF/lib*"
...BOOT-INF/lib/kotlin-stdlib-2.2.20.jar
...BOOT-INF/lib/thymeleaf-3.1.1.RELEASE.jar
...BOOT-INF/lib/ognl-3.3.4.jar
...BOOT-INF/lib/attoparser-2.0.6.RELEASE.jar
...BOOT-INF/lib/unbescape-1.1.6.RELEASE.jar
...BOOT-INF/lib/slf4j-api-2.0.5.jar
...BOOT-INF/lib/javassist-3.29.0-GA.jar
...BOOT-INF/lib/qux-0.0.1.jar
...BOOT-INF/lib/bar-0.0.1.jar

*/
//// SNIPPET:END
14 changes: 14 additions & 0 deletions example/kotlinlib/publishing/9-repackage-config/foo/src/foo/Foo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package foo

public class Foo {
companion object {
val value = "<h1>hello</h1>"

@JvmStatic
fun main(args: Array<String>) {
println("Foo.value: " + Foo.value)
println("Bar.value: " + bar.Bar.value())
println("Qux.value: " + qux.Qux.value)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package foo

import org.junit.Assert.assertEquals
import org.junit.Test

class FooTests {

@Test
fun test() {
assertEquals(Foo.value, "<h1>hello</h1>")
}
}
12 changes: 12 additions & 0 deletions example/kotlinlib/publishing/9-repackage-config/qux/src/qux/Qux.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package qux

public class Qux {
companion object {
val value = 31337

@JvmStatic
fun main(args: Array<String>) {
println("Qux.value: " + Qux.value)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package bar

import org.thymeleaf.TemplateEngine
import org.thymeleaf.context.Context

object Bar {
def value: String = {
val context = Context()
context.setVariable("text", "world")
TemplateEngine().process("<p th:text=\"${text}\"></p>", context)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package bar

import org.junit.Assert.assertEquals

import org.junit.Test

class BarTests {

@Test
def test() = {
assertEquals(Bar.value, "<p>world</p>")
}

}
85 changes: 85 additions & 0 deletions example/scalalib/publishing/9-repackage-config/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// An alternative way to produce self-executable assemblies is the `RepackageModule` which used the https://docs.spring.io/spring-boot/build-tool-plugin/index.html[Spring Boot Tools suite].
// Instead of copying and merging dependencies classes and resources into a flat jar file, it embeds all dependencies as-is in the final jar.
// One of the pros of this approach is, that all dependency archives are kept unextracted, which makes later introspection for checksums, authorship and copyright questions easier.

//// SNIPPET:BUILD
package build

import mill.*, scalalib.*, publish.*
import mill.javalib.repackage.RepackageModule

trait MyModule extends ScalaModule, PublishModule {
def scalaVersion = "3.7.3"

def publishVersion = "0.0.1"

def pomSettings = PomSettings(
description = "Hello",
organization = "com.lihaoyi",
url = "https://github.com/lihaoyi/example",
licenses = Seq(License.MIT),
versionControl = VersionControl.github("lihaoyi", "example"),
developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
)

def mvnDeps = Seq(mvn"org.thymeleaf:thymeleaf:3.1.1.RELEASE")

object test extends ScalaTests, TestModule.Junit4
}

object foo extends MyModule, RepackageModule { // <1>
def moduleDeps = Seq(bar, qux)
}

object bar extends MyModule {
def moduleDeps = Seq(qux)
}

object qux extends MyModule

// <1> Add the `mill.javalib.repackage.RepackageModule` to the executable module.

/** Usage

> ./mill foo.run
Foo.value: <h1>hello</h1>
Bar.value: <p>world</p>
Qux.value: 31337

> ./mill __.test
...Test run foo.FooTests finished: 0 failed, 0 ignored, 1 total, ...s
...Test run bar.BarTests finished: 0 failed, 0 ignored, 1 total, ...s

> ./mill show foo.repackagedJar
".../out/foo/repackagedJar.dest/out.jar"

> ./out/foo/repackagedJar.dest/out.jar
Foo.value: <h1>hello</h1>
Bar.value: <p>world</p>
Qux.value: 31337

> unzip -l ./out/foo/repackagedJar.dest/out.jar "BOOT-INF/lib*"
...BOOT-INF/lib/scala3-library_3-3.7.3.jar
...BOOT-INF/lib/thymeleaf-3.1.1.RELEASE.jar
...BOOT-INF/lib/ognl-3.3.4.jar
...BOOT-INF/lib/attoparser-2.0.6.RELEASE.jar
...BOOT-INF/lib/unbescape-1.1.6.RELEASE.jar
...BOOT-INF/lib/slf4j-api-2.0.5.jar
...BOOT-INF/lib/javassist-3.29.0-GA.jar
...BOOT-INF/lib/qux_3-0.0.1.jar
...BOOT-INF/lib/bar_3-0.0.1.jar

*/
//// SNIPPET:END

// *Futher notes:*
//
// * a small wrapper application needs to be added, which is run as entry point and transparently manages loading the embedded jars and running your `main` method.
// This works for all Java (also Scala or Kotlin) applications.
// * It's not necessary to use the Spring Framework in the application.
// * The resulting jar is a self-executable application, but it might not suitable to be used on the classpath of other applications.

// * Since the final jar produced with the `RepackageModule.repackagedJar` task often contains significantly less ZIP entries
// then the jar file produced with `.assembly`, it's possible to workaround
// an https://github.com/com-lihaoyi/mill/issues/2650[issue where `JavaModule.assembly` cannot produce executable assemblies]
// due to some JVM limitations in ZIP file handling of large files.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package foo

object Foo {
val value = "<h1>hello</h1>"

def main(args: Array[String]): Unit = {
println("Foo.value: " + Foo.value)
println("Bar.value: " + bar.Bar.value)
println("Qux.value: " + qux.Qux.value)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package foo

import org.junit.Assert.assertEquals

import org.junit.Test

class FooTests {

@Test
def test() = {
assertEquals(Foo.value, "<h1>hello</h1>")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package qux

object Qux {
val value = 31337
def main(args: Array[String]): Unit = {
println("Qux.value: " + Qux.value)
}
}
5 changes: 3 additions & 2 deletions website/docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
** xref:javalib/publishing.adoc[]
** xref:javalib/build-examples.adoc[]
** xref:javalib/web-examples.adoc[]
** xref:javalib/springboot-examples.adoc[]
** xref:javalib/spring-boot.adoc[]
* xref:scalalib/intro.adoc[]
** xref:scalalib/config.adoc[]
** xref:scalalib/script.adoc[]
Expand All @@ -26,6 +26,7 @@
** xref:scalalib/web-examples.adoc[]
** xref:scalalib/native-examples.adoc[]
** xref:scalalib/spark.adoc[]
** xref:scalalib/spring-boot.adoc[]
* xref:kotlinlib/intro.adoc[]
** xref:kotlinlib/config.adoc[]
** xref:kotlinlib/script.adoc[]
Expand All @@ -36,7 +37,7 @@
** xref:kotlinlib/publishing.adoc[]
// ** xref:kotlinlib/build-examples.adoc[]
** xref:kotlinlib/web-examples.adoc[]
** xref:kotlinlib/springboot-examples.adoc[]
** xref:kotlinlib/spring-boot.adoc[]
[]
* Experimental Platform Support
** Building Android Apps
Expand Down
25 changes: 25 additions & 0 deletions website/docs/modules/ROOT/pages/javalib/spring-boot.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
= Spring Framework / Spring Boot Projects
:page-aliases: Spring_Boot_Java.adoc
:language-small: java

include::partial$Spring_Header.adoc[]

// This page contains examples of providing Mill as a build tool for Spring Boot applications, adapting the official Spring Boot documentation in increasing complexity.


== Spring Boot Web with Initializr

include::partial$example/springboot/java/1-web-initializr.adoc[]


[#_spring_boot_hello_world_app]
== Spring Boot Hello World App

include::partial$example/javalib/web/2-hello-spring-boot.adoc[]


[#_spring_boot_todomvc_app]
== Spring Boot TodoMvc App


include::partial$example/javalib/web/3-todo-spring-boot.adoc[]

This file was deleted.

Loading
Loading