diff --git a/internal/buildengine/build_java.go b/internal/buildengine/build_java.go
index 879c8af4f8..6909ef348e 100644
--- a/internal/buildengine/build_java.go
+++ b/internal/buildengine/build_java.go
@@ -24,7 +24,6 @@ func buildJavaModule(ctx context.Context, module Module) error {
}
logger.Infof("Using build command '%s'", module.Config.Build)
command := exec.Command(ctx, log.Debug, module.Config.Dir, "bash", "-c", module.Config.Build)
- command.Env = append(command.Env, "FTL_MODULE_NAME="+module.Config.Module)
err := command.RunBuffered(ctx)
if err != nil {
return fmt.Errorf("failed to build module %q: %w", module.Config.Module, err)
diff --git a/jvm-runtime/ftl-runtime/common/deployment/pom.xml b/jvm-runtime/ftl-runtime/common/deployment/pom.xml
index 766da8745e..0ba449822e 100644
--- a/jvm-runtime/ftl-runtime/common/deployment/pom.xml
+++ b/jvm-runtime/ftl-runtime/common/deployment/pom.xml
@@ -31,12 +31,15 @@
io.quarkus
quarkus-credentials-deployment
-
xyz.block.ftl
ftl-jvm-runtime
${project.version}
+
+ org.tomlj
+ tomlj
+
io.quarkus
quarkus-junit5-internal
diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/FTLBuildTimeConfig.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/FTLBuildTimeConfig.java
deleted file mode 100644
index 174014bb04..0000000000
--- a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/FTLBuildTimeConfig.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package xyz.block.ftl.deployment;
-
-import java.util.Optional;
-
-import io.quarkus.runtime.annotations.ConfigItem;
-import io.quarkus.runtime.annotations.ConfigRoot;
-
-@ConfigRoot(name = "ftl")
-public class FTLBuildTimeConfig {
-
- /**
- * The FTL module name, should be set automatically during build
- */
- @ConfigItem
- public Optional moduleName;
-}
diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java
index 37eed9da1e..70f98075a4 100644
--- a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java
+++ b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/FtlProcessor.java
@@ -52,10 +52,8 @@
import io.quarkus.deployment.builditem.ApplicationInfoBuildItem;
import io.quarkus.deployment.builditem.ApplicationStartBuildItem;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
-import io.quarkus.deployment.builditem.RunTimeConfigBuilderBuildItem;
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
import io.quarkus.deployment.builditem.SystemPropertyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
@@ -91,7 +89,6 @@
import xyz.block.ftl.runtime.builtin.HttpRequest;
import xyz.block.ftl.runtime.builtin.HttpResponse;
import xyz.block.ftl.runtime.config.FTLConfigSource;
-import xyz.block.ftl.runtime.config.FTLConfigSourceFactoryBuilder;
import xyz.block.ftl.v1.CallRequest;
import xyz.block.ftl.v1.schema.Any;
import xyz.block.ftl.v1.schema.Array;
@@ -124,7 +121,6 @@ class FtlProcessor {
private static final Logger log = Logger.getLogger(FtlProcessor.class);
private static final String SCHEMA_OUT = "schema.pb";
- private static final String FEATURE = "ftl-java-runtime";
public static final DotName EXPORT = DotName.createSimple(Export.class);
public static final DotName VERB = DotName.createSimple(Verb.class);
public static final DotName CRON = DotName.createSimple(Cron.class);
@@ -141,21 +137,6 @@ class FtlProcessor {
public static final DotName NOT_NULL = DotName.createSimple(NotNull.class);
public static final DotName JSON_NODE = DotName.createSimple(JsonNode.class.getName());
- @BuildStep
- ModuleNameBuildItem moduleName(ApplicationInfoBuildItem applicationInfoBuildItem, FTLBuildTimeConfig buildTimeConfig) {
- return new ModuleNameBuildItem(buildTimeConfig.moduleName.orElse(applicationInfoBuildItem.getName()));
- }
-
- @BuildStep
- RunTimeConfigBuilderBuildItem runTimeConfigBuilderBuildItem() {
- return new RunTimeConfigBuilderBuildItem(FTLConfigSourceFactoryBuilder.class.getName());
- }
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
@BuildStep
BindableServiceBuildItem verbService() {
var ret = new BindableServiceBuildItem(DotName.createSimple(VerbHandler.class));
diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleProcessor.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleProcessor.java
new file mode 100644
index 0000000000..21197e4e49
--- /dev/null
+++ b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleProcessor.java
@@ -0,0 +1,67 @@
+package xyz.block.ftl.deployment;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import org.jboss.logging.Logger;
+import org.tomlj.Toml;
+import org.tomlj.TomlParseResult;
+
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
+import io.quarkus.deployment.builditem.ApplicationInfoBuildItem;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+import io.quarkus.deployment.builditem.RunTimeConfigBuilderBuildItem;
+import xyz.block.ftl.runtime.config.FTLConfigSourceFactoryBuilder;
+
+public class ModuleProcessor {
+
+ private static final Logger log = Logger.getLogger(ModuleProcessor.class);
+
+ private static final String FEATURE = "ftl-java-runtime";
+
+ @BuildStep
+ ModuleNameBuildItem moduleName(ApplicationInfoBuildItem applicationInfoBuildItem,
+ ApplicationArchivesBuildItem archivesBuildItem) throws IOException {
+ for (var root : archivesBuildItem.getRootArchive().getRootDirectories()) {
+ Path source = root;
+ for (;;) {
+ var toml = source.resolve("ftl.toml");
+ if (Files.exists(toml)) {
+ TomlParseResult result = Toml.parse(toml);
+ if (result.hasErrors()) {
+ throw new RuntimeException("Failed to parse " + toml + " "
+ + result.errors().stream().map(Objects::toString).collect(Collectors.joining(", ")));
+ }
+
+ String value = result.getString("module");
+ if (value != null) {
+ return new ModuleNameBuildItem(value);
+ } else {
+ log.errorf("module name not found in %s", toml);
+ }
+ }
+ if (source.getParent() == null) {
+ break;
+ } else {
+ source = source.getParent();
+ }
+ }
+ }
+
+ return new ModuleNameBuildItem(applicationInfoBuildItem.getName());
+ }
+
+ @BuildStep
+ RunTimeConfigBuilderBuildItem runTimeConfigBuilderBuildItem() {
+ return new RunTimeConfigBuilderBuildItem(FTLConfigSourceFactoryBuilder.class.getName());
+ }
+
+ @BuildStep
+ FeatureBuildItem feature() {
+ return new FeatureBuildItem(FEATURE);
+ }
+}
diff --git a/jvm-runtime/ftl-runtime/pom.xml b/jvm-runtime/ftl-runtime/pom.xml
index 93380fc60f..c910731441 100644
--- a/jvm-runtime/ftl-runtime/pom.xml
+++ b/jvm-runtime/ftl-runtime/pom.xml
@@ -29,6 +29,7 @@
2.24.1
1.11.0
1.18.1
+ 1.1.1
@@ -72,6 +73,11 @@
pom
import
+
+ org.tomlj
+ tomlj
+ ${tomlj.version}
+
com.squareup
diff --git a/jvm-runtime/testdata/java/verbs/pom.xml b/jvm-runtime/testdata/java/verbs/pom.xml
index 9c9231cd8d..17cc01f697 100644
--- a/jvm-runtime/testdata/java/verbs/pom.xml
+++ b/jvm-runtime/testdata/java/verbs/pom.xml
@@ -2,7 +2,7 @@
4.0.0
xyz.block.ftl.examples
- verbs
+ verbs-module
1.0-SNAPSHOT