-
Notifications
You must be signed in to change notification settings - Fork 61
Dynamic Loading
The dynamic loading mechanism of the business package can download and install the application plug-ins in the cloud market into the current container in some scenarios. Cloud market example:
This example mainly demonstrates how to dynamically load a business package based on Lattice, but does not include the construction of the cloud market itself.
With this sample, you can learn:
- Dynamic loading example of business plug-in package
- The extension mechanism of custom ClassLoader
- An Integrated Developer Environment (IDE). Popular choices include IntelliJ IDEA, Spring Tools, Visual Studio Code, or Eclipse, and many more.
- A Java™ Development Kit (JDK). We recommend BellSoft Liberica JDK version 8 or version 11.
<dependency>
<groupId>org.hiforce.lattice</groupId>
<artifactId>lattice-model</artifactId>
<version>1.0.12</version>
</dependency>
<dependency>
<groupId>org.hiforce.lattice</groupId>
<artifactId>lattice-runtime</artifactId>
<version>1.0.12</version>
</dependency>
<dependency>
<groupId>org.hiforce.lattice</groupId>
<artifactId>lattice-dynamic-loading</artifactId>
<version>1.0.12</version>
</dependency>
In lattice-sample, you can refer to the demo of lattice-dynamic-load-apps, the configuration Lattice plugin loading directory is defined, in application.properties, as follows:
lattice.plugin.dirs=/Users/rocky/code/plugins
Then we start the Starter org.hiforce.lattice.dynamic.LatticeDynamicStarter. In your browser, open http://localhost:8080/business/install/1 and you will see the following input:
Next, we continue to enter http://localhost:8080/business/install/2 , we can see the following results:
It can be seen that the dynamic loading of the business package has been replaced with a new version. The corresponding Controller code is as follows:
@RequestMapping("/business/install/1")
public String installBusinessPlugin_1() {
clear();
String urlStr = "/apps/lattice-business-cloth-1.0.0-SNAPSHOT.jar";
URL url = DynamicLoadTestController.class.getResource(urlStr);
if (null != url) {
File file = new File(url.getPath());
LatticeDynamic.getInstance().installPlugin(new PluginFileInfo(file));
}
return invokeBusinessPlugin();
}
@RequestMapping("/business/install/2")
public String installBusinessPlugin_2() {
clear();
String urlStr = "/apps/lattice-business-cloth-1.0.1-SNAPSHOT.jar";
URL url = DynamicLoadTestController.class.getResource(urlStr);
if (null != url) {
File file = new File(url.getPath());
LatticeDynamic.getInstance().installPlugin(new PluginFileInfo(file));
}
return invokeBusinessPlugin();
}
In the Lattice framework, the SPI of the custom ClassLoader is provided, which is defined as follows:
public interface CustomClassLoaderSpi {
ClassLoader getCustomClassLoader();
}
In this example, I provide a very simple loading scheme based on URLClassLoader in the framework in Lattice. In lattice-dynamic-loading, LatticeDynamicClassLoaderBuilder is defined, which can realize the loading of plug-in packages in the specified directory, as follows:
@AutoService(CustomClassLoaderSpi.class)
public class LatticeDynamicClassLoaderBuilder implements CustomClassLoaderSpi {
@Override
public ClassLoader getCustomClassLoader() {
String[] dirs = LatticeDynamicProperties.getInstance().getPluginDirs();
List<URL> urls = Lists.newArrayList();
for (String dir : dirs) {
urls.addAll(buildJarURLList(dir));
}
URL[] urlArrays = urls.toArray(new URL[0]);
return new URLClassLoader(urlArrays, LatticeDynamicClassLoaderBuilder.class.getClassLoader());
}
private List<URL> buildJarURLList(String dirStr) {
List<URL> urls = Lists.newArrayList();
try {
File dir = new File(dirStr);
if (!dir.exists() || !dir.isDirectory()) {
return Lists.newArrayList();
}
File[] jars = dir.listFiles(pathname -> pathname.getPath().endsWith(".jar"));
if (null == jars) {
return urls;
}
for (File file : jars) {
urls.add(new URL("file:" + file.getPath()));
}
return urls;
} catch (Exception ex) {
return Lists.newArrayList();
}
}
}
Lattice framework users can write more complex plugin loading schemes based on this mechanism. for example:
- It can be further enhanced to isolate the loading mechanism for different business identities
- Business plugins can be packaged into flat-jar, and each business can even introduce other third-party packages by itself
These, will not be available in the official Lattice framework.
This sample code: https://github.com/hiforce/lattice-sample/tree/main/lattice-dynamic-load-apps
Thanks..
Getting Started
Key Features
- Business Overlay Product
- Register Business Configuration
- Load Local Configuration
- Reduce Strategy
- UseCase Precipitation and Reuse
- RPC Invoke Extension
- Dynamic Loading
Key Concepts
Stories