BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Spring Modulith 1.0 Gains Production-Readiness, IDE Support and Improved Testability

Spring Modulith 1.0 Gains Production-Readiness, IDE Support and Improved Testability

Spring Modulith 1.0 was promoted from its experimental status and became a fully supported Spring project. It structures Spring Boot 3 applications through modules and events using conventions and optional configuration. That module structure is now visible in IDEs like Spring Tool Suite and Visual Studio Code through actuators. The Event Publication Registry (EPR) persists event completion faster. And Integration Tests Scenarios ease testing events.

Spring Modulith modules exist because Java packages are not hierarchical. In the sample below, Java's default visibility already hides the example.inventory.SomethingInventoryInternal class from other packages. But the example.order.internal package must be public so example.order can access it. That makes it visible to all other packages.

└─  src/main/java
   ├─  example
   |  └─  Application.java
   ├─  example.inventory
   |  ├─  InventoryManagement.java
   |  └─  SomethingInventoryInternal.java
   ├─  example.order
   |  └─  OrderManagement.java
   └─  example.order.internal
      └─  SomethingOrderInternal.java

Spring Modulith modules neither use the Java Platform Module System (JPMS) nor generate code. Instead, each direct sub-package of the main package is simply a module by default. That's inventory and order in the example above. All public types in the package make up the module API. Crucially, Spring Modulith considers sub-packages internal to the module. That solves the problem of the public example.order.internal package described above.

Java still compiles when modules access other modules' internal packages. But the Spring Modulith test ApplicationModules.of(Application.class).verify() will fail then. Spring Modulith uses ArchUnit to detect such violations.

Spring Modulith encourages using Spring Framework application events for communication between modules. Spring Modulith enhances these events with the EPR, guaranteeing event delivery. So even if a module receiving the event crashes or the entire application does, the registry still delivers the event when the module or application runs again.

The EPR stores events with JPA, JDBC, and MongoDB. The latter one gained automatically configured transactions in this release. An application with Spring Modulith can use modules and events together or each feature alone.

Until now, asynchronous transaction event listeners required three annotations:

@Component
class InventoryManagement {

  @Async
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  @TransactionalEventListener
  void on(OrderCompleted event) { /*…*/ }
}

The new @ApplicationModuleListener shortcut in version 1.0 simplifies that:

@Component
class InventoryManagement {

  @ApplicationModuleListener
  void on(OrderCompleted event) { /*…*/ }
}

Testing asynchronous transactional code can be challenging. That's where the new Integration Test Scenarios help. They can be injected into Java tests and allow to define both the start of an event-driven test and its expected results. Furthermore, these scenarios can customize execution details and define additional event tests.

jMolecules defines annotations for architectures, such as Domain-Driven Design (@ValueObject or @Repository, for example) or Hexagonal Architecture (like @Port and @Adapter). Spring Modulith 1.0 detects jMolecules annotations and generates application documentation that groups classes by their annotated role, such as "Port" or "Adapter".

VMware announced the upcoming Spring Modulith 1.1 at Spring One in August 2023. This new version requires Spring Boot 3.2, which will be released on November 23, 2023. Version 1.1 will support additional databases for event persistence, such as Neo4J, to better align with Spring Data. And it can automatically send events to external destinations. That's helpful when at least some of the events are of interest to other applications. Version 1.1 will support Kafka, AMQP, and potentially Redis as external event destinations.

Oliver Drotbohm, Staff 2 engineer at VMware and the driving force behind Spring Modulith, spoke to InfoQ about Spring Modulith.

InfoQ: Spring Modulith has been out for ten months. How has the feedback been so far?

Oliver Drotbohm: The feedback at conferences and in online communities has been overwhelmingly positive. The primary aspect that made folks slightly hesitant was the fact that the project was considered experimental until its release a few days ago. We're looking forward to how the community will adopt it with that impediment removed.

InfoQ: How do you define success for Spring Modulith? And how do you measure it?

Drotbohm: As with all Spring projects, we are monitoring the Maven Central download numbers, of course, because those are skewed in either direction. Still, the trends in the number's development are usually a good indicator of the usage growth rate of an individual project. We also have numbers from start.spring.io. Given that Spring Modulith's primary target is new applications, those will hopefully give us a good impression as well. Other than that, GitHub stars, definitely as well.

InfoQ: Spring Tool Suite and VS Code can read the module structure. What are your plans for also supporting IntelliJ and Eclipse?

Drotbohm: Eclipse is supported via the STS plugins. For IDEA, we're in touch with the development team, and they're currently looking into it.

InfoQ: Spring Modulith currently has two core abstractions – modules and events. What other abstractions do you envision in future versions – if any?

Drotbohm: The two abstractions actually serve the two fundamental activities in software architecture as described by Neil Ford and Mark Richards in "Software Architecture — The Hard Parts": "pulling things apart," i.e., defining an application's functional decomposition, and "putting them back together," by defining a programming model for the decomposed individual parts to interact eventually. The application modules' concept helps to implement functional structure within a code base, including means to make sure that things that are supposed to stay apart actually do. The event-based application integration programming model we recommend allows those modules to still interact in an eventually consistent way.

We are currently primarily looking for these two parts to evolve, find out how the community will use them, and how we can react to make them even more useful. The event externalization mechanism currently scheduled for 1.1 M1 reflects that.

InfoQ: In your estimation, what percentage of Spring Modulith applications use modules, and what percentage uses events?

Drotbohm: We'll have to see what the download numbers for the individual Spring Modulith artifacts will tell. The stats during the experimental phase show a 90/10 split for modules (including the module integration test support) versus events.

About the Author

Rate this Article

Adoption
Style

BT