Skip to content

Commit b1c4a83

Browse files
lefouautofix-ci[bot]lihaoyi
authored
Improve Spring docs (#6071)
* Add general notes about Spring and Mill * Add `RepackageModule` docs for Scala and Kotlin with their specific examples * Move all spring project examples to Spring landing pages --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Li Haoyi <[email protected]>
1 parent 83ad1bc commit b1c4a83

File tree

26 files changed

+439
-64
lines changed

26 files changed

+439
-64
lines changed

example/javalib/publishing/9-repackage-config/build.mill

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
// 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].
2-
// Instead of copying and merging dependencies classes and resources into a flat jar file, it embeds all dependencies as-is in the final jar.
3-
// 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.
4-
1+
//// SNIPPET:BUILD
52
package build
63

74
import mill.*, javalib.*, publish.*
@@ -43,6 +40,10 @@ Foo.value: <h1>hello</h1>
4340
Bar.value: <p>world</p>
4441
Qux.value: 31337
4542

43+
> ./mill __.test
44+
...Test run foo.FooTests finished: 0 failed, 0 ignored, 1 total, ...s
45+
...Test run bar.BarTests finished: 0 failed, 0 ignored, 1 total, ...s
46+
4647
> ./mill show foo.repackagedJar
4748
".../out/foo/repackagedJar.dest/out.jar"
4849

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

6465
*/
65-
66-
// *Futher notes:*
67-
//
68-
// * 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.
69-
// This works for all Java (also Scala or Kotlin) applications.
70-
// * It's not necessary to use the Spring Framework in the application.
71-
// * The resulting jar is a self-executable application, but it might not suitable to be used on the classpath of other applications.
72-
73-
// * Since the final jar produced with the `RepackageModule.repackagedJar` task often contains significantly less ZIP entries
74-
// then the jar file produced with `.assembly`, it's possible to workaround
75-
// an https://github.com/com-lihaoyi/mill/issues/2650[issue where `JavaModule.assembly` cannot produce executable assemblies]
76-
// due to some JVM limitations in ZIP file handling of large files.
66+
////SNIPPED:END
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package bar
2+
3+
import org.thymeleaf.TemplateEngine
4+
import org.thymeleaf.context.Context
5+
6+
class Bar {
7+
companion object {
8+
@JvmStatic
9+
fun value(): String {
10+
val context = Context()
11+
context.setVariable("text", "world")
12+
return TemplateEngine().process("<p th:text=\"\${text}\"></p>", context)
13+
}
14+
}
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package bar
2+
3+
import org.junit.Assert.assertEquals
4+
import org.junit.Test
5+
6+
class BarTests {
7+
8+
@Test
9+
fun test() {
10+
assertEquals(Bar.value(), "<p>world</p>")
11+
}
12+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//// SNIPPET:BUILD
2+
package build
3+
4+
import mill.*, kotlinlib.*, publish.*
5+
import mill.javalib.repackage.RepackageModule
6+
7+
trait MyModule extends KotlinModule, PublishModule {
8+
def kotlinVersion = "2.2.20"
9+
10+
def publishVersion = "0.0.1"
11+
12+
def pomSettings = PomSettings(
13+
description = "Hello",
14+
organization = "com.lihaoyi",
15+
url = "https://github.com/lihaoyi/example",
16+
licenses = Seq(License.MIT),
17+
versionControl = VersionControl.github("lihaoyi", "example"),
18+
developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
19+
)
20+
21+
def mvnDeps = Seq(mvn"org.thymeleaf:thymeleaf:3.1.1.RELEASE")
22+
23+
object test extends KotlinTests, TestModule.Junit4
24+
}
25+
26+
object foo extends MyModule, RepackageModule { // <1>
27+
def moduleDeps = Seq(bar, qux)
28+
}
29+
30+
object bar extends MyModule {
31+
def moduleDeps = Seq(qux)
32+
}
33+
34+
object qux extends MyModule
35+
36+
// <1> Add the `mill.javalib.repackage.RepackageModule` to the executable module.
37+
38+
/** Usage
39+
40+
> ./mill foo.run
41+
Foo.value: <h1>hello</h1>
42+
Bar.value: <p>world</p>
43+
Qux.value: 31337
44+
45+
> ./mill -j1 __.test
46+
...Test run foo.FooTests finished: 0 failed, 0 ignored, 1 total, ...s
47+
...Test run bar.BarTests finished: 0 failed, 0 ignored, 1 total, ...s
48+
49+
> ./mill show foo.repackagedJar
50+
".../out/foo/repackagedJar.dest/out.jar"
51+
52+
> ./out/foo/repackagedJar.dest/out.jar
53+
Foo.value: <h1>hello</h1>
54+
Bar.value: <p>world</p>
55+
Qux.value: 31337
56+
57+
> unzip -l ./out/foo/repackagedJar.dest/out.jar "BOOT-INF/lib*"
58+
...BOOT-INF/lib/kotlin-stdlib-2.2.20.jar
59+
...BOOT-INF/lib/thymeleaf-3.1.1.RELEASE.jar
60+
...BOOT-INF/lib/ognl-3.3.4.jar
61+
...BOOT-INF/lib/attoparser-2.0.6.RELEASE.jar
62+
...BOOT-INF/lib/unbescape-1.1.6.RELEASE.jar
63+
...BOOT-INF/lib/slf4j-api-2.0.5.jar
64+
...BOOT-INF/lib/javassist-3.29.0-GA.jar
65+
...BOOT-INF/lib/qux-0.0.1.jar
66+
...BOOT-INF/lib/bar-0.0.1.jar
67+
68+
*/
69+
//// SNIPPET:END
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package foo
2+
3+
public class Foo {
4+
companion object {
5+
val value = "<h1>hello</h1>"
6+
7+
@JvmStatic
8+
fun main(args: Array<String>) {
9+
println("Foo.value: " + Foo.value)
10+
println("Bar.value: " + bar.Bar.value())
11+
println("Qux.value: " + qux.Qux.value)
12+
}
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package foo
2+
3+
import org.junit.Assert.assertEquals
4+
import org.junit.Test
5+
6+
class FooTests {
7+
8+
@Test
9+
fun test() {
10+
assertEquals(Foo.value, "<h1>hello</h1>")
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package qux
2+
3+
public class Qux {
4+
companion object {
5+
val value = 31337
6+
7+
@JvmStatic
8+
fun main(args: Array<String>) {
9+
println("Qux.value: " + Qux.value)
10+
}
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package bar
2+
3+
import org.thymeleaf.TemplateEngine
4+
import org.thymeleaf.context.Context
5+
6+
object Bar {
7+
def value: String = {
8+
val context = Context()
9+
context.setVariable("text", "world")
10+
TemplateEngine().process("<p th:text=\"${text}\"></p>", context)
11+
}
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package bar
2+
3+
import org.junit.Assert.assertEquals
4+
5+
import org.junit.Test
6+
7+
class BarTests {
8+
9+
@Test
10+
def test() = {
11+
assertEquals(Bar.value, "<p>world</p>")
12+
}
13+
14+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// 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].
2+
// Instead of copying and merging dependencies classes and resources into a flat jar file, it embeds all dependencies as-is in the final jar.
3+
// 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.
4+
5+
//// SNIPPET:BUILD
6+
package build
7+
8+
import mill.*, api.*, scalalib.*, publish.*
9+
import mill.javalib.repackage.RepackageModule
10+
import mill.javalib.spring.boot.SpringBootToolsModule
11+
12+
trait MyModule extends ScalaModule, PublishModule {
13+
def scalaVersion = "3.7.3"
14+
15+
def publishVersion = "0.0.1"
16+
17+
def pomSettings = PomSettings(
18+
description = "Hello",
19+
organization = "com.lihaoyi",
20+
url = "https://github.com/lihaoyi/example",
21+
licenses = Seq(License.MIT),
22+
versionControl = VersionControl.github("lihaoyi", "example"),
23+
developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
24+
)
25+
26+
def mvnDeps = Seq(mvn"org.thymeleaf:thymeleaf:3.1.1.RELEASE")
27+
28+
object test extends ScalaTests, TestModule.Junit4
29+
}
30+
31+
object SpringBootTools2 extends SpringBootToolsModule {
32+
// Default version requires Java 17+, so downgrate to latest 2.x version
33+
override def springBootToolsVersion = "2.7.18"
34+
protected lazy val millDiscover = Discover[this.type]
35+
}
36+
37+
object foo extends MyModule, RepackageModule { // <1>
38+
def moduleDeps = Seq(bar, qux)
39+
override def springBootToolsModule = ModuleRef(SpringBootTools2)
40+
}
41+
42+
object bar extends MyModule {
43+
def moduleDeps = Seq(qux)
44+
}
45+
46+
object qux extends MyModule
47+
48+
// <1> Add the `mill.javalib.repackage.RepackageModule` to the executable module.
49+
50+
/** Usage
51+
52+
> ./mill foo.run
53+
Foo.value: <h1>hello</h1>
54+
Bar.value: <p>world</p>
55+
Qux.value: 31337
56+
57+
> ./mill __.test
58+
...Test run foo.FooTests finished: 0 failed, 0 ignored, 1 total, ...s
59+
...Test run bar.BarTests finished: 0 failed, 0 ignored, 1 total, ...s
60+
61+
> ./mill show foo.repackagedJar
62+
".../out/foo/repackagedJar.dest/out.jar"
63+
64+
> ./out/foo/repackagedJar.dest/out.jar
65+
Foo.value: <h1>hello</h1>
66+
Bar.value: <p>world</p>
67+
Qux.value: 31337
68+
69+
> unzip -l ./out/foo/repackagedJar.dest/out.jar "BOOT-INF/lib*" # mac/linux
70+
...BOOT-INF/lib/scala3-library_3-3.7.3.jar
71+
...BOOT-INF/lib/thymeleaf-3.1.1.RELEASE.jar
72+
...BOOT-INF/lib/ognl-3.3.4.jar
73+
...BOOT-INF/lib/attoparser-2.0.6.RELEASE.jar
74+
...BOOT-INF/lib/unbescape-1.1.6.RELEASE.jar
75+
...BOOT-INF/lib/slf4j-api-2.0.5.jar
76+
...BOOT-INF/lib/javassist-3.29.0-GA.jar
77+
...BOOT-INF/lib/qux_3-0.0.1.jar
78+
...BOOT-INF/lib/bar_3-0.0.1.jar
79+
80+
*/
81+
//// SNIPPET:END
82+
83+
// *Futher notes:*
84+
//
85+
// * 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.
86+
// This works for all Java (also Scala or Kotlin) applications.
87+
// * It's not necessary to use the Spring Framework in the application.
88+
// * The resulting jar is a self-executable application, but it might not suitable to be used on the classpath of other applications.
89+
90+
// * Since the final jar produced with the `RepackageModule.repackagedJar` task often contains significantly less ZIP entries
91+
// then the jar file produced with `.assembly`, it's possible to workaround
92+
// an https://github.com/com-lihaoyi/mill/issues/2650[issue where `JavaModule.assembly` cannot produce executable assemblies]
93+
// due to some JVM limitations in ZIP file handling of large files.

0 commit comments

Comments
 (0)