This is an automated email from the ASF dual-hosted git repository.

shushengzhou pushed a commit to branch build/graalvm-native-support
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git

commit b412308acbe5b449031d7b35a840c37f0207c176
Author: a-little-fool <[email protected]>
AuthorDate: Mon Feb 16 09:52:10 2026 +0800

    build(graalvm): add basic native image configuration
    
    Introduces necessary plugins and config files for GraalVM.
    Pending: Local verification and CI integration.
---
 .../alert/controller/AlertReportController.java    | 15 +++---
 .../impl/FeiShuAppAlertNotifyHandlerImpl.java      |  7 ---
 .../notice/impl/SlackAlertNotifyHandlerImpl.java   |  4 --
 .../impl/WeComAppAlertNotifyHandlerImpl.java       |  5 --
 .../nativex/HertzbeatRuntimeHintsRegistrar.java    | 54 ++++++++++++++++++++++
 hertzbeat-startup/pom.xml                          | 54 ++++++++++++++++++++++
 .../src/main/resources/application.yml             |  1 +
 web-app/package.json                               |  2 +-
 8 files changed, 119 insertions(+), 23 deletions(-)

diff --git 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/controller/AlertReportController.java
 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/controller/AlertReportController.java
index cf81040abb..69e09c549d 100644
--- 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/controller/AlertReportController.java
+++ 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/controller/AlertReportController.java
@@ -19,6 +19,8 @@ package org.apache.hertzbeat.alert.controller;
 
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
+
+import java.math.BigInteger;
 import java.util.List;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.alert.service.ExternAlertService;
