# 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.0.0 -DgroupId=io.sermant -Dversion=2.0.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.0.0
[INFO] Using property: package = io.sermant
Confirm properties configuration:
groupId: io.sermant
artifactId: first-plugin
version: 2.0.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: 2023-10-19T15: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.demo.template.Application")
, the matcher matchesio.demo.template.Application
class by class name.
@Override
public ClassMatcher getClassMatcher() {
return ClassMatcher.nameEquals("io.demo.template.Application");
}
Note:The above logic is implemented in the template code
io.demo.template.Application
logic is as follows:public class Application { public static void main(String[] args) { System.out.println("Good afternoon!"); } }
We will add System.out.println("Good morning!") and System.out.println("Good night!")` logic before and after 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("main")
,the matcher matches themain
method ofio.demo.template.Application
class by method name. - Define an interceptor for the 'main' method, add
System.out.println("Good morning!")
to thebefore
method , and addSystem.out.println("Good morning!")
logic to theafter
method,before
andafter
method will take effect before and after themain
method is executed.
@Override
public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
return new InterceptDeclarer[]{
InterceptDeclarer.build(MethodMatcher.nameEquals("main"), new 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
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.