This is the multi-page printable view of this section. Click here to print.
4.2 Module Access
1 - 4.2.1 Upgrade to Module from existing SpringBoot or SOFABoot
We can create Biz Module in three ways, and this article introduces the second one:
- Splitting a large application into multiple modules
- Transforming an existing application into a single module
- Directly creating a module using a scaffold
This article introduces how existing SpringBoot or SOFABoot applications can be cost-effectively upgraded to modules with the operational and validation steps. It requires only the addition of an ark packaging plugin + configuration for module slimming to enable a conventional application to be upgraded to a module application at the push of a button. Moreover, the same set of code branches can be used for independent startup as before, just like a regular SpringBoot application, as well as being capable of being deployed together with other applications as a module.
Prerequisites
- SpringBoot version >= 2.3.0 (for SpringBoot users)
- SOFABoot >= 3.9.0 or SOFABoot >= 4.0.0 (for SOFABoot users)
Access Steps
Step 1: Modify application.properties
# Need to define the application name
spring.application.name = ${Replace with actual module app name}
Step 2: Add Dependencies and Packaging Plugins for the Module
Note: The order of defining the sofa-ark plugin must be before the springboot packaging plugin;
<!-- Dependencies required for the module, mainly for inter-module communication -->
<dependencies>
<dependency>
<groupId>com.alipay.sofa.koupleless</groupId>
<artifactId>koupleless-app-starter</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<plugins>
<!-- Add the ark packaging plugin here -->
<plugin>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-ark-maven-plugin</artifactId>
<version>{sofa.ark.version}</version>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<skipArkExecutable>true</skipArkExecutable>
<outputDirectory>./target</outputDirectory>
<bizName>${Replace with module name}</bizName>
<webContextPath>${Module's custom web context path}</webContextPath>
<declaredMode>true</declaredMode>
</configuration>
</plugin>
<!-- Build a regular SpringBoot fat jar, used for independent deployment, can be removed if not needed -->
<plugin>
<!-- Original spring-boot packaging plugin -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
Step 3: Automate Module Slimming
You can leverage the automated slimming capability provided by the ark packaging plugin to slim down the Maven dependencies in your module application. This step is mandatory; otherwise, the resulting module JAR file will be very large, and startup may fail. Extended Reading: If the module does not optimize its dependenciesWhat will happen if SpringBoot framework is imported independently?
Step 4: Build the Module Jar Package
Execute mvn clean package -DskipTest, you can find the packaged ark biz jar in the target directory, or you can find the packaged regular springboot jar in the target/boot directory.
Tip:Full Middleware Compatibility List Supported in the Module。
Experiment: Verifying that the module can be started independently and deployed as a combined module
After adding the module packaging plugin (sofa-ark-maven-plugin) for packaging, only the ark-biz.jar build artifact will be added, which does not conflict with or affect the executable Jar built by the native spring-boot-maven-plugin. When deploying on the server, if you want to start independently, use the executable Jar built by the native spring-boot-maven-plugin as the build artifact; if you want to deploy as an ark module to the base, use the ark-biz.jar built by the sofa-ark-maven-plugin as the build artifact.
Verification of Deployment to the Base
- Start the base from the previous step (verification of independent startup).
- Initiate module deployment
curl --location --request POST 'localhost:1238/installBiz' \
--header 'Content-Type: application/json' \
--data '{
"bizName": "${Module Name}",
"bizVersion": "${Module Version}",
"bizUrl": "file:///path/to/ark/biz/jar/target/xx-xxxx-ark-biz.jar"
}'
If the following information is returned, it indicates that the module is installed successfully.
- View Current Module Information: Besides the base “base,” there is also a module named “dynamic-provider.”
- Uninstall the module
curl --location --request POST 'localhost:1238/uninstallBiz' \
--header 'Content-Type: application/json' \
--data '{
"bizName": "dynamic-provider",
"bizVersion": "0.0.1-SNAPSHOT"
}'
If the following information is returned, it indicates that the uninstallation was successful.
{
"code": "SUCCESS",
"data": {
"code": "SUCCESS",
"message": "Uninstall biz: dynamic-provider:0.0.1-SNAPSHOT success."
}
}
Verification of Independent Startup
After transforming a regular application into a module, it can still be started independently to verify some basic startup logic. Simply check the option to automatically add provided
scope to the classpath in the startup configuration, and then use the same startup method as for regular applications. Modules transformed through automatic slimming can also be started directly using the SpringBoot jar package located in the target/boot
directory. For more details, please refer to this link
2 - 4.2.2 Creating Modules Using Maven Archetype
We can create Biz Module in three ways, and this article introduces the second one:
- Splitting a large application into multiple modules
- Transforming an existing application into a single module
- Directly creating a module using a scaffold
- Transform ordinary code fragments into a module
It’s easy to creating a module from maven archetype, all you need to do is input the Maven groupId and artifactId for the archetype in IDEA.
<dependency>
<groupId>com.alipay.sofa.koupleless</groupId>
<artifactId>koupleless-common-module-archetype</artifactId>
<version>{koupleless.runtime.version}</version>
</dependency>
The module created from this archetype has already integrated the module packaging plugin and automatic slimming configuration. It can be directly packaged as a module and installed on the base, or started independently locally.
3 -
title: 4.2.3 Java Code Fragment as Module
date: 2024-01-25T10:28:32+08:00
description: Java Code Fragment as Module
weight: 310
Module creation has four methods, and this article introduces the fourth method:
- Split multiple modules from a large application
- Transform existing applications into a single module
- Create a module directly using scaffolding
- Transform ordinary code fragments into a module
This article introduces the operation and verification steps of upgrading Java code fragments to modules, and only requires adding an ark packaging plugin and configuring module slimming to achieve the one-click upgrade of Java code fragments into module applications. It enables the same set of code branches to be independently started like the original Java code fragments, and can also be deployed and started with other applications as a module.
Prerequisites
- JDK 8
- sofa.ark.version >= 2.2.14-SNAPSHOT
- koupleless.runtime.version >= 1.3.1-SNAPSHOT
- JDK 17/JDK 21
- sofa.ark.version >= 3.1.7-SNAPSHOT
- koupleless.runtime.version >= 2.1.6-SNAPSHOT
Integration Steps
Step 1: Add dependencies and packaging plugins required for the module
<properties>
<sofa.ark.version>${see-prerequisites-above}</sofa.ark.version>
<!-- Use different koupleless versions for different JDK versions, see: https://koupleless.io/docs/tutorials/module-development/runtime-compatibility-list/#%E6%A1%86%E6%9E%B6%E8%87%AA%E8%BA%AB%E5%90%84%E7%89%88%E6%9C%AC%E5%85%BC%E5%AE%B9%E6%80%A7%E5%85%B3%E7%B3%BB -->
<koupleless.runtime.version>${see-prerequisites-above}</koupleless.runtime.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alipay.sofa.koupleless</groupId>
<artifactId>koupleless-app-starter</artifactId>
<version>${koupleless.runtime.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<plugins>
<!-- Add the ark packaging plugin here -->
<plugin>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-ark-maven-plugin</artifactId>
<version>{sofa.ark.version}</version>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<skipArkExecutable>true</skipArkExecutable>
<outputDirectory>./target</outputDirectory>
<bizName>${replace-with-module-name}</bizName>
<declaredMode>true</declaredMode>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<classifier>lib</classifier>
<!-- Ensure other necessary configuration here -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Step 2: Add initialization logic
Add MainApplication.init()
in the code snippet to initialize the container.
public static void main(String[] args) {
// Initialize the module's instance container
MainApplication.init();
// ...
}
In terms of communication between modules and the base, the module registers instances in the container, and the base obtains module instances through SpringServiceFinder
. Using biz3 as an example:
- biz3 implements two instances that are based on the
AppService
interface:Biz3AppServiceImpl
andBiz3OtherAppServiceImpl
:
public class Biz3OtherAppServiceImpl implements AppService {
// Get the base bean
private AppService baseAppService = SpringServiceFinder.getBaseService(AppService.class);
@Override
public String getAppName() {
return "biz3OtherAppServiceImpl in the base: " + baseAppService.getAppName();
}
}
public class Biz3AppServiceImpl implements AppService {
// Get the base bean
private AppService baseAppService = SpringServiceFinder.getBaseService(AppService.class);
public String getAppName() {
return "biz3AppServiceImpl in the base: " + baseAppService.getAppName();
}
}
In which, the module obtains the base bean using: SpringServiceFinder.getBaseService(XXX.class)
, details can be found in: Module and Base Communication under ‘Module calls the base approach two: programming API SpringServiceFinder’.
- biz3 registers instances of these two classes in the container:
public static void main(String[] args) {
// Initialize the module's instance container
MainApplication.init();
// Register instances in the module container
MainApplication.register("biz3AppServiceImpl", new Biz3AppServiceImpl());
MainApplication.register("biz3OtherAppServiceImpl", new Biz3OtherAppServiceImpl());
}
- The base obtains instances from biz3:
@RestController
public class SampleController {
// Get specific instances from biz3 through annotation
@AutowiredFromBiz(bizName = "biz3", bizVersion = "0.0.1-SNAPSHOT", name = "biz3AppServiceImpl")
private AppService biz3AppServiceImpl;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String hello() {
System.out.println(biz3AppServiceImpl.getAppName());
// Get specific instances from biz3 through an API
AppService biz3OtherAppServiceImpl = SpringServiceFinder.getModuleService("biz3", "0.0.1-SNAPSHOT",
"biz3OtherAppServiceImpl", AppService.class);
System.out.println(biz3OtherAppServiceImpl.getAppName());
// Get all instances of AppService class from biz3 through an API
Map<String, AppService> appServiceMap = SpringServiceFinder.listModuleServices("biz3",
"0.0.1-SNAPSHOT", AppService.class);
for (AppService appService : appServiceMap.values()) {
System.out.println(appService.getAppName());
}
return "hello to ark master biz";
}
}
Where SpringBoot / SOFABoot base can obtain module instances through the @AutowiredFromBiz
annotation or SpringServiceFinder.getModuleService()
programming API, details can be found in: Module and Base Communication under ‘Base calls module’.
Step 3: Automate module slimming
Typically, module dependencies for code fragments are relatively simple. You can set the scope of dependencies in the module that are consistent with the base to “provided”, or use the automated slimming capability of the ark packaging plugin to automatically slim down the maven dependencies in the module. This step is mandatory, otherwise the module jar package will be very large and will result in startup errors.
Step 4: Build the module into a jar package
Execute mvn clean package -DskipTest
, and you can find the packaged ark biz jar in the target directory.
Experiment: Verify the module can be deployed and merged
- Start the base from the previous step (verify independent start-up steps)
- Initiate module deployment Refer to the sample module deployment of biz3: https://github.com/koupleless/samples/blob/main/springboot-samples/service/README-zh_CN.md