@@ -39,7 +41,7 @@ import org.springframework.web.bind.annotation.RestController;
 @RestController
 @Slf4j
 public class AlertReportController {
-    
+
     private final List<ExternAlertService> externAlertServiceList;
 
     public AlertReportController(List<ExternAlertService> 
externAlertServiceList) {
@@ -48,7 +50,7 @@ public class AlertReportController {
 
     @PostMapping("/api/alerts/report/{source}")
     @Operation(summary = "Api for receive external alarm information")
-    public ResponseEntity<Message<Void>> 
receiveExternAlert(@PathVariable(value = "source") String source, 
+    public ResponseEntity<Message<Void>> 
receiveExternAlert(@PathVariable(value = "source") String source,
                                                             @RequestBody 
String content) {
         log.info("Receive extern alert from source: {}, content: {}", source, 
content);
         if (!StringUtils.hasText(source)) {
@@ -58,10 +60,10 @@ public class AlertReportController {
             if (externAlertService.supportSource().equals(source)) {
                 try {
                     externAlertService.addExternAlert(content);
-                    return ResponseEntity.ok(Message.success("Add extern alert 
success"));      
+                    return ResponseEntity.ok(Message.success("Add extern alert 
success"));
                 } catch (Exception e) {
                     return ResponseEntity.status(HttpStatus.BAD_REQUEST)
-                            .body(Message.fail(CommonConstants.FAIL_CODE, 
+                            .body(Message.fail(CommonConstants.FAIL_CODE,
                                     "Add extern alert failed: " + 
e.getMessage()));
                 }
             }
@@ -80,16 +82,17 @@ public class AlertReportController {
         if (externAlertService != null) {
             try {
                 externAlertService.addExternAlert(content);
-                return ResponseEntity.ok(Message.success("Add extern alert 
success"));   
+                return ResponseEntity.ok(Message.success("Add extern alert 
success"));
             } catch (Exception e) {
                 return ResponseEntity.status(HttpStatus.BAD_REQUEST)
-                        .body(Message.fail(CommonConstants.FAIL_CODE, 
+                        .body(Message.fail(CommonConstants.FAIL_CODE,
                                 "Add extern alert failed: " + e.getMessage()));
             }
         }
         log.error("Not support default extern alert");
         return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                 .body(Message.success("Not support the default source alert"));
+        BigInteger
     }
 
     @PostMapping("/api/v2/alerts")
diff --git 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/FeiShuAppAlertNotifyHandlerImpl.java
 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/FeiShuAppAlertNotifyHandlerImpl.java
index 1c49c08af8..d53f53f58f 100644
--- 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/FeiShuAppAlertNotifyHandlerImpl.java
+++ 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/FeiShuAppAlertNotifyHandlerImpl.java
@@ -26,10 +26,8 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
-import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.hertzbeat.alert.AlerterProperties;
 import org.apache.hertzbeat.alert.notice.AlertNoticeException;
 import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
 import org.apache.hertzbeat.common.entity.alerter.NoticeReceiver;
@@ -41,7 +39,6 @@ import org.springframework.http.HttpMethod;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -54,7 +51,6 @@ import java.util.stream.Collectors;
  * FeiShu app alert notify impl
  */
 @Component
-@RequiredArgsConstructor
 @Slf4j
 public class FeiShuAppAlertNotifyHandlerImpl extends 
AbstractAlertNotifyHandlerImpl {
 
@@ -84,9 +80,6 @@ public class FeiShuAppAlertNotifyHandlerImpl extends 
AbstractAlertNotifyHandlerI
     private static final byte PART_RECEIVE_TYPE = 2;
     private static final byte ALL_RECEIVE_TYPE = 3;
 
-    private final RestTemplate restTemplate;
-    private final AlerterProperties alerterProperties;
-
     @Override
     public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, 
GroupAlert alert) throws AlertNoticeException {
         var appId = receiver.getAppId();
diff --git 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/SlackAlertNotifyHandlerImpl.java
 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/SlackAlertNotifyHandlerImpl.java
index 8f782076cd..6e1b350951 100644
--- 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/SlackAlertNotifyHandlerImpl.java
+++ 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/SlackAlertNotifyHandlerImpl.java
@@ -21,7 +21,6 @@ import java.net.URI;
 import java.util.Objects;
 import lombok.Builder;
 import lombok.Data;
-import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.alert.notice.AlertNoticeException;
 import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
@@ -32,17 +31,14 @@ import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
 
 /**
  * Send alarm information by Slack Webhook
  */
 @Component
-@RequiredArgsConstructor
 @Slf4j
 final class SlackAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl 
{
     private static final String SUCCESS = "ok";
-    private final RestTemplate restTemplate;
 
     @Override
     public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, 
GroupAlert alert) throws AlertNoticeException {
diff --git 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/WeComAppAlertNotifyHandlerImpl.java
 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/WeComAppAlertNotifyHandlerImpl.java
index 2bb671f7fc..f6f413b555 100644
--- 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/WeComAppAlertNotifyHandlerImpl.java
+++ 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/WeComAppAlertNotifyHandlerImpl.java
@@ -23,7 +23,6 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.alert.notice.AlertNoticeException;
 import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
@@ -34,13 +33,11 @@ import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
 
 /**
  * WeChat app alert notify impl
  */
 @Component
-@RequiredArgsConstructor
 @Slf4j
 public class WeComAppAlertNotifyHandlerImpl extends 
AbstractAlertNotifyHandlerImpl {
 
@@ -59,8 +56,6 @@ public class WeComAppAlertNotifyHandlerImpl extends 
AbstractAlertNotifyHandlerIm
      */
     private static final String DEFAULT_ALL = "@all";
 
-    private final RestTemplate restTemplate;
-
     @Override
     public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, 
GroupAlert alert) throws AlertNoticeException {
         String corpId = receiver.getCorpId();
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/nativex/HertzbeatRuntimeHintsRegistrar.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/nativex/HertzbeatRuntimeHintsRegistrar.java
index 44d9b3a6a3..1f8846667c 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/nativex/HertzbeatRuntimeHintsRegistrar.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/nativex/HertzbeatRuntimeHintsRegistrar.java
@@ -20,7 +20,14 @@
 package org.apache.hertzbeat.manager.nativex;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.Arrays;
 import java.util.Set;
+import org.apache.hertzbeat.common.entity.job.Configmap;
+import org.apache.hertzbeat.common.entity.job.Job;
+import org.apache.hertzbeat.common.entity.job.Metrics;
+import org.apache.hertzbeat.common.entity.manager.ParamDefine;
+import org.apache.hertzbeat.common.entity.plugin.PluginConfig;
 import org.apache.sshd.common.channel.ChannelListener;
 import org.apache.sshd.common.forward.PortForwardingEventListener;
 import org.apache.sshd.common.io.nio2.Nio2ServiceFactory;
@@ -42,10 +49,19 @@ import org.springframework.util.ClassUtils;
  */
 public class HertzbeatRuntimeHintsRegistrar implements RuntimeHintsRegistrar {
 
+    private static final MemberCategory[] YAML_MODEL_MEMBER_CATEGORIES = {
+            MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
+            MemberCategory.INVOKE_DECLARED_METHODS,
+            MemberCategory.DECLARED_FIELDS
+    };
+
     private static final String SshConstantsClassName = 
"org.apache.sshd.common.SshConstants";
+    private static final String JobProtocolPackageNamePrefix = 
"org.apache.hertzbeat.common.entity.job.protocol.";
 
     @Override
     public void registerHints(@NonNull RuntimeHints hints, ClassLoader 
classLoader) {
+        registerResourceHints(hints);
+        registerYamlModelHints(hints);
         // see: 
https://github.com/spring-cloud/spring-cloud-config/blob/main/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerRuntimeHints.java
         // TODO: move over to GraalVM reachability metadata
         if (ClassUtils.isPresent(SshConstantsClassName, classLoader)) {
@@ -61,6 +77,44 @@ public class HertzbeatRuntimeHintsRegistrar implements 
RuntimeHintsRegistrar {
         }
     }
 
+    private void registerResourceHints(RuntimeHints hints) {
+        hints.resources().registerPattern("application*.yml");
+        hints.resources().registerPattern("banner.txt");
+        hints.resources().registerPattern("sureness.yml");
+        hints.resources().registerPattern("logback-spring.xml");
+        hints.resources().registerPattern("db/migration/**");
+        hints.resources().registerPattern("define/*.yml");
+        hints.resources().registerPattern("define/*.yaml");
+        hints.resources().registerPattern("templates/**");
+        hints.resources().registerPattern("grafana/*.json");
+        hints.resources().registerPattern("dist/**");
+        
hints.resources().registerPattern("META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports");
+    }
+
+    private void registerYamlModelHints(RuntimeHints hints) {
+        registerTypeWithDeclaredMembers(hints, Job.class);
+        registerTypeWithDeclaredMembers(hints, Metrics.class);
+        registerTypeWithDeclaredMembers(hints, Metrics.Field.class);
+        registerTypeWithDeclaredMembers(hints, Configmap.class);
+        registerTypeWithDeclaredMembers(hints, ParamDefine.class);
+        registerTypeWithDeclaredMembers(hints, ParamDefine.Option.class);
+        registerTypeWithDeclaredMembers(hints, PluginConfig.class);
+
+        Arrays.stream(Metrics.class.getDeclaredFields())
+                .map(Field::getType)
+                .filter(this::isJobProtocolClass)
+                .forEach(type -> registerTypeWithDeclaredMembers(hints, type));
+    }
+
+    private boolean isJobProtocolClass(Class<?> type) {
+        return type.getName().startsWith(JobProtocolPackageNamePrefix);
+    }
+
+    private void registerTypeWithDeclaredMembers(RuntimeHints hints, Class<?> 
clazz) {
+        hints.reflection().registerType(clazz, hint -> 
hint.withMembers(YAML_MODEL_MEMBER_CATEGORIES));
+        registerConstructor(hints, clazz);
+    }
+
     private void registerConstructor(RuntimeHints hints, Class<?> clazz) {
         Constructor<?>[] declaredConstructors = 
clazz.getDeclaredConstructors();
         for (Constructor<?> declaredConstructor : declaredConstructors) {
diff --git a/hertzbeat-startup/pom.xml b/hertzbeat-startup/pom.xml
index f45a196a6b..e4782dfddb 100644
--- a/hertzbeat-startup/pom.xml
+++ b/hertzbeat-startup/pom.xml
@@ -201,6 +201,60 @@
     </build>
 
     <profiles>
+        <profile>
+            <id>native</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.springframework.boot</groupId>
+                        <artifactId>spring-boot-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>process-aot</id>
+                                <goals>
+                                    <goal>process-aot</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.graalvm.buildtools</groupId>
+                        <artifactId>native-maven-plugin</artifactId>
+                        <configuration>
+                            
<mainClass>org.apache.hertzbeat.startup.HertzBeatApplication</mainClass>
+                            <fallback>false</fallback>
+                            <verbose>true</verbose>
+                            <buildArgs>
+                                
<buildArg>-H:+ReportExceptionStackTraces</buildArg>
+                                
<buildArg>-H:TempDirectory=${project.build.directory}/native-temp</buildArg>
+                                
<buildArg>--initialize-at-build-time=org.apache.sshd.sftp.client.fs.SftpFileSystemProvider</buildArg>
+                                
<buildArg>--initialize-at-run-time=io.grpc.netty.shaded.io.netty.channel.epoll</buildArg>
+                                
<buildArg>--initialize-at-run-time=io.netty.channel.epoll</buildArg>
+                                
<buildArg>--initialize-at-run-time=io.grpc.netty.shaded.io.netty.channel.unix</buildArg>
+                                
<buildArg>--initialize-at-run-time=io.netty.channel.unix</buildArg>
+                            </buildArgs>
+                            <environment>
+                                
<TMPDIR>${project.build.directory}/native-temp</TMPDIR>
+                                
<TEMP>${project.build.directory}/native-temp</TEMP>
+                                
<TMP>${project.build.directory}/native-temp</TMP>
+                            </environment>
+                            <metadataRepository>
+                                <enabled>true</enabled>
+                            </metadataRepository>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>build-native</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>compile-no-fork</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
         <profile>
             <id>release</id>
             <build>
diff --git a/hertzbeat-startup/src/main/resources/application.yml 
b/hertzbeat-startup/src/main/resources/application.yml
index 85ff831d59..e58ae512ec 100644
--- a/hertzbeat-startup/src/main/resources/application.yml
+++ b/hertzbeat-startup/src/main/resources/application.yml
@@ -14,6 +14,7 @@
 # limitations under the License.
 server:
   port: 1157
+  address: 0.0.0.0
 spring:
   application:
     name: ${HOSTNAME:@hertzbeat@}${PID}
diff --git a/web-app/package.json b/web-app/package.json
index d750e6bcb3..a1ea6ee727 100644
--- a/web-app/package.json
+++ b/web-app/package.json
@@ -20,7 +20,7 @@
   ],
   "scripts": {
     "ng": "ng",
-    "start": "ng serve --proxy-config proxy.conf.json",
+    "start": "ng serve --proxy-config proxy.conf.json --host 0.0.0.0",
     "build": "npm run ng-high-memory build",
     "watch": "ng build --watch --configuration development",
     "test": "ng test",


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to