[{"data":1,"prerenderedAt":2011},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fgetting-started\u002Fproject-setup":314,"\u002Fdocs\u002Fgetting-started\u002Fproject-setup-surround":2006},[4,38,86,149,176,219,257,273],{"title":5,"path":6,"stem":7,"children":8,"icon":37},"Getting Started","\u002Fdocs\u002Fgetting-started","1.docs\u002F1.getting-started\u002F1.index",[9,12,17,22,27,32],{"title":10,"path":6,"stem":7,"icon":11},"Getting started","i-lucide-flag",{"title":13,"path":14,"stem":15,"icon":16},"Modules overview","\u002Fdocs\u002Fgetting-started\u002Fmodules-overview","1.docs\u002F1.getting-started\u002F2.modules-overview","i-lucide-boxes",{"title":18,"path":19,"stem":20,"icon":21},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","1.docs\u002F1.getting-started\u002F3.installation","i-lucide-download",{"title":23,"path":24,"stem":25,"icon":26},"License configuration","\u002Fdocs\u002Fgetting-started\u002Flicense-configuration","1.docs\u002F1.getting-started\u002F4.license-configuration","i-lucide-key-round",{"title":28,"path":29,"stem":30,"icon":31},"Your first app","\u002Fdocs\u002Fgetting-started\u002Ffirst-app","1.docs\u002F1.getting-started\u002F5.first-app","i-lucide-square-play",{"title":33,"path":34,"stem":35,"icon":36},"Project setup","\u002Fdocs\u002Fgetting-started\u002Fproject-setup","1.docs\u002F1.getting-started\u002F6.project-setup","i-lucide-package",false,{"title":39,"path":40,"stem":41,"children":42,"icon":45},"Core Concepts","\u002Fdocs\u002Fconcepts","1.docs\u002F2.concepts\u002F1.index",[43,46,51,56,61,66,71,76,81],{"title":44,"path":40,"stem":41,"icon":45},"Core concepts","i-lucide-book-open",{"title":47,"path":48,"stem":49,"icon":50},"Architecture","\u002Fdocs\u002Fconcepts\u002Farchitecture","1.docs\u002F2.concepts\u002F2.architecture","i-lucide-layers",{"title":52,"path":53,"stem":54,"icon":55},"Exactly-once semantics","\u002Fdocs\u002Fconcepts\u002Fexactly-once","1.docs\u002F2.concepts\u002F3.exactly-once","i-lucide-shield-check",{"title":57,"path":58,"stem":59,"icon":60},"Lanes and parallelism","\u002Fdocs\u002Fconcepts\u002Flanes-and-parallelism","1.docs\u002F2.concepts\u002F4.lanes-and-parallelism","i-lucide-split",{"title":62,"path":63,"stem":64,"icon":65},"State and thread-safety","\u002Fdocs\u002Fconcepts\u002Fstate-and-thread-safety","1.docs\u002F2.concepts\u002F5.state-and-thread-safety","i-lucide-lock",{"title":67,"path":68,"stem":69,"icon":70},"Event time and watermarks","\u002Fdocs\u002Fconcepts\u002Fevent-time-and-watermarks","1.docs\u002F2.concepts\u002F6.event-time-and-watermarks","i-lucide-clock",{"title":72,"path":73,"stem":74,"icon":75},"The configuration model","\u002Fdocs\u002Fconcepts\u002Fconfiguration-model","1.docs\u002F2.concepts\u002F7.configuration-model","i-lucide-sliders-horizontal",{"title":77,"path":78,"stem":79,"icon":80},"The error-handling model","\u002Fdocs\u002Fconcepts\u002Ferror-handling-model","1.docs\u002F2.concepts\u002F8.error-handling-model","i-lucide-triangle-alert",{"title":82,"path":83,"stem":84,"icon":85},"How StoatFlow differs from Kafka Streams","\u002Fdocs\u002Fconcepts\u002Fhow-stoatflow-differs-from-ks","1.docs\u002F2.concepts\u002F9.how-stoatflow-differs-from-ks","i-lucide-arrow-left-right",{"title":87,"path":88,"stem":89,"children":90,"icon":93},"Building Topologies","\u002Fdocs\u002Fbuilding","1.docs\u002F3.building\u002F1.index",[91,94,99,104,109,114,119,124,129,134,139,144],{"title":92,"path":88,"stem":89,"icon":93},"Building topologies","i-lucide-blocks",{"title":95,"path":96,"stem":97,"icon":98},"Error handling and DLQ","\u002Fdocs\u002Fbuilding\u002Ferror-handling-dlq","1.docs\u002F3.building\u002F10.error-handling-dlq","i-lucide-circle-x",{"title":100,"path":101,"stem":102,"icon":103},"State stores","\u002Fdocs\u002Fbuilding\u002Fstate-stores","1.docs\u002F3.building\u002F11.state-stores","i-lucide-database",{"title":105,"path":106,"stem":107,"icon":108},"Testing topologies","\u002Fdocs\u002Fbuilding\u002Ftesting","1.docs\u002F3.building\u002F12.testing","i-lucide-flask-conical",{"title":110,"path":111,"stem":112,"icon":113},"Sources and sinks","\u002Fdocs\u002Fbuilding\u002Fstreams-builder","1.docs\u002F3.building\u002F2.streams-builder","i-lucide-import",{"title":115,"path":116,"stem":117,"icon":118},"KStream and KTable operations","\u002Fdocs\u002Fbuilding\u002Fkstream-ktable","1.docs\u002F3.building\u002F3.kstream-ktable","i-lucide-waypoints",{"title":120,"path":121,"stem":122,"icon":123},"Aggregations","\u002Fdocs\u002Fbuilding\u002Faggregations","1.docs\u002F3.building\u002F4.aggregations","i-lucide-sigma",{"title":125,"path":126,"stem":127,"icon":128},"Windowing","\u002Fdocs\u002Fbuilding\u002Fwindowing","1.docs\u002F3.building\u002F5.windowing","i-lucide-calendar-clock",{"title":130,"path":131,"stem":132,"icon":133},"Joins","\u002Fdocs\u002Fbuilding\u002Fjoins","1.docs\u002F3.building\u002F6.joins","i-lucide-git-merge",{"title":135,"path":136,"stem":137,"icon":138},"The Processor API","\u002Fdocs\u002Fbuilding\u002Fprocessor-api","1.docs\u002F3.building\u002F7.processor-api","i-lucide-cpu",{"title":140,"path":141,"stem":142,"icon":143},"Scheduled sources","\u002Fdocs\u002Fbuilding\u002Fscheduled-sources","1.docs\u002F3.building\u002F8.scheduled-sources","i-lucide-timer",{"title":145,"path":146,"stem":147,"icon":148},"Serdes and Avro","\u002Fdocs\u002Fbuilding\u002Fserdes","1.docs\u002F3.building\u002F9.serdes","i-lucide-binary",{"title":150,"path":151,"stem":152,"children":153,"icon":75},"Configuration","\u002Fdocs\u002Fconfiguration","1.docs\u002F4.configuration\u002F1.index",[154,156,161,166,171],{"title":155,"path":151,"stem":152,"icon":75},"How configuration works",{"title":157,"path":158,"stem":159,"icon":160},"Engine configuration (:core)","\u002Fdocs\u002Fconfiguration\u002Fcore-config","1.docs\u002F4.configuration\u002F2.core-config","i-lucide-settings-2",{"title":162,"path":163,"stem":164,"icon":165},"Runtime configuration (:runtime)","\u002Fdocs\u002Fconfiguration\u002Fruntime-config","1.docs\u002F4.configuration\u002F3.runtime-config","i-lucide-server-cog",{"title":167,"path":168,"stem":169,"icon":170},"Defaults, adaptivity, and presets","\u002Fdocs\u002Fconfiguration\u002Fdefaults-and-presets","1.docs\u002F4.configuration\u002F4.defaults-and-presets","i-lucide-gauge",{"title":172,"path":173,"stem":174,"icon":175},"Kafka client configuration","\u002Fdocs\u002Fconfiguration\u002Fkafka-client-config","1.docs\u002F4.configuration\u002F5.kafka-client-config","i-lucide-plug",{"title":177,"path":178,"stem":179,"children":180,"icon":183},"Running in Production","\u002Fdocs\u002Fruntime","1.docs\u002F5.runtime\u002F1.index",[181,184,189,194,199,204,209,214],{"title":182,"path":178,"stem":179,"icon":183},"The runtime","i-lucide-server",{"title":185,"path":186,"stem":187,"icon":188},"The REST API","\u002Fdocs\u002Fruntime\u002Frest-api","1.docs\u002F5.runtime\u002F2.rest-api","i-lucide-globe",{"title":190,"path":191,"stem":192,"icon":193},"Health checks","\u002Fdocs\u002Fruntime\u002Fhealth-checks","1.docs\u002F5.runtime\u002F3.health-checks","i-lucide-heart-pulse",{"title":195,"path":196,"stem":197,"icon":198},"Metrics","\u002Fdocs\u002Fruntime\u002Fmetrics","1.docs\u002F5.runtime\u002F4.metrics","i-lucide-activity",{"title":200,"path":201,"stem":202,"icon":203},"Pause and resume","\u002Fdocs\u002Fruntime\u002Fpause-unpause","1.docs\u002F5.runtime\u002F5.pause-unpause","i-lucide-pause",{"title":205,"path":206,"stem":207,"icon":208},"Plugins and lifecycle hooks","\u002Fdocs\u002Fruntime\u002Fplugins","1.docs\u002F5.runtime\u002F6.plugins","i-lucide-puzzle",{"title":210,"path":211,"stem":212,"icon":213},"Docker images","\u002Fdocs\u002Fruntime\u002Fdocker","1.docs\u002F5.runtime\u002F7.docker","i-lucide-container",{"title":215,"path":216,"stem":217,"icon":218},"GraalVM native image","\u002Fdocs\u002Fruntime\u002Fnative-image","1.docs\u002F5.runtime\u002F8.native-image","i-lucide-zap",{"title":220,"path":221,"stem":222,"children":223,"icon":226},"Deploying & Operating","\u002Fdocs\u002Foperating","1.docs\u002F6.operating\u002F1.index",[224,227,232,237,242,247,252],{"title":225,"path":221,"stem":222,"icon":226},"Deploying and operating","i-lucide-life-buoy",{"title":228,"path":229,"stem":230,"icon":231},"Running on Kubernetes","\u002Fdocs\u002Foperating\u002Fkubernetes","1.docs\u002F6.operating\u002F2.kubernetes","i-lucide-ship",{"title":233,"path":234,"stem":235,"icon":236},"High availability","\u002Fdocs\u002Foperating\u002Fhigh-availability","1.docs\u002F6.operating\u002F3.high-availability","i-lucide-copy",{"title":238,"path":239,"stem":240,"icon":241},"Liveness and readiness probes","\u002Fdocs\u002Foperating\u002Fprobes","1.docs\u002F6.operating\u002F4.probes","i-lucide-stethoscope",{"title":243,"path":244,"stem":245,"icon":246},"Observability","\u002Fdocs\u002Foperating\u002Fobservability","1.docs\u002F6.operating\u002F5.observability","i-lucide-telescope",{"title":248,"path":249,"stem":250,"icon":251},"Tuning under load","\u002Fdocs\u002Foperating\u002Ftuning","1.docs\u002F6.operating\u002F6.tuning","i-lucide-sliders",{"title":253,"path":254,"stem":255,"icon":256},"Production checklist","\u002Fdocs\u002Foperating\u002Fproduction-checklist","1.docs\u002F6.operating\u002F7.production-checklist","i-lucide-clipboard-check",{"title":258,"path":259,"stem":260,"children":261,"icon":85},"Migrating from Kafka Streams","\u002Fdocs\u002Fmigration","1.docs\u002F7.migration\u002F1.index",[262,263,268],{"title":258,"path":259,"stem":260,"icon":85},{"title":264,"path":265,"stem":266,"icon":267},"Migration without carrying state","\u002Fdocs\u002Fmigration\u002Fwithout-data-migration","1.docs\u002F7.migration\u002F2.without-data-migration","i-lucide-sparkles",{"title":269,"path":270,"stem":271,"icon":272},"Migration carrying state","\u002Fdocs\u002Fmigration\u002Fwith-data-migration","1.docs\u002F7.migration\u002F3.with-data-migration","i-lucide-database-backup",{"title":274,"path":275,"stem":276,"children":277,"icon":279},"Reference","\u002Fdocs\u002Freference","1.docs\u002F8.reference\u002F1.index",[278,280,285,290,295,300,305,309],{"title":274,"path":275,"stem":276,"icon":279},"i-lucide-list",{"title":281,"path":282,"stem":283,"icon":284},"Configuration reference","\u002Fdocs\u002Freference\u002Fconfiguration-reference","1.docs\u002F8.reference\u002F2.configuration-reference","i-lucide-table",{"title":286,"path":287,"stem":288,"icon":289},"REST API reference","\u002Fdocs\u002Freference\u002Frest-api-reference","1.docs\u002F8.reference\u002F3.rest-api-reference","i-lucide-network",{"title":291,"path":292,"stem":293,"icon":294},"Gradle plugin reference","\u002Fdocs\u002Freference\u002Fgradle-plugin-reference","1.docs\u002F8.reference\u002F4.gradle-plugin-reference","i-lucide-box",{"title":296,"path":297,"stem":298,"icon":299},"Maven reference","\u002Fdocs\u002Freference\u002Fmaven-reference","1.docs\u002F8.reference\u002F5.maven-reference","i-simple-icons-apachemaven",{"title":301,"path":302,"stem":303,"icon":304},"Kafka Streams compatibility matrix","\u002Fdocs\u002Freference\u002Fks-compatibility-matrix","1.docs\u002F8.reference\u002F6.ks-compatibility-matrix","i-lucide-table-2",{"title":306,"path":307,"stem":308,"icon":170},"Metrics reference","\u002Fdocs\u002Freference\u002Fmetrics-reference","1.docs\u002F8.reference\u002F7.metrics-reference",{"title":310,"path":311,"stem":312,"icon":313},"Glossary","\u002Fdocs\u002Freference\u002Fglossary","1.docs\u002F8.reference\u002F8.glossary","i-lucide-book-a",{"id":315,"title":33,"body":316,"description":1999,"extension":2000,"meta":2001,"navigation":2002,"pageType":2003,"path":34,"seo":2004,"stem":35,"__hash__":2005},"docs\u002F1.docs\u002F1.getting-started\u002F6.project-setup.md",{"type":317,"value":318,"toc":1989},"minimark",[319,337,426,431,438,693,731,757,761,764,905,916,920,930,1092,1139,1163,1167,1170,1321,1344,1348,1351,1422,1426,1564,1594,1598,1601,1932,1941,1945,1985],[320,321,322,323,327,328,332,333,336],"p",{},"A StoatFlow application has non-trivial build requirements: a JDK 25 toolchain, two mandatory JVM flags at ",[324,325,326],"strong",{},"compile, test, and run"," time, a fat JAR with the right ",[329,330,331],"code",{},"Main-Class",", and — when you opt in — a container-aware heap entrypoint and a GraalVM native image with the correct metadata. You don't hand-maintain any of that. StoatFlow ships first-class build conventions for ",[324,334,335],{},"both Gradle and Maven",", kept deliberately symmetric, so a production-ready build is a few lines of config.",[338,339,340],"tldr-panel",{},[341,342,343,362,387,417],"ul",{},[344,345,346,349,350,353,354,357,358,361],"li",{},[324,347,348],{},"Gradle"," → the ",[329,351,352],{},"io.stoatflow"," convention plugin: one ",[329,355,356],{},"plugins { }"," line + a ",[329,359,360],{},"stoatflow { }"," block.",[344,363,364,349,367,370,371,374,375,378,379,382,383,386],{},[324,365,366],{},"Maven",[329,368,369],{},"io.stoatflow:stoatflow-parent"," parent POM (+ the ",[329,372,373],{},"stoatflow-bom"," and ",[329,376,377],{},"stoatflow-maven-plugin","): a ",[329,380,381],{},"\u003Cparent>"," and a few ",[329,384,385],{},"\u003Cproperties>",".",[344,388,389,392,393,396,397,400,401,404,405,408,409,396,413,416],{},[324,390,391],{},"Both give you:"," the JDK 25 toolchain, ",[329,394,395],{},"--enable-preview"," + ",[329,398,399],{},"--enable-native-access=ALL-UNNAMED"," (compile\u002Ftest\u002Frun), ",[329,402,403],{},"-XX:+UseG1GC",", a runnable fat JAR, a JUnit-Platform ",[329,406,407],{},"IntegrationTest"," tag-split, and opt-in ",[410,411,412],"a",{"href":211},"Docker",[410,414,415],{"href":216},"native-image"," builds.",[344,418,419,422,423,425],{},[324,420,421],{},"First:"," wire up the repository and credentials in ",[410,424,18],{"href":19}," — this page picks up from there.",[427,428,430],"h2",{"id":429},"apply-the-conventions","Apply the conventions",[320,432,433,434,437],{},"Register the StoatFlow repository (and, for Gradle, the plugin-marker repository) as shown in ",[410,435,18],{"href":436},"\u002Fdocs\u002Fgetting-started\u002Finstallation#_1-register-the-private-maven-repository",". Then apply the convention:",[439,440,442,587],"code-tabs",{"group":441},"build",[443,444,449],"pre",{"className":445,"code":446,"filename":348,"language":447,"meta":448,"style":448},"language-kotlin shiki shiki-themes vitesse-light","\u002F\u002F build.gradle.kts\nplugins {\n    kotlin(\"jvm\") version \"2.4.0\"      \u002F\u002F omit for a Java-only project\n    id(\"io.stoatflow\") version \"\u003Cstoatflow-version>\"\n}\n\nstoatflow {\n    mainClass.set(\"com.example.MainKt\") \u002F\u002F your application entry point\n}\n\ndependencies {\n    implementation(\"io.stoatflow:stoatflow-runtime:\u003Cstoatflow-version>\")\n}\n","kotlin","",[329,450,451,460,471,493,509,515,522,530,550,555,560,568,582],{"__ignoreMap":448},[452,453,456],"span",{"class":454,"line":455},"line",1,[452,457,459],{"class":458},"s8zF2","\u002F\u002F build.gradle.kts\n",[452,461,463,467],{"class":454,"line":462},2,[452,464,466],{"class":465},"sySUi","plugins",[452,468,470],{"class":469},"suHK_"," {\n",[452,472,474,477,480,484,487,490],{"class":454,"line":473},3,[452,475,476],{"class":465},"    kotlin",[452,478,479],{"class":469},"(",[452,481,483],{"class":482},"spphp","\"jvm\"",[452,485,486],{"class":469},") version ",[452,488,489],{"class":482},"\"2.4.0\"",[452,491,492],{"class":458},"      \u002F\u002F omit for a Java-only project\n",[452,494,496,499,501,504,506],{"class":454,"line":495},4,[452,497,498],{"class":465},"    id",[452,500,479],{"class":469},[452,502,503],{"class":482},"\"io.stoatflow\"",[452,505,486],{"class":469},[452,507,508],{"class":482},"\"\u003Cstoatflow-version>\"\n",[452,510,512],{"class":454,"line":511},5,[452,513,514],{"class":469},"}\n",[452,516,518],{"class":454,"line":517},6,[452,519,521],{"emptyLinePlaceholder":520},true,"\n",[452,523,525,528],{"class":454,"line":524},7,[452,526,527],{"class":465},"stoatflow",[452,529,470],{"class":469},[452,531,533,536,539,541,544,547],{"class":454,"line":532},8,[452,534,535],{"class":469},"    mainClass.",[452,537,538],{"class":465},"set",[452,540,479],{"class":469},[452,542,543],{"class":482},"\"com.example.MainKt\"",[452,545,546],{"class":469},") ",[452,548,549],{"class":458},"\u002F\u002F your application entry point\n",[452,551,553],{"class":454,"line":552},9,[452,554,514],{"class":469},[452,556,558],{"class":454,"line":557},10,[452,559,521],{"emptyLinePlaceholder":520},[452,561,563,566],{"class":454,"line":562},11,[452,564,565],{"class":465},"dependencies",[452,567,470],{"class":469},[452,569,571,574,576,579],{"class":454,"line":570},12,[452,572,573],{"class":465},"    implementation",[452,575,479],{"class":469},[452,577,578],{"class":482},"\"io.stoatflow:stoatflow-runtime:\u003Cstoatflow-version>\"",[452,580,581],{"class":469},")\n",[452,583,585],{"class":454,"line":584},13,[452,586,514],{"class":469},[443,588,592],{"className":589,"code":590,"filename":366,"language":591,"meta":448,"style":448},"language-xml shiki shiki-themes vitesse-light","\u003C!-- pom.xml -->\n\u003Cparent>\n  \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n  \u003CartifactId>stoatflow-parent\u003C\u002FartifactId>\n  \u003Cversion>REPLACE-WITH-CURRENT-RELEASE\u003C\u002Fversion>   \u003C!-- literal — Maven can't resolve a property in \u003Cparent> -->\n  \u003CrelativePath\u002F>\n\u003C\u002Fparent>\n\n\u003Cproperties>\n  \u003Cstoatflow.mainClass>com.example.Main\u003C\u002Fstoatflow.mainClass>\n\u003C\u002Fproperties>\n\n\u003Cdependencies>\n  \u003Cdependency>\n    \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n    \u003CartifactId>stoatflow-runtime\u003C\u002FartifactId>\n    \u003C!-- version managed by the BOM the parent imports -->\n  \u003C\u002Fdependency>\n\u003C\u002Fdependencies>\n","xml",[329,593,594,599,604,609,614,619,624,629,633,638,643,648,652,657,663,669,675,681,687],{"__ignoreMap":448},[452,595,596],{"class":454,"line":455},[452,597,598],{},"\u003C!-- pom.xml -->\n",[452,600,601],{"class":454,"line":462},[452,602,603],{},"\u003Cparent>\n",[452,605,606],{"class":454,"line":473},[452,607,608],{},"  \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n",[452,610,611],{"class":454,"line":495},[452,612,613],{},"  \u003CartifactId>stoatflow-parent\u003C\u002FartifactId>\n",[452,615,616],{"class":454,"line":511},[452,617,618],{},"  \u003Cversion>REPLACE-WITH-CURRENT-RELEASE\u003C\u002Fversion>   \u003C!-- literal — Maven can't resolve a property in \u003Cparent> -->\n",[452,620,621],{"class":454,"line":517},[452,622,623],{},"  \u003CrelativePath\u002F>\n",[452,625,626],{"class":454,"line":524},[452,627,628],{},"\u003C\u002Fparent>\n",[452,630,631],{"class":454,"line":532},[452,632,521],{"emptyLinePlaceholder":520},[452,634,635],{"class":454,"line":552},[452,636,637],{},"\u003Cproperties>\n",[452,639,640],{"class":454,"line":557},[452,641,642],{},"  \u003Cstoatflow.mainClass>com.example.Main\u003C\u002Fstoatflow.mainClass>\n",[452,644,645],{"class":454,"line":562},[452,646,647],{},"\u003C\u002Fproperties>\n",[452,649,650],{"class":454,"line":570},[452,651,521],{"emptyLinePlaceholder":520},[452,653,654],{"class":454,"line":584},[452,655,656],{},"\u003Cdependencies>\n",[452,658,660],{"class":454,"line":659},14,[452,661,662],{},"  \u003Cdependency>\n",[452,664,666],{"class":454,"line":665},15,[452,667,668],{},"    \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n",[452,670,672],{"class":454,"line":671},16,[452,673,674],{},"    \u003CartifactId>stoatflow-runtime\u003C\u002FartifactId>\n",[452,676,678],{"class":454,"line":677},17,[452,679,680],{},"    \u003C!-- version managed by the BOM the parent imports -->\n",[452,682,684],{"class":454,"line":683},18,[452,685,686],{},"  \u003C\u002Fdependency>\n",[452,688,690],{"class":454,"line":689},19,[452,691,692],{},"\u003C\u002Fdependencies>\n",[320,694,695,696,699,700,702,703,706,707,710,711,714,715,718,719,722,723,726,727,730],{},"The current published version is ",[697,698],"stoatflow-version",{}," — substitute it for the placeholders above (the Maven ",[329,701,381],{}," version must be a ",[324,704,705],{},"literal","; Maven does not interpolate properties in parent coordinates). For a Kotlin ",[329,708,709],{},"fun main()"," in ",[329,712,713],{},"Main.kt"," the entry point is the synthetic ",[329,716,717],{},"MainKt"," class (",[329,720,721],{},"com.example.MainKt","); for a Java ",[329,724,725],{},"public static void main"," it's the class itself (",[329,728,729],{},"com.example.Main",").",[732,733,736],"callout",{"color":734,"icon":735},"info","i-lucide-info",[320,737,738,739,741,742,748,749,752,753,386],{},"The Maven parent imports ",[329,740,373],{}," for you, so you ",[324,743,744,745],{},"omit the ",[329,746,747],{},"\u003Cversion>"," on every ",[329,750,751],{},"io.stoatflow:*"," dependency. If you already have a corporate parent POM, import the BOM directly instead and set the toolchain by hand — see ",[410,754,756],{"href":755},"\u002Fdocs\u002Freference\u002Fmaven-reference#using-just-the-bom","Maven reference → Using just the BOM",[427,758,760],{"id":759},"what-you-get","What you get",[320,762,763],{},"Applying the convention — with no further configuration — already gives you all of this:",[765,766,767,780],"table",{},[768,769,770],"thead",{},[771,772,773,777],"tr",{},[774,775,776],"th",{},"Capability",[774,778,779],{},"What it does",[781,782,783,794,812,824,845,863,891],"tbody",{},[771,784,785,791],{},[786,787,788],"td",{},[324,789,790],{},"JDK 25 toolchain",[786,792,793],{},"Compiles and runs on JDK 25 — required for the virtual-thread \u002F structured-concurrency preview features StoatFlow is built on.",[771,795,796,801],{},[786,797,798],{},[324,799,800],{},"Mandatory JVM flags",[786,802,803,374,805,807,808,811],{},[329,804,395],{},[329,806,399],{}," at compile, test, ",[324,809,810],{},"and"," run time. Non-negotiable and always added.",[771,813,814,819],{},[786,815,816],{},[324,817,818],{},"Default GC flag",[786,820,821,823],{},[329,822,403],{}," — overridable, but on by default for predictable pauses even on a single core or a small container.",[771,825,826,831],{},[786,827,828],{},[324,829,830],{},"Runnable fat JAR",[786,832,833,834,837,838,840,841,844],{},"A shaded ",[329,835,836],{},"-all"," JAR with the ",[329,839,331],{}," manifest and merged service files. ",[329,842,843],{},"java -jar"," just works.",[771,846,847,852],{},[786,848,849],{},[324,850,851],{},"Test conventions",[786,853,854,855,858,859,862],{},"JUnit Platform with the preview\u002Fnative-access flags; an ",[329,856,857],{},"integrationTest"," task that runs only ",[329,860,861],{},"@Tag(\"IntegrationTest\")"," tests (the unit run excludes them).",[771,864,865,875],{},[786,866,867,870,871],{},[324,868,869],{},"Docker image"," ",[872,873,874],"em",{},"(opt-in)",[786,876,877,878,884,885,888,889,386],{},"A reproducible JVM container via ",[410,879,883],{"href":880,"rel":881},"https:\u002F\u002Fgithub.com\u002FGoogleContainerTools\u002Fjib",[882],"nofollow","Jib"," — no ",[329,886,887],{},"Dockerfile",", no Docker daemon to assemble the layers. See ",[410,890,412],{"href":211},[771,892,893,900],{},[786,894,895,870,898],{},[324,896,897],{},"Native image",[872,899,874],{},[786,901,902,903,386],{},"A GraalVM native image with all of StoatFlow's reflection \u002F JNI \u002F FFM metadata already registered. One line to turn on. See ",[410,904,897],{"href":216},[732,906,907],{"color":734,"icon":735},[320,908,909,911,912,915],{},[329,910,403],{}," is set explicitly because the JVM only auto-selects G1 on \"server-class\" hardware (≥ 2 CPUs and ≥ ~2 GB memory), falling back to the single-threaded Serial collector below that. Setting it explicitly gives short, predictable GC pauses even on a single core — which matters for stream processing, where a long stop-the-world pause stalls commit barriers. See ",[410,913,18],{"href":914},"\u002Fdocs\u002Fgetting-started\u002Finstallation#_3-configure-the-jvm-toolchain"," for the full reasoning.",[427,917,919],{"id":918},"configure-the-build","Configure the build",[320,921,922,925,926,929],{},[329,923,924],{},"mainClass"," is the only property most projects set. The container and native-image builds are opt-in and default to off. Here are the common knobs — the ",[324,927,928],{},"full"," surface (every property, task, and default) lives in the reference pages, linked below.",[439,931,932,1060],{"group":441},[443,933,935],{"className":445,"code":934,"filename":348,"language":447,"meta":448,"style":448},"\u002F\u002F build.gradle.kts\nstoatflow {\n    mainClass.set(\"com.example.MainKt\")\n\n    docker {\n        enabled.set(true)               \u002F\u002F opt in to the Jib image\n        imageName.set(\"acme\u002Fword-count\")\n    }\n\n    nativeImage {\n        enabled.set(true)               \u002F\u002F opt in to the GraalVM native image\n        gc.set(\"G1\")                    \u002F\u002F Oracle GraalVM; omit for Serial (stateless only)\n    }\n}\n",[329,936,937,941,947,959,963,970,989,1003,1008,1012,1019,1034,1052,1056],{"__ignoreMap":448},[452,938,939],{"class":454,"line":455},[452,940,459],{"class":458},[452,942,943,945],{"class":454,"line":462},[452,944,527],{"class":465},[452,946,470],{"class":469},[452,948,949,951,953,955,957],{"class":454,"line":473},[452,950,535],{"class":469},[452,952,538],{"class":465},[452,954,479],{"class":469},[452,956,543],{"class":482},[452,958,581],{"class":469},[452,960,961],{"class":454,"line":495},[452,962,521],{"emptyLinePlaceholder":520},[452,964,965,968],{"class":454,"line":511},[452,966,967],{"class":465},"    docker",[452,969,470],{"class":469},[452,971,972,975,977,979,983,986],{"class":454,"line":517},[452,973,974],{"class":469},"        enabled.",[452,976,538],{"class":465},[452,978,479],{"class":469},[452,980,982],{"class":981},"sbBg2","true",[452,984,985],{"class":469},")               ",[452,987,988],{"class":458},"\u002F\u002F opt in to the Jib image\n",[452,990,991,994,996,998,1001],{"class":454,"line":524},[452,992,993],{"class":469},"        imageName.",[452,995,538],{"class":465},[452,997,479],{"class":469},[452,999,1000],{"class":482},"\"acme\u002Fword-count\"",[452,1002,581],{"class":469},[452,1004,1005],{"class":454,"line":532},[452,1006,1007],{"class":469},"    }\n",[452,1009,1010],{"class":454,"line":552},[452,1011,521],{"emptyLinePlaceholder":520},[452,1013,1014,1017],{"class":454,"line":557},[452,1015,1016],{"class":465},"    nativeImage",[452,1018,470],{"class":469},[452,1020,1021,1023,1025,1027,1029,1031],{"class":454,"line":562},[452,1022,974],{"class":469},[452,1024,538],{"class":465},[452,1026,479],{"class":469},[452,1028,982],{"class":981},[452,1030,985],{"class":469},[452,1032,1033],{"class":458},"\u002F\u002F opt in to the GraalVM native image\n",[452,1035,1036,1039,1041,1043,1046,1049],{"class":454,"line":570},[452,1037,1038],{"class":469},"        gc.",[452,1040,538],{"class":465},[452,1042,479],{"class":469},[452,1044,1045],{"class":482},"\"G1\"",[452,1047,1048],{"class":469},")                    ",[452,1050,1051],{"class":458},"\u002F\u002F Oracle GraalVM; omit for Serial (stateless only)\n",[452,1053,1054],{"class":454,"line":584},[452,1055,1007],{"class":469},[452,1057,1058],{"class":454,"line":659},[452,1059,514],{"class":469},[443,1061,1063],{"className":589,"code":1062,"filename":366,"language":591,"meta":448,"style":448},"\u003C!-- pom.xml — container\u002Fnative config lives in \u003Cproperties> -->\n\u003Cproperties>\n  \u003Cstoatflow.mainClass>com.example.Main\u003C\u002Fstoatflow.mainClass>\n  \u003Cstoatflow.docker.imageName>acme\u002Fword-count\u003C\u002Fstoatflow.docker.imageName>\n  \u003Cstoatflow.nativeImage.gc>G1\u003C\u002Fstoatflow.nativeImage.gc>\n\u003C\u002Fproperties>\n",[329,1064,1065,1070,1074,1078,1083,1088],{"__ignoreMap":448},[452,1066,1067],{"class":454,"line":455},[452,1068,1069],{},"\u003C!-- pom.xml — container\u002Fnative config lives in \u003Cproperties> -->\n",[452,1071,1072],{"class":454,"line":462},[452,1073,637],{},[452,1075,1076],{"class":454,"line":473},[452,1077,642],{},[452,1079,1080],{"class":454,"line":495},[452,1081,1082],{},"  \u003Cstoatflow.docker.imageName>acme\u002Fword-count\u003C\u002Fstoatflow.docker.imageName>\n",[452,1084,1085],{"class":454,"line":511},[452,1086,1087],{},"  \u003Cstoatflow.nativeImage.gc>G1\u003C\u002Fstoatflow.nativeImage.gc>\n",[452,1089,1090],{"class":454,"line":517},[452,1091,647],{},[732,1093,1095],{"color":1094,"icon":80},"warning",[320,1096,1097,1106,1107,1110,1111,1114,1115,1118,1119,1122,1123,1126,1127,1131,1132,1134,1135,1138],{},[324,1098,1099,1100,1103,1104,386],{},"Maven profiles are activated with ",[329,1101,1102],{},"-P",", not ",[329,1105,385],{}," Setting ",[329,1108,1109],{},"\u003Cstoatflow.docker.enabled>"," does ",[324,1112,1113],{},"not"," turn the build on — Maven ",[329,1116,1117],{},"\u003Cactivation>"," reads system\u002Fuser properties, not your project's. Activate the build with ",[329,1120,1121],{},"mvn -Pstoatflow-docker …"," \u002F ",[329,1124,1125],{},"mvn -Pstoatflow-native …"," (the ",[410,1128,1130],{"href":1129},"#build-and-run","build commands"," below). The ",[329,1133,385],{}," above only ",[872,1136,1137],{},"configure"," the build once a profile is active.",[341,1140,1141,1152],{},[344,1142,1143,1146,1147,1149,1150,386],{},[324,1144,1145],{},"Full Gradle DSL"," — every ",[329,1148,360],{}," property, task, and default: ",[410,1151,291],{"href":292},[344,1153,1154,1157,1158,1160,1161,386],{},[324,1155,1156],{},"Full Maven surface"," — the three artifacts, every ",[329,1159,385],{}," key, and the four goals: ",[410,1162,296],{"href":297},[427,1164,1166],{"id":1165},"gradle-maven-the-same-conventions-both-tools","Gradle ⇄ Maven: the same conventions, both tools",[320,1168,1169],{},"Everything one tool does has a counterpart on the other. If you've configured one, this is the map to the other:",[765,1171,1172,1192],{},[768,1173,1174],{},[771,1175,1176,1179,1185],{},[774,1177,1178],{},"Concept",[774,1180,1181,1182,1184],{},"Gradle (",[329,1183,352],{}," plugin)",[774,1186,1187,1188,1191],{},"Maven (",[329,1189,1190],{},"stoatflow-parent"," + plugin)",[781,1193,1194,1208,1223,1246,1261,1283,1304],{},[771,1195,1196,1198,1203],{},[786,1197,430],{},[786,1199,1200],{},[329,1201,1202],{},"plugins { id(\"io.stoatflow\") }",[786,1204,1205],{},[329,1206,1207],{},"\u003Cparent>io.stoatflow:stoatflow-parent\u003C\u002Fparent>",[771,1209,1210,1213,1218],{},[786,1211,1212],{},"Entry point",[786,1214,1215],{},[329,1216,1217],{},"stoatflow { mainClass.set(\"…\") }",[786,1219,1220],{},[329,1221,1222],{},"\u003Cstoatflow.mainClass>…\u003C\u002Fstoatflow.mainClass>",[771,1224,1225,1228,1238],{},[786,1226,1227],{},"Fat JAR",[786,1229,1230,1233,1234,1237],{},[329,1231,1232],{},".\u002Fgradlew shadowJar"," (",[329,1235,1236],{},"-all.jar",")",[786,1239,1240,1233,1243,1245],{},[329,1241,1242],{},"mvn package",[329,1244,1236],{},", via shade)",[771,1247,1248,1251,1256],{},[786,1249,1250],{},"Run (forked, preview on)",[786,1252,1253],{},[329,1254,1255],{},".\u002Fgradlew run",[786,1257,1258],{},[329,1259,1260],{},"mvn stoatflow:run",[771,1262,1263,1266,1275],{},[786,1264,1265],{},"Build a Docker image",[786,1267,1268,1271,1272],{},[329,1269,1270],{},"docker { enabled.set(true) }"," → ",[329,1273,1274],{},".\u002Fgradlew jibDockerBuild",[786,1276,1277,1271,1280],{},[329,1278,1279],{},"\u003Cstoatflow.docker…>",[329,1281,1282],{},"mvn -Pstoatflow-docker package",[771,1284,1285,1288,1296],{},[786,1286,1287],{},"Build a native image",[786,1289,1290,1271,1293],{},[329,1291,1292],{},"nativeImage { enabled.set(true) }",[329,1294,1295],{},".\u002Fgradlew nativeDockerBuild",[786,1297,1298,1271,1301],{},[329,1299,1300],{},"\u003Cstoatflow.nativeImage…>",[329,1302,1303],{},"mvn stoatflow:native-docker-build",[771,1305,1306,1309,1315],{},[786,1307,1308],{},"Aligned dependency versions",[786,1310,1311,1312],{},"resolved transitively from ",[329,1313,1314],{},"stoatflow-runtime",[786,1316,1317,1318,1320],{},"import ",[329,1319,373],{}," (the parent does this for you)",[732,1322,1324],{"color":734,"icon":1323},"i-lucide-git-compare",[320,1325,1326,1329,1330,1333,1334,1336,1337,1340,1341,1343],{},[324,1327,1328],{},"One source of truth under the hood."," Both build tools bundle the ",[872,1331,1332],{},"same"," native-image argument file, the ",[872,1335,1332],{}," generic ",[329,1338,1339],{},"Dockerfile.native",", and the ",[872,1342,1332],{}," container entrypoint scripts (shared from one internal module). A change to the native flags or the heap model lands on both at once — they can't drift.",[427,1345,1347],{"id":1346},"shared-build-behaviours","Shared build behaviours",[320,1349,1350],{},"These are identical across Gradle and Maven — worth understanding once.",[341,1352,1353,1379,1397],{},[344,1354,1355,1358,1359,1362,1363,1366,1367,1370,1371,1374,1375,1378],{},[324,1356,1357],{},"Reproducible images."," By default the image ",[329,1360,1361],{},"creationTime"," (JVM\u002FJib) and ",[329,1364,1365],{},"SOURCE_DATE_EPOCH"," (native) are pinned to your ",[324,1368,1369],{},"HEAD commit timestamp",", not wall-clock — so identical source produces an identical digest with a meaningful ",[329,1372,1373],{},"Created"," date. Outside a git repo the timestamp falls back to the Unix epoch. Turn it off with ",[329,1376,1377],{},"reproducibleBuild = false"," to restore wall-clock.",[344,1380,1381,1384,1385,1388,1389,1392,1393,386],{},[324,1382,1383],{},"Container-aware heap sizing."," The bundled entrypoint sizes the JVM (or native) heap from the ",[324,1386,1387],{},"container's"," memory limit (cgroup v1\u002Fv2), not the host's — no ",[329,1390,1391],{},"-Xmx"," guesswork under Kubernetes limits. The full model lives in ",[410,1394,1396],{"href":1395},"\u002Fdocs\u002Fruntime\u002Fdocker#container-aware-heap-sizing","Docker → Container-aware heap sizing",[344,1398,1399,1402,1403,1406,1407,1409,1410,1413,1414,1417,1418,1421],{},[324,1400,1401],{},"RocksDB off-heap auto-detection."," If ",[329,1404,1405],{},"org.rocksdb"," is on the runtime classpath (it is, via ",[329,1408,1314],{},"\u002F",[329,1411,1412],{},"stoatflow-core","), the image sets ",[329,1415,1416],{},"STOATFLOW_ROCKSDB_MB=256"," so the entrypoint reserves off-heap memory for the state store before sizing the heap. Override the reservation explicitly, or set it to ",[329,1419,1420],{},"0"," to skip the reservation for an app that only uses in-memory stores. Automatic on both build tools.",[427,1423,1425],{"id":1424},"build-and-run","Build and run",[439,1427,1428,1496],{"group":441},[443,1429,1433],{"className":1430,"code":1431,"filename":348,"language":1432,"meta":448,"style":448},"language-bash shiki shiki-themes vitesse-light",".\u002Fgradlew run             # run locally with the required JVM flags\n.\u002Fgradlew shadowJar       # build the fat JAR  → build\u002Flibs\u002F\u003Cname>-\u003Cversion>-all.jar\n.\u002Fgradlew test            # unit tests (IntegrationTest tag excluded)\n.\u002Fgradlew integrationTest # integration tests (only the IntegrationTest tag)\n.\u002Fgradlew jibDockerBuild  # build the container image   (docker.enabled)\n.\u002Fgradlew nativeDockerBuild # build the native image      (nativeImage.enabled)\n","bash",[329,1434,1435,1446,1456,1466,1476,1486],{"__ignoreMap":448},[452,1436,1437,1440,1443],{"class":454,"line":455},[452,1438,1439],{"class":465},".\u002Fgradlew",[452,1441,1442],{"class":482}," run",[452,1444,1445],{"class":458},"             # run locally with the required JVM flags\n",[452,1447,1448,1450,1453],{"class":454,"line":462},[452,1449,1439],{"class":465},[452,1451,1452],{"class":482}," shadowJar",[452,1454,1455],{"class":458},"       # build the fat JAR  → build\u002Flibs\u002F\u003Cname>-\u003Cversion>-all.jar\n",[452,1457,1458,1460,1463],{"class":454,"line":473},[452,1459,1439],{"class":465},[452,1461,1462],{"class":482}," test",[452,1464,1465],{"class":458},"            # unit tests (IntegrationTest tag excluded)\n",[452,1467,1468,1470,1473],{"class":454,"line":495},[452,1469,1439],{"class":465},[452,1471,1472],{"class":482}," integrationTest",[452,1474,1475],{"class":458}," # integration tests (only the IntegrationTest tag)\n",[452,1477,1478,1480,1483],{"class":454,"line":511},[452,1479,1439],{"class":465},[452,1481,1482],{"class":482}," jibDockerBuild",[452,1484,1485],{"class":458},"  # build the container image   (docker.enabled)\n",[452,1487,1488,1490,1493],{"class":454,"line":517},[452,1489,1439],{"class":465},[452,1491,1492],{"class":482}," nativeDockerBuild",[452,1494,1495],{"class":458}," # build the native image      (nativeImage.enabled)\n",[443,1497,1499],{"className":1430,"code":1498,"filename":366,"language":1432,"meta":448,"style":448},"mvn stoatflow:run               # run locally (forked JVM, --enable-preview)\nmvn package                     # fat JAR  → target\u002F\u003Cname>-\u003Cversion>-all.jar\nmvn test                        # unit tests (IntegrationTest tag excluded)\nmvn verify                      # + integration tests (failsafe)\nmvn -Pstoatflow-docker package  # build the container image (one command)\nmvn stoatflow:native-docker-build # build the native image (run mvn package first)\n",[329,1500,1501,1512,1522,1531,1541,1554],{"__ignoreMap":448},[452,1502,1503,1506,1509],{"class":454,"line":455},[452,1504,1505],{"class":465},"mvn",[452,1507,1508],{"class":482}," stoatflow:run",[452,1510,1511],{"class":458},"               # run locally (forked JVM, --enable-preview)\n",[452,1513,1514,1516,1519],{"class":454,"line":462},[452,1515,1505],{"class":465},[452,1517,1518],{"class":482}," package",[452,1520,1521],{"class":458},"                     # fat JAR  → target\u002F\u003Cname>-\u003Cversion>-all.jar\n",[452,1523,1524,1526,1528],{"class":454,"line":473},[452,1525,1505],{"class":465},[452,1527,1462],{"class":482},[452,1529,1530],{"class":458},"                        # unit tests (IntegrationTest tag excluded)\n",[452,1532,1533,1535,1538],{"class":454,"line":495},[452,1534,1505],{"class":465},[452,1536,1537],{"class":482}," verify",[452,1539,1540],{"class":458},"                      # + integration tests (failsafe)\n",[452,1542,1543,1545,1549,1551],{"class":454,"line":511},[452,1544,1505],{"class":465},[452,1546,1548],{"class":1547},"sEi1f"," -Pstoatflow-docker",[452,1550,1518],{"class":482},[452,1552,1553],{"class":458},"  # build the container image (one command)\n",[452,1555,1556,1558,1561],{"class":454,"line":517},[452,1557,1505],{"class":465},[452,1559,1560],{"class":482}," stoatflow:native-docker-build",[452,1562,1563],{"class":458}," # build the native image (run mvn package first)\n",[732,1565,1567],{"color":734,"icon":1566},"i-lucide-terminal",[320,1568,1569,1575,1576,1578,1579,1582,1583,1586,1587,1590,1591,386],{},[324,1570,1571,1574],{},[329,1572,1573],{},"mvn stoatflow:…"," short prefix."," To call the plugin's standalone goals by their short prefix, add ",[329,1577,352],{}," to ",[329,1580,1581],{},"\u003CpluginGroups>"," in your ",[329,1584,1585],{},"~\u002F.m2\u002Fsettings.xml",". Without it, use full coordinates — ",[329,1588,1589],{},"mvn io.stoatflow:stoatflow-maven-plugin:run",". See the ",[410,1592,296],{"href":1593},"\u002Fdocs\u002Freference\u002Fmaven-reference#set-up",[427,1595,1597],{"id":1596},"worked-examples","Worked examples",[320,1599,1600],{},"A complete build for each tool, both languages:",[439,1602,1603,1749],{"group":441},[443,1604,1606],{"className":445,"code":1605,"filename":348,"language":447,"meta":448,"style":448},"\u002F\u002F build.gradle.kts\nplugins {\n    kotlin(\"jvm\") version \"2.4.0\"   \u002F\u002F drop this line for a Java-only project\n    id(\"io.stoatflow\") version \"\u003Cstoatflow-version>\"\n}\n\ndependencies {\n    implementation(\"io.stoatflow:stoatflow-runtime:\u003Cstoatflow-version>\")\n    testImplementation(\"io.stoatflow:stoatflow-test-utils:\u003Cstoatflow-version>\")\n}\n\nstoatflow {\n    mainClass.set(\"com.example.MainKt\")   \u002F\u002F Java: \"com.example.Main\"\n    docker {\n        enabled.set(true)\n        imageName.set(\"acme\u002Fword-count\")\n    }\n}\n",[329,1607,1608,1612,1618,1633,1645,1649,1653,1659,1669,1681,1685,1689,1695,1711,1717,1729,1741,1745],{"__ignoreMap":448},[452,1609,1610],{"class":454,"line":455},[452,1611,459],{"class":458},[452,1613,1614,1616],{"class":454,"line":462},[452,1615,466],{"class":465},[452,1617,470],{"class":469},[452,1619,1620,1622,1624,1626,1628,1630],{"class":454,"line":473},[452,1621,476],{"class":465},[452,1623,479],{"class":469},[452,1625,483],{"class":482},[452,1627,486],{"class":469},[452,1629,489],{"class":482},[452,1631,1632],{"class":458},"   \u002F\u002F drop this line for a Java-only project\n",[452,1634,1635,1637,1639,1641,1643],{"class":454,"line":495},[452,1636,498],{"class":465},[452,1638,479],{"class":469},[452,1640,503],{"class":482},[452,1642,486],{"class":469},[452,1644,508],{"class":482},[452,1646,1647],{"class":454,"line":511},[452,1648,514],{"class":469},[452,1650,1651],{"class":454,"line":517},[452,1652,521],{"emptyLinePlaceholder":520},[452,1654,1655,1657],{"class":454,"line":524},[452,1656,565],{"class":465},[452,1658,470],{"class":469},[452,1660,1661,1663,1665,1667],{"class":454,"line":532},[452,1662,573],{"class":465},[452,1664,479],{"class":469},[452,1666,578],{"class":482},[452,1668,581],{"class":469},[452,1670,1671,1674,1676,1679],{"class":454,"line":552},[452,1672,1673],{"class":465},"    testImplementation",[452,1675,479],{"class":469},[452,1677,1678],{"class":482},"\"io.stoatflow:stoatflow-test-utils:\u003Cstoatflow-version>\"",[452,1680,581],{"class":469},[452,1682,1683],{"class":454,"line":557},[452,1684,514],{"class":469},[452,1686,1687],{"class":454,"line":562},[452,1688,521],{"emptyLinePlaceholder":520},[452,1690,1691,1693],{"class":454,"line":570},[452,1692,527],{"class":465},[452,1694,470],{"class":469},[452,1696,1697,1699,1701,1703,1705,1708],{"class":454,"line":584},[452,1698,535],{"class":469},[452,1700,538],{"class":465},[452,1702,479],{"class":469},[452,1704,543],{"class":482},[452,1706,1707],{"class":469},")   ",[452,1709,1710],{"class":458},"\u002F\u002F Java: \"com.example.Main\"\n",[452,1712,1713,1715],{"class":454,"line":659},[452,1714,967],{"class":465},[452,1716,470],{"class":469},[452,1718,1719,1721,1723,1725,1727],{"class":454,"line":665},[452,1720,974],{"class":469},[452,1722,538],{"class":465},[452,1724,479],{"class":469},[452,1726,982],{"class":981},[452,1728,581],{"class":469},[452,1730,1731,1733,1735,1737,1739],{"class":454,"line":671},[452,1732,993],{"class":469},[452,1734,538],{"class":465},[452,1736,479],{"class":469},[452,1738,1000],{"class":482},[452,1740,581],{"class":469},[452,1742,1743],{"class":454,"line":677},[452,1744,1007],{"class":469},[452,1746,1747],{"class":454,"line":683},[452,1748,514],{"class":469},[443,1750,1752],{"className":589,"code":1751,"filename":366,"language":591,"meta":448,"style":448},"\u003C!-- pom.xml — a StoatFlow app on the parent POM -->\n\u003Cproject>\n  \u003CmodelVersion>4.0.0\u003C\u002FmodelVersion>\n  \u003Cparent>\n    \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n    \u003CartifactId>stoatflow-parent\u003C\u002FartifactId>\n    \u003Cversion>REPLACE-WITH-CURRENT-RELEASE\u003C\u002Fversion>  \u003C!-- literal — Maven can't resolve a property in \u003Cparent> -->\n    \u003CrelativePath\u002F>\n  \u003C\u002Fparent>\n\n  \u003CgroupId>com.example\u003C\u002FgroupId>\n  \u003CartifactId>word-count\u003C\u002FartifactId>\n  \u003Cversion>1.0.0\u003C\u002Fversion>\n\n  \u003Cproperties>\n    \u003Cstoatflow.mainClass>com.example.MainKt\u003C\u002Fstoatflow.mainClass>   \u003C!-- Java: com.example.Main -->\n    \u003Cstoatflow.docker.imageName>acme\u002Fword-count\u003C\u002Fstoatflow.docker.imageName>\n  \u003C\u002Fproperties>\n\n  \u003C!-- Kotlin only: point Maven at src\u002Fmain\u002Fkotlin and add the stdlib -->\n  \u003Cbuild>\u003CsourceDirectory>src\u002Fmain\u002Fkotlin\u003C\u002FsourceDirectory>\u003C\u002Fbuild>\n\n  \u003Cdependencies>\n    \u003Cdependency>\n      \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n      \u003CartifactId>stoatflow-runtime\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n      \u003CgroupId>org.jetbrains.kotlin\u003C\u002FgroupId>\n      \u003CartifactId>kotlin-stdlib\u003C\u002FartifactId>\n      \u003Cversion>${kotlin.version}\u003C\u002Fversion>   \u003C!-- omit for a Java app -->\n    \u003C\u002Fdependency>\n  \u003C\u002Fdependencies>\n\u003C\u002Fproject>\n",[329,1753,1754,1759,1764,1769,1774,1778,1783,1788,1793,1798,1802,1807,1812,1817,1821,1826,1831,1836,1841,1845,1851,1857,1862,1868,1874,1880,1886,1892,1897,1903,1909,1915,1920,1926],{"__ignoreMap":448},[452,1755,1756],{"class":454,"line":455},[452,1757,1758],{},"\u003C!-- pom.xml — a StoatFlow app on the parent POM -->\n",[452,1760,1761],{"class":454,"line":462},[452,1762,1763],{},"\u003Cproject>\n",[452,1765,1766],{"class":454,"line":473},[452,1767,1768],{},"  \u003CmodelVersion>4.0.0\u003C\u002FmodelVersion>\n",[452,1770,1771],{"class":454,"line":495},[452,1772,1773],{},"  \u003Cparent>\n",[452,1775,1776],{"class":454,"line":511},[452,1777,668],{},[452,1779,1780],{"class":454,"line":517},[452,1781,1782],{},"    \u003CartifactId>stoatflow-parent\u003C\u002FartifactId>\n",[452,1784,1785],{"class":454,"line":524},[452,1786,1787],{},"    \u003Cversion>REPLACE-WITH-CURRENT-RELEASE\u003C\u002Fversion>  \u003C!-- literal — Maven can't resolve a property in \u003Cparent> -->\n",[452,1789,1790],{"class":454,"line":532},[452,1791,1792],{},"    \u003CrelativePath\u002F>\n",[452,1794,1795],{"class":454,"line":552},[452,1796,1797],{},"  \u003C\u002Fparent>\n",[452,1799,1800],{"class":454,"line":557},[452,1801,521],{"emptyLinePlaceholder":520},[452,1803,1804],{"class":454,"line":562},[452,1805,1806],{},"  \u003CgroupId>com.example\u003C\u002FgroupId>\n",[452,1808,1809],{"class":454,"line":570},[452,1810,1811],{},"  \u003CartifactId>word-count\u003C\u002FartifactId>\n",[452,1813,1814],{"class":454,"line":584},[452,1815,1816],{},"  \u003Cversion>1.0.0\u003C\u002Fversion>\n",[452,1818,1819],{"class":454,"line":659},[452,1820,521],{"emptyLinePlaceholder":520},[452,1822,1823],{"class":454,"line":665},[452,1824,1825],{},"  \u003Cproperties>\n",[452,1827,1828],{"class":454,"line":671},[452,1829,1830],{},"    \u003Cstoatflow.mainClass>com.example.MainKt\u003C\u002Fstoatflow.mainClass>   \u003C!-- Java: com.example.Main -->\n",[452,1832,1833],{"class":454,"line":677},[452,1834,1835],{},"    \u003Cstoatflow.docker.imageName>acme\u002Fword-count\u003C\u002Fstoatflow.docker.imageName>\n",[452,1837,1838],{"class":454,"line":683},[452,1839,1840],{},"  \u003C\u002Fproperties>\n",[452,1842,1843],{"class":454,"line":689},[452,1844,521],{"emptyLinePlaceholder":520},[452,1846,1848],{"class":454,"line":1847},20,[452,1849,1850],{},"  \u003C!-- Kotlin only: point Maven at src\u002Fmain\u002Fkotlin and add the stdlib -->\n",[452,1852,1854],{"class":454,"line":1853},21,[452,1855,1856],{},"  \u003Cbuild>\u003CsourceDirectory>src\u002Fmain\u002Fkotlin\u003C\u002FsourceDirectory>\u003C\u002Fbuild>\n",[452,1858,1860],{"class":454,"line":1859},22,[452,1861,521],{"emptyLinePlaceholder":520},[452,1863,1865],{"class":454,"line":1864},23,[452,1866,1867],{},"  \u003Cdependencies>\n",[452,1869,1871],{"class":454,"line":1870},24,[452,1872,1873],{},"    \u003Cdependency>\n",[452,1875,1877],{"class":454,"line":1876},25,[452,1878,1879],{},"      \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n",[452,1881,1883],{"class":454,"line":1882},26,[452,1884,1885],{},"      \u003CartifactId>stoatflow-runtime\u003C\u002FartifactId>\n",[452,1887,1889],{"class":454,"line":1888},27,[452,1890,1891],{},"    \u003C\u002Fdependency>\n",[452,1893,1895],{"class":454,"line":1894},28,[452,1896,1873],{},[452,1898,1900],{"class":454,"line":1899},29,[452,1901,1902],{},"      \u003CgroupId>org.jetbrains.kotlin\u003C\u002FgroupId>\n",[452,1904,1906],{"class":454,"line":1905},30,[452,1907,1908],{},"      \u003CartifactId>kotlin-stdlib\u003C\u002FartifactId>\n",[452,1910,1912],{"class":454,"line":1911},31,[452,1913,1914],{},"      \u003Cversion>${kotlin.version}\u003C\u002Fversion>   \u003C!-- omit for a Java app -->\n",[452,1916,1918],{"class":454,"line":1917},32,[452,1919,1891],{},[452,1921,1923],{"class":454,"line":1922},33,[452,1924,1925],{},"  \u003C\u002Fdependencies>\n",[452,1927,1929],{"class":454,"line":1928},34,[452,1930,1931],{},"\u003C\u002Fproject>\n",[732,1933,1934],{"color":734,"icon":735},[320,1935,1936,1937,386],{},"Don't want a build plugin at all? Both tools have a \"configure it yourself\" path — set the JDK 25 toolchain and the two JVM flags by hand. See ",[410,1938,1940],{"href":1939},"\u002Fdocs\u002Fgetting-started\u002Finstallation#option-b-configure-it-yourself","Installation → Option B",[427,1942,1944],{"id":1943},"next-steps","Next steps",[341,1946,1947,1954,1965,1977],{},[344,1948,1949,1953],{},[324,1950,1951],{},[410,1952,28],{"href":29}," — build and run a complete word-count app on the runtime.",[344,1955,1956,374,1960,1964],{},[324,1957,1958],{},[410,1959,412],{"href":211},[324,1961,1962],{},[410,1963,897],{"href":216}," — the full container and GraalVM build guides.",[344,1966,1967,1971,1972,1976],{},[324,1968,1969],{},[410,1970,291],{"href":292}," · ",[324,1973,1974],{},[410,1975,296],{"href":297}," — every knob, task, and default.",[344,1978,1979,1980,1984],{},"Stuck on the build? ",[410,1981,1983],{"href":1982},"\u002Fcontact","Get in touch"," — real people read every email during the alpha.",[1986,1987,1988],"style",{},"html pre.shiki code .s8zF2, html code.shiki .s8zF2{--shiki-default:#A0ADA0}html pre.shiki code .sySUi, html code.shiki .sySUi{--shiki-default:#59873A}html pre.shiki code .suHK_, html code.shiki .suHK_{--shiki-default:#393A34}html pre.shiki code .spphp, html code.shiki .spphp{--shiki-default:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sbBg2, html code.shiki .sbBg2{--shiki-default:#1E754F}html pre.shiki code .sEi1f, html code.shiki .sEi1f{--shiki-default:#A65E2B}",{"title":448,"searchDepth":462,"depth":462,"links":1990},[1991,1992,1993,1994,1995,1996,1997,1998],{"id":429,"depth":462,"text":430},{"id":759,"depth":462,"text":760},{"id":918,"depth":462,"text":919},{"id":1165,"depth":462,"text":1166},{"id":1346,"depth":462,"text":1347},{"id":1424,"depth":462,"text":1425},{"id":1596,"depth":462,"text":1597},{"id":1943,"depth":462,"text":1944},"Apply StoatFlow's build conventions with Gradle or Maven — the JDK 25 toolchain, the required JVM flags, a runnable fat JAR, and opt-in reproducible Docker and GraalVM native images, from a few lines of config.","md",{},{"icon":36},"how-to",{"title":33,"description":1999},"qCkVU2j43tRJcZ03GU6XQ1hE4on0DtQag8RxU7D8JXk",[2007,2009],{"title":28,"path":29,"stem":30,"description":2008,"icon":31,"children":-1},"Build and run a complete word-count stream processor on the StoatFlow runtime — in Kotlin or Java.",{"title":44,"path":40,"stem":41,"description":2010,"icon":45,"children":-1},"A map of the StoatFlow concept pages and the order to read them in — from the single-instance architecture through exactly-once, lanes, state, event time, configuration, and error handling.",1783713351004]