# Create Your First Plugin
This article is for guidance on how to develop your first plugin locally.
# Development Environment
- HuaweiJDK 1.8 (opens new window) / OpenJDK 1.8 (opens new window) / OracleJDK 1.8 (opens new window)
- Apache Maven 3 (opens new window)
# Create the Project Based on the Archetype Template
# Build Project
Execute the following Maven commands locally:
$ mvn archetype:generate -DarchetypeGroupId=io.sermant -DarchetypeArtifactId=sermant-template-archetype -DarchetypeVersion=2.1.0 -DgroupId=io.sermant -Dversion=2.1.0 -Dpackage=io.sermant -DartifactId=first-plugin
After executing the above command, press Enter for confirmation when the following log is displayed:
[INFO] Using property: groupId = io.sermant
[INFO] Using property: artifactId = first-plugin
[INFO] Using property: version = 2.1.0
[INFO] Using property: package = io.sermant
Confirm properties configuration:
groupId: io.sermant
artifactId: first-plugin
version: 2.1.0
package: io.sermant
Y: :
If the following success log appears, the project is successfully created using Archetype template:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.409 s
[INFO] Finished at: 2024-12-01T15:10:05+08:00
[INFO] ------------------------------------------------------------------------
# Project Structure
The template project directory generated based on Archetype is as follows:
.
├── application
├── config
└── template
├── config
├── template-plugin
└── template-service
application
:Test application module. This module is used to test whether the plug-ins defined in the template can take effect and can be cleared when the project is formally developed.
config
:Configuration directory for Sermant.
template
:template plugin module, plugin are developed here.
template\template-plugin
:The main module of the template plugin, refering to The main module of the plugin.
template\template-service
:The service module of template plugin, refering to The service module of plugin.
# Develop Plugin
First find the io.sermant.template.TemplateDeclarer
class of template project template\template-plugin
, there we can declare the class we expect to enhance, specify the methods in that class we expect to enhance, and define enhancement logic for it.
# Declares the Class to Be Enhanced
The getClassMatcher()
method of io.sermant.template.TemplateDeclarer
class need to be implement the following logic to enhance the class:
- Define Class matcher
ClassMatcher.nameEquals("io.sermant.demo.template.Application")
, the matcher matchesio.sermant.demo.template.Application
class by class name.
@Override
public ClassMatcher getClassMatcher() {
return ClassMatcher.nameEquals("io.sermant.demo.template.Application");
}
Note:The above logic is implemented in the template code
io.sermant.demo.template.Application
logic is as follows:@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); greeting(); } private static void greeting() { System.out.println("Good afternoon!"); SimulateServer.handleRequest(new HashMap<>()); } }
We will add
System.out.println("Good morning!")
andSystem.out.println("Good night!")
logic before and aftergreeting
method in this plugin.
# Declare the Methods That Need to Be Enhanced
After you specify the class that you want to enhance, you need to specify the method in that class that you want to enhance and define the enhancement logic for that method, the above steps require the following logic to be added to the getInterceptDeclarers(ClassLoader classLoader)
method in the io.sermant.template.TemplateDeclarer
class:
- Define Method matcher
MethodMatcher.nameEquals("greeting")
,the matcher matches thegreeting
method ofio.sermant.demo.template.Application
class by method name.
@Override
public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
return new InterceptDeclarer[]{
InterceptDeclarer.build(MethodMatcher.nameEquals("greeting"), new TemplateInterceptor())
};
}
- Define an interceptor for the
greeting
method, adding the logicSystem.out.println("Good morning!")
in thebefore
method ofio.sermant.template.TemplateInterceptor
andSystem.out.println("Good night!")
in theafter
method. Thebefore
method andafter
method will take effect before and after the execution of thegreeting
method, respectively.
public class TemplateInterceptor implements Interceptor {
@Override
public ExecuteContext before(ExecuteContext context) throws Exception {
System.out.println("Good morning!");
return context;
}
@Override
public ExecuteContext after(ExecuteContext context) throws Exception {
System.out.println("Good night!");
return context;
}
@Override
public ExecuteContext onThrow(ExecuteContext context) throws Exception {
return context;
}
}
Note:The above logic is implemented in the template code
# Add SPI Configuration That Enhances the Declaration
At the end of developing the plugin, don't forget to add the SPI configuration that enhances the declaration, add the META-INF/services
directory to resources
directory under template\template-plugin
in your project, and create SPI file named io.sermant.core.plugin.agent.declarer.PluginDeclarer
, then add the class name of the bytecode enhanced declaration class to it:
io.sermant.template.TemplateDeclarer
# Packaged Build
Execute mvn package under the generated project root directory , the build product directory is generated under the root directory of the build project:
.
├── agent
│ ├── Application.jar
│ ├── common
│ ├── config
│ ├── core
│ ├── god
│ ├── implement
│ ├── pluginPackage
│ │ └── template
│ └── sermant-agent.jar
Application.jar
is an executable package for testing applications,other directory structures refer to Product directory description
Note:The template uses Maven's
maven-dependency-plugin:copy
plug-in to pull the necessary core components of Sermant from the maven central repository into the local build directory, eliminating the need for developers to care about the dependencies and configurations required to start Sermant.The use of
maven-dependency-plugin:copy
plugin please referes to Maven official documentd maven-dependency-plugin:copy (opens new window)
Execute cd agent/
in the project root directory , perform the following steps in it:
- Run the following command to run the test application independently java -jar Application.jar
$ java -jar Application.jar
Good afternoon!
- Run the test application with Sermant and execute the following command java -javaagent:sermant-agent.jar -jar Application.jar
[xxxx-xx-xxTxx:xx:xx.xxx] [INFO] Loading god library into BootstrapClassLoader.
[xxxx-xx-xxTxx:xx:xx.xxx] [INFO] Building argument map by agent arguments.
[xxxx-xx-xxTxx:xx:xx.xxx] [INFO] Loading core library into SermantClassLoader.
[xxxx-xx-xxTxx:xx:xx.xxx] [INFO] Loading sermant agent, artifact is: default
[xxxx-xx-xxTxx:xx:xx.xxx] [INFO] Load sermant done, artifact is: default
************Omit Spring Boot application startup logs************
Good morning!
Good afternoon!
Good night!
As you can see, the execution logic defined in the plugin has been enhanced into the test application, and now that your first plugin has been developed successfully, let's move on to further development of the Sermant plugin.