🔧 AI Nachrichten ChatGPT showing blank screen [Fix](05.09.2026 um 19:55 Uhr)
⚠️ Malware / Trojaner / VirenSofort deinstallieren: Diese 19 Browser-Erweiterungen sind mit Malware verseucht(06.09.2026 um 08:00 Uhr)
⚠️ Malware / Trojaner / VirenLumma Stealer – dllhost.exe Hollowing, C2 Domains & Payload Extraction(01.09.2026 um 17:19 Uhr)
🔧 AI Nachrichten Simcha Kosman AMA: Owning ChatGPT's Secure Sandbox(03.09.2026 um 07:41 Uhr)
⚠️ Malware / Trojaner / VirenThe Gentlemen Ransomware Analysis: Go Obfuscated(04.09.2026 um 12:05 Uhr)
⚠️ Malware / Trojaner / VirenTengu, a Mirai-style Linux and IoT botnet(06.09.2026 um 15:27 Uhr)
🔧 AI Nachrichten ChatGPT showing blank screen [Fix](05.09.2026 um 19:55 Uhr)
⚠️ Malware / Trojaner / VirenSofort deinstallieren: Diese 19 Browser-Erweiterungen sind mit Malware verseucht(06.09.2026 um 08:00 Uhr)
⚠️ Malware / Trojaner / VirenLumma Stealer – dllhost.exe Hollowing, C2 Domains & Payload Extraction(01.09.2026 um 17:19 Uhr)
🔧 AI Nachrichten Simcha Kosman AMA: Owning ChatGPT's Secure Sandbox(03.09.2026 um 07:41 Uhr)
⚠️ Malware / Trojaner / VirenThe Gentlemen Ransomware Analysis: Go Obfuscated(04.09.2026 um 12:05 Uhr)
⚠️ Malware / Trojaner / VirenTengu, a Mirai-style Linux and IoT botnet(06.09.2026 um 15:27 Uhr)

🔧 Programmierung 🕛 kürzlich 10 Min Lesezeit
0

How flexible is the Mill build tool?

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

tl;dr: I implemented an experimental Mill plugin that publishes a Scala library as a pure Java library.





My goal was to automate the core tasks like shrinking, shading, and POM/Ivy adjustments. Users should only need to override methods in exceptional cases. I aimed for a setup that is as simple as a standard Scala project:




CODE
//| mill-version: 1.1.6
//| mill-jvm-version: temurin:21
//| mvnDeps:
//| - io.github.fmantz::scala4java_plugin::0.1.0
package build

import mill._, scalalib._, publish._

object `package` extends scala4java.ScalaModule, scala4java.PublishModule {
def artifactName = "example_lib"
def scalaVersion = "2.11.12"
def proguardVersion = "7.9.1"

def mvnDeps = Seq(
mvn"com.lihaoyi::scalatags:0.12.0", // a scala lib
mvn"org.jsoup:jsoup:1.22.1", // a java lib
mvn"org.apache.commons:commons-lang3:3.20.0", // a java lib
mvn"org.clapper::grizzled-slf4j:1.3.4" // scala lib that uses a java lib (slf4j)
)

object test extends ScalaTests, TestModule.Utest, scala4java.TestModule(this) {
def utestVersion = "0.8.2"
}

object testjava extends JavaTests, TestModule.Junit5, scala4java.TestModule(this) {
def jupiterVersion = "5.14.0"
}

def publishVersion = "0.1.0"

def pomSettings = PomSettings(
description = "MyTest",
organization = "xyz.test",
url = "https://github.com/johndoe/test",
licenses = Seq(License.MIT),
versionControl = VersionControl.github("xyz", "mytest"),
developers = Seq(Developer("mm", "John Doe", "https://github.com/johndoe"))
)

}






Key differences include specifying a




CODE
./mill run 







  • Use the lib via sbt (Scala):




CODE
mvn compile exec:java









The aftermath



The plugins default settings are:




CODE
def enableShadingScalaFiles = true
def enableShrinkingInBuild = true
def enableObfuscationInBuild = true
def enableLicensesInfo = true






With default settings and no verification tests enabled (i.e., omitting extends scala4java.TestModule(this)), the Java library of the example project above was only 571 KB. Disabling 'LicensesInfo' generation reduced the size further to 505 KB. Adding JUnit tests barely affected the JAR size (increasing it to just 586 KB) since JUnit is Java-based and does not rely on Scala. However, switching to 'uTest' increased the size to 793 KB because the testing library requires additional Scala standard functions (code from the scala-library.jar). Finally, using 'ScalaTest' caused a massive jump to 3.2 MB, as it heavily utilizes the Scala API.




  • no tests: 571 KB

  • only junit: 586 KB

  • only utest: 793 KB

  • only ScalaTest: 3.2 MB


  • no tests + no licence info : 505 KB!




These numbers are highly dependent on your specific project and setup and can vary based on several factors, including the libraries used, the Scala version, and your individual coding style. Nevertheless, I consider this experiment a success: the JAR size of the example project was significantly reduced here (compared to the sum of all needed libraries), and the resulting JAR remains highly versatile, working seamlessly across different setups and Scala versions.



To provide an overview of what is included in the example JAR and how different settings affect the results, I have compiled some additional data:



note: scala4java.TestModule was only enabled for JUnit





  • project classes (compiled. without tests):




    • 83.5K




  • included Scala libraries in publish.jar (total ca. 6.5 MB):




    • geny_2.11-1.0.0.jar: 105 KB

    • grizzled-slf4j_2.11-1.3.4.jar: 7.4 KB

    • scala-library-2.11.12.jar: 5.5 MB

    • scalatags_2.11-0.12.0.jar: 691 KB

    • sourcecode_2.11-0.3.0.jar 125: KB








