-
-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Tobias Roeser <[email protected]>
- Loading branch information
Showing
11 changed files
with
287 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
//// SNIPPET:BUILD | ||
package build | ||
import mill._, javalib._ | ||
import mill.javalib.Assembly._ | ||
import mill.scalalib.JlinkModule | ||
|
||
object foo extends JavaModule with JlinkModule { | ||
override def jlinkModuleName: T[String] = T { "foo" } | ||
override def jlinkModuleVersion: T[Option[String]] = T { Option("1.0.0") } | ||
} | ||
|
||
/** Usage | ||
|
||
> mill foo.jlinkAppImage | ||
|
||
> mill show foo.jlinkAppImage | ||
".../out/foo/jlinkAppImage.dest/jlink-runtime" | ||
|
||
> ./out/foo/jlinkAppImage.dest/jlink-runtime/bin/jlink | ||
Nov 27, 2024 7:21:12 PM foo.Bar main | ||
INFO: Hello World! | ||
|
||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Bar Application Conf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package foo; | ||
|
||
import java.util.logging.Logger; | ||
|
||
public class Bar { | ||
private static final Logger LOG = Logger.getLogger(Bar.class.getName()); | ||
public static void main(String[] args) { | ||
LOG.info("Hello World!"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module foo | ||
{ | ||
requires java.logging; | ||
} |
1 change: 1 addition & 0 deletions
1
example/javalib/module/17-jpackage/bar/resources/application.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Bar Application Conf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
//// SNIPPET:BUILD | ||
package build | ||
import mill._, javalib._ | ||
import mill.javalib.Assembly._ | ||
import mill.scalalib.JpackageModule | ||
|
||
object foo extends JavaModule with JpackageModule { | ||
override def jpackageType = "pkg" | ||
|
||
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"), | ||
) | ||
} | ||
|
||
|
||
/** Usage | ||
|
||
> mill foo.assembly | ||
|
||
> unzip -p ./out/foo/assembly.dest/out.jar application.conf | ||
Foo Application Conf | ||
|
||
> java -jar ./out/foo/assembly.dest/out.jar | ||
Loaded application.conf from resources: Foo Application Conf | ||
|
||
> mill show foo.jpackageAppImage | ||
".../out/foo/jpackageAppImage.dest/image" | ||
|
||
|
||
# jpackageType accepts 3 values on macOS: "dmg" or "pkg" or "app-image" (default). | ||
# macOS: jpackageType = "dmg" | ||
> ls -l ./out/foo/jpackageAppImage.dest/image | ||
-rw-r--r--@ 1 mac staff 6291968 Nov 25 15:14 foo-1.0.dmg | ||
|
||
# macOS: jpackageType = "pkg" | ||
> ls -l ./out/foo/jpackageAppImage.dest/image | ||
total 106360 | ||
-rw-r--r-- 1 mac staff 54456037 Nov 25 15:19 foo-1.0.pkg | ||
|
||
# macOS: jpackageType = "app-image" | ||
> ls -l ./out/foo/jpackageAppImage.dest/image | ||
drwxr-xr-x 3 mac staff 96 Nov 25 15:10 foo.app/ | ||
|
||
> ./out/foo/jpackageAppImage.dest/image/foo.app/Contents/MacOS/foo | ||
Loaded application.conf from resources: Foo Application Conf | ||
|
||
|
||
# Linux: jpackageType = "app-image" | ||
> ./out/foo/jpackageAppImage.dest/image/foo/bin/foo | ||
Loaded application.conf from resources: Foo Application Conf | ||
|
||
*/ |
1 change: 1 addition & 0 deletions
1
example/javalib/module/17-jpackage/foo/resources/application.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Foo Application Conf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package foo; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
|
||
public class Foo { | ||
public static void main(String[] args) throws IOException { | ||
InputStream inputStream = Foo.class.getClassLoader().getResourceAsStream("application.conf"); | ||
String conf = new String(inputStream.readAllBytes()); | ||
System.out.println("Loaded application.conf from resources: " + conf); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package mill | ||
package scalalib | ||
|
||
import mill._ | ||
|
||
/** | ||
* Support building modular runtime images with the `jlink` tool, which is included in JDK 9 and later. | ||
* | ||
* The official `jlink` docs: https://docs.oracle.com/en/java/javase/23/docs/specs/man/jlink.html | ||
*/ | ||
trait JlinkModule extends JavaModule { | ||
|
||
/** The base name for the runtime image */ | ||
def jlinkImageName: T[String] = T { "jlink" } | ||
|
||
/** Name of the main module to be included in the runtime image */ | ||
def jlinkModuleName: T[String] = T { "" } | ||
|
||
/** The main module's version number. */ | ||
def jlinkModuleVersion: T[Option[String]] = T { None } | ||
|
||
/** The main class to use as the runtime entry point. */ | ||
def jlinkMainClass: T[String] = T { finalMainClass() } | ||
|
||
/** Compress level for the runtime image. | ||
* Valid values range between: | ||
* "zip-0" (no compression) and "zip-9" (best compression) | ||
* Defaults to "zip-6" */ | ||
def jlinkCompressLevel: T[String] = T { "zip-6" } | ||
|
||
|
||
/** | ||
* Creates a Java module file (.jmod) from compiled classes | ||
*/ | ||
def jmodPackage: T[PathRef] = T { | ||
|
||
val mainClass: String = finalMainClass() | ||
val outputPath = T.dest / "jlink.jmod" | ||
|
||
val libs = T.dest / "libs" | ||
val cp = runClasspath().map(_.path) | ||
val jars = cp.filter(os.exists).zipWithIndex.map { case (p, idx) => | ||
val dest = libs / s"${p.last}" | ||
os.copy(p, dest, createFolders = true) | ||
dest | ||
} | ||
|
||
val classPath = jars.map(_.toString).mkString(sys.props("path.separator")) | ||
val args = { | ||
val baseArgs = Seq( | ||
"jmod", | ||
"create", | ||
"--class-path", classPath.toString, | ||
"--main-class", mainClass, | ||
"--module-path", classPath.toString, | ||
outputPath.toString | ||
) | ||
|
||
val versionArgs = jlinkModuleVersion().toSeq.flatMap { version => | ||
Seq("--module-version", version) | ||
} | ||
|
||
baseArgs ++ versionArgs | ||
} | ||
os.proc(args).call() | ||
|
||
PathRef(outputPath) | ||
} | ||
|
||
/** Builds a custom runtime image using jlink */ | ||
def jlinkAppImage: T[PathRef] = T { | ||
val modulePath = jmodPackage().path.toString | ||
val outputPath = T.dest / "jlink-runtime" | ||
|
||
val args = Seq( | ||
"jlink", | ||
"--launcher", s"${jlinkImageName()}=${jlinkModuleName()}/${jlinkMainClass()}", | ||
"--module-path", modulePath, | ||
"--add-modules", jlinkModuleName(), | ||
"--output", outputPath.toString, | ||
"--compress", jlinkCompressLevel().toString, | ||
"--no-header-files", | ||
"--no-man-pages" | ||
) | ||
os.proc(args).call() | ||
|
||
PathRef(outputPath) | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package mill | ||
package scalalib | ||
|
||
import mill._ | ||
|
||
/** | ||
* Support for building a native package / installer with the `jpackage` tool which comes bundled with JDK 14 and later. | ||
* | ||
* The official `jpackage` docs: https://docs.oracle.com/en/java/javase/23/docs/specs/man/jpackage.html | ||
*/ | ||
trait JpackageModule extends JavaModule { | ||
|
||
/** The application name */ | ||
def jpackageName: T[String] = T { artifactName() } | ||
|
||
/** The main class to use as the entry point to the native package / installer. */ | ||
def jpackageMainClass: T[String] = T { finalMainClass() } | ||
|
||
/** | ||
* The type of native package / installer to be created. | ||
* | ||
* Valid values are: | ||
* "app-image" - any OS | ||
* "dmg", "pkg" - macOS (native package, installer) | ||
* "exe", "msi" - Windows (native package, installer) | ||
* "rpm", "deb" - Linux | ||
* | ||
* If unspecified, defaults to "app-image" which will build a package native to the host platform. | ||
* */ | ||
def jpackageType: T[String] = T { "app-image" } | ||
|
||
/** | ||
* The classpath used for the `jpackage` tool. The first entry needs to be the main jar. | ||
* In difference to [[runClasspath]], it contains the built jars of all dependent modules. | ||
*/ | ||
def jpackageRunClasspath: T[Seq[PathRef]] = T { | ||
val recLocalClasspath = (localClasspath() ++ transitiveLocalClasspath()).map(_.path) | ||
|
||
val runCp = runClasspath().filterNot(pr => recLocalClasspath.contains(pr.path)) | ||
|
||
val mainJar = jar() | ||
val recJars = transitiveJars() | ||
|
||
mainJar +: (recJars ++ runCp) | ||
} | ||
|
||
/** Builds a native package of the main application. */ | ||
def jpackageAppImage: T[PathRef] = T { | ||
// materialize all jars into a "lib" dir | ||
val libs = T.dest / "lib" | ||
val cp = jpackageRunClasspath().map(_.path) | ||
val jars = cp.filter(os.exists).zipWithIndex.map { case (p, idx) => | ||
val dest = libs / s"${idx + 1}-${p.last}" | ||
os.copy(p, dest, createFolders = true) | ||
dest | ||
} | ||
|
||
val appName = jpackageName() | ||
val appType = jpackageType() | ||
val mainClass = jpackageMainClass() | ||
val mainJarName = jars.head.last | ||
|
||
val args: Seq[String] = Seq( | ||
"jpackage", | ||
"--type", | ||
appType, | ||
"--name", | ||
appName, | ||
"--input", | ||
libs.toString(), | ||
"--main-jar", | ||
mainJarName, | ||
"--main-class", | ||
mainClass | ||
) | ||
|
||
// run jpackage tool | ||
val outDest = T.dest / "image" | ||
os.makeDir.all(outDest) | ||
os.proc(args).call(cwd = outDest) | ||
PathRef(outDest) | ||
} | ||
} |