diff --git a/pom.xml b/pom.xml
index 21bfbd93..957b08cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -99,7 +99,7 @@ limitations under the License.
spring-modulith-integration-test
- spring-modulith-example
+ spring-modulith-examples
@@ -132,7 +132,7 @@ limitations under the License.
spring-modulith-distribution
- spring-modulith-example
+ spring-modulith-examples
spring-modulith-integration-test
diff --git a/spring-modulith-example/pom.xml b/spring-modulith-examples/pom.xml
similarity index 58%
rename from spring-modulith-example/pom.xml
rename to spring-modulith-examples/pom.xml
index 51b30ff9..78d7f893 100644
--- a/spring-modulith-example/pom.xml
+++ b/spring-modulith-examples/pom.xml
@@ -1,17 +1,25 @@
-
-
+
4.0.0
org.springframework.boot
spring-boot-starter-parent
- 3.0.3
+ 3.1.0-RC1
- spring-modulith-example
- Spring Modulith - Example
+ org.springframework.experimental
+ spring-modulith-examples
0.6.0-SNAPSHOT
+ pom
+
+ Spring Modulith - Examples
+
+
+ spring-modulith-examples-epr-jdbc
+ spring-modulith-examples-epr-mongodb
+ spring-modulith-examples-full
+
17
@@ -29,7 +37,7 @@
org.jmolecules
jmolecules-bom
- 2022.2.2
+ 2022.3.0
pom
import
@@ -48,53 +56,6 @@
spring-boot-starter-json
-
- org.springframework.experimental
- spring-modulith-starter-jpa
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-actuator
-
-
-
- org.springframework.experimental
- spring-modulith-actuator
-
-
-
-
-
- org.jmolecules
- jmolecules-ddd
-
-
-
- org.jmolecules
- jmolecules-events
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
-
- com.h2database
- h2
- runtime
-
-
@@ -111,12 +72,6 @@
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
org.projectlombok
lombok
@@ -126,6 +81,13 @@
+
+ spring-milestone
+ https://repo.spring.io/milestone
+
+ false
+
+
spring-snapshot
https://repo.spring.io/snapshot
@@ -136,6 +98,13 @@
+
+ spring-milestone
+ https://repo.spring.io/milestone
+
+ false
+
+
spring-snapshot
https://repo.spring.io/snapshot
@@ -144,4 +113,5 @@
+
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/pom.xml b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/pom.xml
new file mode 100644
index 00000000..a98ca2ce
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+
+
+ org.springframework.experimental
+ spring-modulith-examples
+ 0.6.0-SNAPSHOT
+ ../pom.xml
+
+
+ spring-modulith-examples-epr-jdbc
+ Spring Modulith - Examples - EPR JDBC Example
+
+
+
+
+ org.springframework.experimental
+ spring-modulith-starter-jdbc
+
+
+
+
+
+ org.jmolecules
+ jmolecules-events
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jdbc
+
+
+
+ org.testcontainers
+ junit-jupiter
+ test
+
+
+
+ org.postgresql
+ postgresql
+
+
+
+ org.testcontainers
+ postgresql
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-testcontainers
+ test
+
+
+
+
+
diff --git a/spring-modulith-example/src/main/asciidoc/index.adoc b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/asciidoc/index.adoc
similarity index 100%
rename from spring-modulith-example/src/main/asciidoc/index.adoc
rename to spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/asciidoc/index.adoc
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/Application.java b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/Application.java
new file mode 100644
index 00000000..e74c7a88
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/Application.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Spring Modulith example application
+ *
+ * @author Oliver Drotbohm
+ */
+@SpringBootApplication
+public class Application {
+
+ public static void main(String... args) throws Exception {}
+}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/inventory/InventoryManagement.java b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/inventory/InventoryManagement.java
new file mode 100644
index 00000000..52d96746
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/inventory/InventoryManagement.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example.inventory;
+
+import example.order.OrderCompleted;
+import lombok.RequiredArgsConstructor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.modulith.ApplicationModuleListener;
+import org.springframework.stereotype.Service;
+
+/**
+ * A Spring {@link Service} exposed by the inventory module.
+ *
+ * @author Oliver Drotbohm
+ */
+@Service
+@RequiredArgsConstructor
+class InventoryManagement {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InventoryManagement.class);
+
+ private final ApplicationEventPublisher events;
+
+ @ApplicationModuleListener
+ void on(OrderCompleted event) throws InterruptedException {
+
+ var orderId = event.orderId();
+
+ LOG.info("Received order completion for {}.", orderId);
+
+ // Simulate busy work
+ Thread.sleep(1000);
+ events.publishEvent(new InventoryUpdated(orderId));
+
+ LOG.info("Finished order completion for {}.", orderId);
+ }
+}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/inventory/InventoryUpdated.java b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/inventory/InventoryUpdated.java
new file mode 100644
index 00000000..b4c7c29c
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/inventory/InventoryUpdated.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example.inventory;
+
+import java.util.UUID;
+
+/**
+ * @author Oliver Drotbohm
+ */
+public record InventoryUpdated(UUID orderId) {}
diff --git a/spring-modulith-example/src/main/java/example/inventory/package-info.java b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/inventory/package-info.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/inventory/package-info.java
rename to spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/inventory/package-info.java
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/order/OrderCompleted.java b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/order/OrderCompleted.java
new file mode 100644
index 00000000..5aa24d46
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/order/OrderCompleted.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example.order;
+
+import java.util.UUID;
+
+import org.jmolecules.event.types.DomainEvent;
+
+/**
+ * @author Oliver Drotbohm
+ */
+public record OrderCompleted(UUID orderId) implements DomainEvent {}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/order/OrderManagement.java b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/order/OrderManagement.java
new file mode 100644
index 00000000..a20bd0aa
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/order/OrderManagement.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example.order;
+
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+import java.util.UUID;
+
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author Oliver Drotbohm
+ */
+@Service
+@RequiredArgsConstructor
+public class OrderManagement {
+
+ private final @NonNull ApplicationEventPublisher events;
+
+ @Transactional
+ public void complete() {
+ events.publishEvent(new OrderCompleted(UUID.randomUUID()));
+ }
+}
diff --git a/spring-modulith-example/src/main/java/example/order/package-info.java b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/order/package-info.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/order/package-info.java
rename to spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/java/example/order/package-info.java
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/resources/application.properties b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/resources/application.properties
new file mode 100644
index 00000000..f4080270
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+spring.jpa.show-sql=true
+spring.modulith.events.jdbc.schema-initialization.enabled=true
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/resources/logback.xml b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/resources/logback.xml
new file mode 100644
index 00000000..b7f9d1d8
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/main/resources/logback.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/test/java/example/ApplicationIntegrationTests.java b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/test/java/example/ApplicationIntegrationTests.java
new file mode 100644
index 00000000..d6f741e4
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/test/java/example/ApplicationIntegrationTests.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example;
+
+import example.inventory.InventoryUpdated;
+import example.order.OrderManagement;
+
+import java.util.Collection;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
+import org.springframework.context.annotation.Bean;
+import org.springframework.modulith.events.EventPublicationRegistry;
+import org.springframework.modulith.test.EnableScenarios;
+import org.springframework.modulith.test.Scenario;
+import org.testcontainers.containers.PostgreSQLContainer;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+/**
+ * Integration test for the overall application.
+ *
+ * @author Oliver Drotbohm
+ */
+@SpringBootTest
+@EnableScenarios
+@Testcontainers(disabledWithoutDocker = true)
+class ApplicationIntegrationTests {
+
+ @Autowired OrderManagement orders;
+ @Autowired EventPublicationRegistry registry;
+
+ @TestConfiguration
+ static class Infrastructure {
+
+ @ServiceConnection
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ PostgreSQLContainer> database() {
+ return new PostgreSQLContainer<>("postgres:15.2");
+ }
+ }
+
+ @Test
+ void bootstrapsApplication(Scenario scenario) throws Exception {
+
+ scenario.stimulate(() -> orders.complete())
+ .andWaitForStateChange(() -> registry.findIncompletePublications(), Collection::isEmpty)
+ .andExpect(InventoryUpdated.class)
+ .toArrive();
+ }
+}
diff --git a/spring-modulith-example/src/test/java/example/ModularityTests.java b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/test/java/example/ModularityTests.java
similarity index 100%
rename from spring-modulith-example/src/test/java/example/ModularityTests.java
rename to spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/test/java/example/ModularityTests.java
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/test/resources/logback.xml b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/test/resources/logback.xml
new file mode 100644
index 00000000..e2eb0089
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-jdbc/src/test/resources/logback.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/pom.xml b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/pom.xml
new file mode 100644
index 00000000..8eb7fe3f
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/pom.xml
@@ -0,0 +1,56 @@
+
+
+ 4.0.0
+
+
+ org.springframework.experimental
+ spring-modulith-examples
+ 0.6.0-SNAPSHOT
+ ../pom.xml
+
+
+ spring-modulith-examples-epr-mongodb
+ Spring Modulith - Examples - EPR MongoDB Example
+
+
+
+
+ org.springframework.experimental
+ spring-modulith-starter-mongodb
+
+
+
+
+
+ org.jmolecules
+ jmolecules-events
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+
+ org.testcontainers
+ junit-jupiter
+ test
+
+
+
+ org.testcontainers
+ mongodb
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-testcontainers
+ test
+
+
+
+
+
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/asciidoc/index.adoc b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/asciidoc/index.adoc
new file mode 100644
index 00000000..bab583d6
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/asciidoc/index.adoc
@@ -0,0 +1,16 @@
+= Spring Modulith Example Documentation
+:modulith-docs: ../../../target/spring-modulith-docs
+
+== Overview
+
+plantuml::{modulith-docs}/components.puml[format="svg"]
+
+== Inventory
+
+plantuml::{modulith-docs}/module-inventory.puml[format="svg"]
+include::{modulith-docs}/module-inventory.adoc[]
+
+== Orders
+
+plantuml::{modulith-docs}/module-order.puml[format="svg"]
+include::{modulith-docs}/module-order.adoc[]
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/Application.java b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/Application.java
new file mode 100644
index 00000000..648c04dc
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/Application.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Spring Modulith example application
+ *
+ * @author Oliver Drotbohm
+ */
+@SpringBootApplication
+public class Application {
+
+ public static void main(String... args) {}
+}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/inventory/InventoryManagement.java b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/inventory/InventoryManagement.java
new file mode 100644
index 00000000..52d96746
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/inventory/InventoryManagement.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example.inventory;
+
+import example.order.OrderCompleted;
+import lombok.RequiredArgsConstructor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.modulith.ApplicationModuleListener;
+import org.springframework.stereotype.Service;
+
+/**
+ * A Spring {@link Service} exposed by the inventory module.
+ *
+ * @author Oliver Drotbohm
+ */
+@Service
+@RequiredArgsConstructor
+class InventoryManagement {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InventoryManagement.class);
+
+ private final ApplicationEventPublisher events;
+
+ @ApplicationModuleListener
+ void on(OrderCompleted event) throws InterruptedException {
+
+ var orderId = event.orderId();
+
+ LOG.info("Received order completion for {}.", orderId);
+
+ // Simulate busy work
+ Thread.sleep(1000);
+ events.publishEvent(new InventoryUpdated(orderId));
+
+ LOG.info("Finished order completion for {}.", orderId);
+ }
+}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/inventory/InventoryUpdated.java b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/inventory/InventoryUpdated.java
new file mode 100644
index 00000000..b4c7c29c
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/inventory/InventoryUpdated.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example.inventory;
+
+import java.util.UUID;
+
+/**
+ * @author Oliver Drotbohm
+ */
+public record InventoryUpdated(UUID orderId) {}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/inventory/package-info.java b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/inventory/package-info.java
new file mode 100644
index 00000000..bf3e64df
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/inventory/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * The logical application module inventory implemented as a single-package module. Allows to hide application
+ * components inside the module by using package scoped types.
+ *
+ * @see example.inventory.InventoryInternal
+ */
+@org.springframework.lang.NonNullApi
+package example.inventory;
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/order/OrderCompleted.java b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/order/OrderCompleted.java
new file mode 100644
index 00000000..5aa24d46
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/order/OrderCompleted.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example.order;
+
+import java.util.UUID;
+
+import org.jmolecules.event.types.DomainEvent;
+
+/**
+ * @author Oliver Drotbohm
+ */
+public record OrderCompleted(UUID orderId) implements DomainEvent {}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/order/OrderManagement.java b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/order/OrderManagement.java
new file mode 100644
index 00000000..a20bd0aa
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/order/OrderManagement.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example.order;
+
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+import java.util.UUID;
+
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author Oliver Drotbohm
+ */
+@Service
+@RequiredArgsConstructor
+public class OrderManagement {
+
+ private final @NonNull ApplicationEventPublisher events;
+
+ @Transactional
+ public void complete() {
+ events.publishEvent(new OrderCompleted(UUID.randomUUID()));
+ }
+}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/order/package-info.java b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/order/package-info.java
new file mode 100644
index 00000000..376d865b
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/main/java/example/order/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * The logical application module order implemented as a multi-package module. Internal components located in nested
+ * packages are prevented from being accessed by the {@link org.springframework.modulith.core.ApplicationModules} type.
+ *
+ * @see example.ModularityTests
+ */
+@org.springframework.lang.NonNullApi
+package example.order;
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/test/java/example/ApplicationIntegrationTests.java b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/test/java/example/ApplicationIntegrationTests.java
new file mode 100644
index 00000000..1410e937
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/test/java/example/ApplicationIntegrationTests.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example;
+
+import example.inventory.InventoryUpdated;
+import example.order.OrderManagement;
+
+import java.util.Collection;
+
+import org.bson.UuidRepresentation;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
+import org.springframework.context.annotation.Bean;
+import org.springframework.modulith.events.EventPublicationRegistry;
+import org.springframework.modulith.test.EnableScenarios;
+import org.springframework.modulith.test.Scenario;
+import org.testcontainers.containers.MongoDBContainer;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+/**
+ * Integration test for the overall application.
+ *
+ * @author Oliver Drotbohm
+ */
+@SpringBootTest
+@EnableScenarios
+@Testcontainers(disabledWithoutDocker = true)
+class ApplicationIntegrationTests {
+
+ @TestConfiguration
+ static class MongoDbInfrastructureConfiguration {
+
+ @ServiceConnection
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ MongoDBContainer mongoDBContainer() {
+ return new MongoDBContainer("mongo:6.0.3");
+ }
+
+ @Bean
+ public MongoClient mongoClient(MongoDBContainer container) {
+
+ var settings = MongoClientSettings.builder()
+ .uuidRepresentation(UuidRepresentation.STANDARD)
+ .applyConnectionString(new ConnectionString(container.getReplicaSetUrl()))
+ .build();
+
+ return MongoClients.create(settings);
+ }
+ }
+
+ @Autowired OrderManagement orders;
+ @Autowired EventPublicationRegistry registry;
+
+ @Test
+ void bootstrapsApplication(Scenario scenario) throws Exception {
+
+ scenario.stimulate(() -> orders.complete())
+ .andWaitForStateChange(() -> registry.findIncompletePublications(), Collection::isEmpty)
+ .andExpect(InventoryUpdated.class)
+ .toArrive();
+ }
+}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/test/java/example/ModularityTests.java b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/test/java/example/ModularityTests.java
new file mode 100644
index 00000000..e8d261f9
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/test/java/example/ModularityTests.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.modulith.core.ApplicationModules;
+import org.springframework.modulith.docs.Documenter;
+
+/**
+ * Tests to verify the modular structure and generate documentation for the modules.
+ *
+ * @author Oliver Drotbohm
+ */
+class ModularityTests {
+
+ ApplicationModules modules = ApplicationModules.of(Application.class);
+
+ @Test
+ void verifiesModularStructure() {
+ modules.verify();
+ }
+
+ @Test
+ void createModuleDocumentation() {
+ new Documenter(modules).writeDocumentation();
+ }
+}
diff --git a/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/test/resources/logback.xml b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/test/resources/logback.xml
new file mode 100644
index 00000000..6dfe47de
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-epr-mongodb/src/test/resources/logback.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-modulith-examples/spring-modulith-examples-full/pom.xml b/spring-modulith-examples/spring-modulith-examples-full/pom.xml
new file mode 100644
index 00000000..10aeaad6
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-full/pom.xml
@@ -0,0 +1,69 @@
+
+
+ 4.0.0
+
+
+ org.springframework.experimental
+ spring-modulith-examples
+ 0.6.0-SNAPSHOT
+ ../pom.xml
+
+
+ spring-modulith-examples-full
+ Spring Modulith - Examples - Full Example
+
+
+
+
+ org.springframework.experimental
+ spring-modulith-starter-jpa
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+ org.springframework.experimental
+ spring-modulith-actuator
+
+
+
+
+
+ org.jmolecules.integrations
+ jmolecules-starter-ddd
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+
+
diff --git a/spring-modulith-examples/spring-modulith-examples-full/src/main/asciidoc/index.adoc b/spring-modulith-examples/spring-modulith-examples-full/src/main/asciidoc/index.adoc
new file mode 100644
index 00000000..bab583d6
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-full/src/main/asciidoc/index.adoc
@@ -0,0 +1,16 @@
+= Spring Modulith Example Documentation
+:modulith-docs: ../../../target/spring-modulith-docs
+
+== Overview
+
+plantuml::{modulith-docs}/components.puml[format="svg"]
+
+== Inventory
+
+plantuml::{modulith-docs}/module-inventory.puml[format="svg"]
+include::{modulith-docs}/module-inventory.adoc[]
+
+== Orders
+
+plantuml::{modulith-docs}/module-order.puml[format="svg"]
+include::{modulith-docs}/module-order.adoc[]
diff --git a/spring-modulith-example/src/main/java/example/Application.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/Application.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/Application.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/Application.java
diff --git a/spring-modulith-example/src/main/java/example/inventory/InventoryInternal.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/inventory/InventoryInternal.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/inventory/InventoryInternal.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/inventory/InventoryInternal.java
diff --git a/spring-modulith-example/src/main/java/example/inventory/InventoryManagement.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/inventory/InventoryManagement.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/inventory/InventoryManagement.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/inventory/InventoryManagement.java
diff --git a/spring-modulith-example/src/main/java/example/inventory/InventorySettings.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/inventory/InventorySettings.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/inventory/InventorySettings.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/inventory/InventorySettings.java
diff --git a/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/inventory/package-info.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/inventory/package-info.java
new file mode 100644
index 00000000..bf3e64df
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/inventory/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * The logical application module inventory implemented as a single-package module. Allows to hide application
+ * components inside the module by using package scoped types.
+ *
+ * @see example.inventory.InventoryInternal
+ */
+@org.springframework.lang.NonNullApi
+package example.inventory;
diff --git a/spring-modulith-example/src/main/java/example/order/Order.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/Order.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/order/Order.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/Order.java
diff --git a/spring-modulith-example/src/main/java/example/order/OrderCompleted.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/OrderCompleted.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/order/OrderCompleted.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/OrderCompleted.java
diff --git a/spring-modulith-example/src/main/java/example/order/OrderManagement.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/OrderManagement.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/order/OrderManagement.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/OrderManagement.java
diff --git a/spring-modulith-example/src/main/java/example/order/internal/OrderInternal.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/internal/OrderInternal.java
similarity index 100%
rename from spring-modulith-example/src/main/java/example/order/internal/OrderInternal.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/internal/OrderInternal.java
diff --git a/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/package-info.java b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/package-info.java
new file mode 100644
index 00000000..376d865b
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-full/src/main/java/example/order/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * The logical application module order implemented as a multi-package module. Internal components located in nested
+ * packages are prevented from being accessed by the {@link org.springframework.modulith.core.ApplicationModules} type.
+ *
+ * @see example.ModularityTests
+ */
+@org.springframework.lang.NonNullApi
+package example.order;
diff --git a/spring-modulith-example/src/main/resources/application.properties b/spring-modulith-examples/spring-modulith-examples-full/src/main/resources/application.properties
similarity index 100%
rename from spring-modulith-example/src/main/resources/application.properties
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/resources/application.properties
diff --git a/spring-modulith-example/src/main/resources/logback.xml b/spring-modulith-examples/spring-modulith-examples-full/src/main/resources/logback.xml
similarity index 100%
rename from spring-modulith-example/src/main/resources/logback.xml
rename to spring-modulith-examples/spring-modulith-examples-full/src/main/resources/logback.xml
diff --git a/spring-modulith-example/src/test/java/example/ApplicationIntegrationTests.java b/spring-modulith-examples/spring-modulith-examples-full/src/test/java/example/ApplicationIntegrationTests.java
similarity index 100%
rename from spring-modulith-example/src/test/java/example/ApplicationIntegrationTests.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/test/java/example/ApplicationIntegrationTests.java
diff --git a/spring-modulith-examples/spring-modulith-examples-full/src/test/java/example/ModularityTests.java b/spring-modulith-examples/spring-modulith-examples-full/src/test/java/example/ModularityTests.java
new file mode 100644
index 00000000..e8d261f9
--- /dev/null
+++ b/spring-modulith-examples/spring-modulith-examples-full/src/test/java/example/ModularityTests.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.modulith.core.ApplicationModules;
+import org.springframework.modulith.docs.Documenter;
+
+/**
+ * Tests to verify the modular structure and generate documentation for the modules.
+ *
+ * @author Oliver Drotbohm
+ */
+class ModularityTests {
+
+ ApplicationModules modules = ApplicationModules.of(Application.class);
+
+ @Test
+ void verifiesModularStructure() {
+ modules.verify();
+ }
+
+ @Test
+ void createModuleDocumentation() {
+ new Documenter(modules).writeDocumentation();
+ }
+}
diff --git a/spring-modulith-example/src/test/java/example/order/EventPublicationRegistryTests.java b/spring-modulith-examples/spring-modulith-examples-full/src/test/java/example/order/EventPublicationRegistryTests.java
similarity index 100%
rename from spring-modulith-example/src/test/java/example/order/EventPublicationRegistryTests.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/test/java/example/order/EventPublicationRegistryTests.java
diff --git a/spring-modulith-example/src/test/java/example/order/OrderIntegrationTests.java b/spring-modulith-examples/spring-modulith-examples-full/src/test/java/example/order/OrderIntegrationTests.java
similarity index 100%
rename from spring-modulith-example/src/test/java/example/order/OrderIntegrationTests.java
rename to spring-modulith-examples/spring-modulith-examples-full/src/test/java/example/order/OrderIntegrationTests.java