How large are my jars with different settings?



SA = shade, SI = shrink, O = Obfuscate












































Setting publish.jar
all false 6.5 MB
SA 7.1 MB
SI 710 KB
O unsupported
SA,SI 792 KB
SA,O 5.5 MB
SI,O unsupported
SI,SA,O 586 KB


note: In the current implementation, obfuscation requires shading for the publish.jar. Furthermore, please note that both shading and shrinking are required to make the JAR compatible with any Scala or Java version.






Limitations



In the scala4java plugin implementation, Mill's assembly feature is used to create the base for JAR files. Consequently, the resolvedIvyAssembly and upstreamAssembly methods have been overridden. Ultimately, this plugin focuses primarily on "JAR" functionality (i.e. mill jar, mill publishLocal, mill publishM2Local) and treats the assembly (mill assembly) merely as an underlying tool.



Therefore, note a few minor limitations:




  • All test code and resources flagged by scala4java.TestModule(this) will be included in the (pre-)assembly.
    To avoid potential naming clashes, ensure that you use unique names across different test modules.

  • Additionally, some unnecessary test classes and test library JARs may be included in the assembly.
    While this can be fixed, it is currently considered a low priority.

  • Using the ProGuard®-optimized code instead of the original code also in the assembly was a design decision.
    Basically, the plugin reuses the pre-assembly JAR as the assembly JAR, only prepending the usual Mill starter scripts.






Conclusion



Mill is remarkably easy to customize, even for niche use cases like the one described above. Whether publishing Scala libraries as pure Java libraries is advisable remains a different matter. Furthermore, the final JAR size depends heavily on the Scala features used and the effectiveness of the ProGuard® optimization, making size predictions difficult. I'm not entirely convinced of the approach yet, but it was a great exercise. If JAR size is a priority, it is advisable to use either a Java testing framework or a lightweight Scala testing framework for the verification step. This allows ProGuard® to better optimize the Scala standard library classes. Feel free to share your thoughts in the comments!



Huge thanks to all the engineers and maintainers behind the tools powering this plugin, especially Scala, Mill, ProGuard®, and Apache BCEL!






DISCLAIMER:



This plugin has only been tested on two small personal projects (on Linux); therefore, it should be considered experimental and not production-ready. Feel free to try it out on your hobby projects, but please do not publish any resulting artifacts to Maven Central, I doubt they would appreciate it! I accept no liability or responsibility for any legal issues that may arise from using this software.






Note



I separated the example code from the plugin code.



To try the example, just clone the GitHub repository (the plugin code is available on Maven Central):




CODE
git clone https://github.com/fmantz/mill-scala4java-example.git






To compile the plugin yourself, clone the GitHub repository:




CODE
git clone https://github.com/fmantz/mill-scala4java.git






Enjoy!






Troubleshooting



Even the official Mill example from https://github.com/scala/scala3-mill-example-project is not a library you would want to reuse; I tested the plugin with it. Unfortunately, the autogenerated ProGuard® rules were not sufficient. I needed to add two extra rules. Therefore, I disabled obfuscation first to better understand where the problem was. Then, I extended the autogenerated ProGuard® entry points as follows:




CODE
//| mill-version: 1.1.6
//| mill-jvm-version: temurin:21
//| mvnDeps:
//| - io.github.fmantz::scala4java_plugin::0.1.0
import mill._, scalalib._

object examples extends scala4java.ScalaModule {
def scalaVersion = "3.8.4"
def proguardVersion = "7.9.1"

// its easier to work with real names (even the jar will be some bytes larger):
def enableObfuscationInBuild = false

// add some extra Progard entry rules:
def prepareAssemblyProGuardEntryPoints = Task {
val prefix = shadedRootDir() + "." + shadedSourceCodeId()
super.prepareAssemblyProGuardEntryPoints() ++
Seq(
s"-keep class $prefix.scala.math.BigDecimal { *; }",
s"-keep class $prefix.scala.concurrent.** { *; }"
)
}
}






You can test it here:




CODE
git clone https://github.com/fmantz/scala3-mill-example-project

./mill examples.assembly

java -jar ./out/examples/assembly.dest/out.jar






The assembly JAR size dropped from 9 MB to 1.5 MB. Since the scala4java plugin allows you to override any default setting, you should be able to resolve any issues that may arise. Usually, adding a missing ProGuard® rule solves the issue. Alternatively, you can disable ProGuard® entirely:




CODE
//| mill-version: 1.1.6
//| mill-jvm-version: temurin:21
//| mvnDeps:
//| - io.github.fmantz::scala4java_plugin::0.1.0
import mill._, scalalib._

object examples extends scala4java.ScalaModule {
def scalaVersion = "3.8.4"
def enableShrinkingInBuild = false
def enableObfuscationInBuild = false
}


Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 44%
🟡 In Evaluierung 27%
🟢 Keine Auswirkung 11%
Spannende Innovation 18%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
KARR Security vulnerability
1 Quelle
How can we detect if Claude in Chrome or other LLM browser agents are accessing/hijacking our web app user authenticated sessions and Block it
1 Quelle
OpenAI confirms ChatGPT is down ahead of 'Astra' model launch
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How flexible is the Mill build tool?

Thematisch verwandte Begriffe: flexible, Mill, build, tool · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...