From c12271c764cf07cd9ecc7b2c36c9c15b96170e57 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Mon, 23 Sep 2024 13:17:26 +1000 Subject: [PATCH] fix: disallow non-static inner classes fixes: #2746 --- examples/java/echo/ftl.toml | 2 ++ examples/java/echo/pom.xml | 14 ++++++++++++++ .../java/echo/src/main/java/ftl/echo/Echo.java | 15 +++++++++++++++ .../src/main/java/ftl/echo/EchoRequest.java | 6 ++++++ .../src/main/java/ftl/echo/EchoResponse.java | 4 ++++ examples/java/time/ftl.toml | 2 ++ examples/java/time/pom.xml | 14 ++++++++++++++ .../java/time/src/main/java/ftl/time/Time.java | 15 +++++++++++++++ .../src/main/java/ftl/time/TimeResponse.java | 6 ++++++ .../xyz/block/ftl/deployment/ModuleBuilder.java | 17 +++++++++++++++++ 10 files changed, 95 insertions(+) create mode 100644 examples/java/echo/ftl.toml create mode 100644 examples/java/echo/pom.xml create mode 100644 examples/java/echo/src/main/java/ftl/echo/Echo.java create mode 100644 examples/java/echo/src/main/java/ftl/echo/EchoRequest.java create mode 100644 examples/java/echo/src/main/java/ftl/echo/EchoResponse.java create mode 100644 examples/java/time/ftl.toml create mode 100644 examples/java/time/pom.xml create mode 100644 examples/java/time/src/main/java/ftl/time/Time.java create mode 100644 examples/java/time/src/main/java/ftl/time/TimeResponse.java diff --git a/examples/java/echo/ftl.toml b/examples/java/echo/ftl.toml new file mode 100644 index 0000000000..700b9d8833 --- /dev/null +++ b/examples/java/echo/ftl.toml @@ -0,0 +1,2 @@ +module = "echo" +language = "kotlin" diff --git a/examples/java/echo/pom.xml b/examples/java/echo/pom.xml new file mode 100644 index 0000000000..7389eb00df --- /dev/null +++ b/examples/java/echo/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + xyz.block.ftl.examples + echo + 1.0-SNAPSHOT + + + xyz.block.ftl + ftl-build-parent-java + 1.0-SNAPSHOT + + + diff --git a/examples/java/echo/src/main/java/ftl/echo/Echo.java b/examples/java/echo/src/main/java/ftl/echo/Echo.java new file mode 100644 index 0000000000..1339b91066 --- /dev/null +++ b/examples/java/echo/src/main/java/ftl/echo/Echo.java @@ -0,0 +1,15 @@ +package ftl.echo; + +import ftl.time.TimeClient; +import xyz.block.ftl.Export; +import xyz.block.ftl.Verb; + +public class Echo { + + @Export + @Verb + public EchoResponse echo(EchoRequest req, TimeClient time) { + var response = time.call(); + return new EchoResponse("Hello, " + req.name().orElse("anonymous") + "! The time is " + response.toString() + "."); + } +} diff --git a/examples/java/echo/src/main/java/ftl/echo/EchoRequest.java b/examples/java/echo/src/main/java/ftl/echo/EchoRequest.java new file mode 100644 index 0000000000..0aa0a4b531 --- /dev/null +++ b/examples/java/echo/src/main/java/ftl/echo/EchoRequest.java @@ -0,0 +1,6 @@ +package ftl.echo; + +import java.util.Optional; + +public record EchoRequest(Optional name) { +} diff --git a/examples/java/echo/src/main/java/ftl/echo/EchoResponse.java b/examples/java/echo/src/main/java/ftl/echo/EchoResponse.java new file mode 100644 index 0000000000..37db3e18bb --- /dev/null +++ b/examples/java/echo/src/main/java/ftl/echo/EchoResponse.java @@ -0,0 +1,4 @@ +package ftl.echo; + +public record EchoResponse(String message) { +} diff --git a/examples/java/time/ftl.toml b/examples/java/time/ftl.toml new file mode 100644 index 0000000000..48033f28f8 --- /dev/null +++ b/examples/java/time/ftl.toml @@ -0,0 +1,2 @@ +module = "time" +language = "kotlin" diff --git a/examples/java/time/pom.xml b/examples/java/time/pom.xml new file mode 100644 index 0000000000..94132b0569 --- /dev/null +++ b/examples/java/time/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + xyz.block.ftl.examples + time + 1.0-SNAPSHOT + + + xyz.block.ftl + ftl-build-parent-java + 1.0-SNAPSHOT + + + diff --git a/examples/java/time/src/main/java/ftl/time/Time.java b/examples/java/time/src/main/java/ftl/time/Time.java new file mode 100644 index 0000000000..b3951c0f4f --- /dev/null +++ b/examples/java/time/src/main/java/ftl/time/Time.java @@ -0,0 +1,15 @@ +package ftl.time; + +import java.time.OffsetDateTime; + +import xyz.block.ftl.Export; +import xyz.block.ftl.Verb; + +public class Time { + + @Verb + @Export + public static TimeResponse time() { + return new TimeResponse(OffsetDateTime.now()); + } +} diff --git a/examples/java/time/src/main/java/ftl/time/TimeResponse.java b/examples/java/time/src/main/java/ftl/time/TimeResponse.java new file mode 100644 index 0000000000..6209efb493 --- /dev/null +++ b/examples/java/time/src/main/java/ftl/time/TimeResponse.java @@ -0,0 +1,6 @@ +package ftl.time; + +import java.time.OffsetDateTime; + +public record TimeResponse(OffsetDateTime time) { +} \ No newline at end of file diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleBuilder.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleBuilder.java index 7a078a04db..155286ace3 100644 --- a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleBuilder.java +++ b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleBuilder.java @@ -85,6 +85,7 @@ public class ModuleBuilder { private final Map verbClients; private final FTLRecorder recorder; private final Map verbDocs; + private final List validationFailures = new ArrayList<>(); public ModuleBuilder(IndexView index, String moduleName, Map knownTopics, Map verbClients, FTLRecorder recorder, @@ -294,6 +295,11 @@ public Type buildType(org.jboss.jandex.Type type, boolean export) { case CLASS -> { var clazz = type.asClassType(); var info = index.getClassByName(clazz.name()); + if (info.enclosingClass() != null && !Modifier.isStatic(info.flags())) { + // proceed as normal, we fail at the end + validationFailures.add(new ValidationFailure(clazz.name().toString(), + "Inner classes must be static")); + } PrimitiveType unboxed = PrimitiveType.unbox(clazz); if (unboxed != null) { @@ -435,6 +441,14 @@ public ModuleBuilder addDecls(Decl decl) { } public void writeTo(OutputStream out) throws IOException { + if (!validationFailures.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (var failure : validationFailures) { + sb.append("Validation failure: ").append(failure.className).append(": ").append(failure.message) + .append("\n"); + } + throw new RuntimeException(sb.toString()); + } moduleBuilder.build().writeTo(out); } @@ -456,4 +470,7 @@ public enum BodyType { ALLOWED, REQUIRED } + + record ValidationFailure(String className, String message) { + } }