leizhiyuan commented on PR #10335:
URL: https://github.com/apache/rocketmq/pull/10335#issuecomment-4485489427

    意见 1: loadNativeShim 未捕获 UnsatisfiedLinkError + 缺少 ARM 架构 shim
   
   问题: loadNativeShim() 中 System.load() 调用可能抛出 UnsatisfiedLinkError(例如在 Linux 
aarch64 上加载 x86-64 的 .so),但当前只捕获了 IOException。由于该方法在 static {} 块中调用,未捕获的 
UnsatisfiedLinkError
    会导致 ExceptionInInitializerError,使 CqCompactionFilterJni 类在整个 JVM 
生命周期内永久不可用,后续任何对该类的引用都会抛出 NoClassDefFoundError。
   
    当前打包的原生库只有:
    - .so — 仅 x86-64
    - .dylib — 仅 arm64
    - .dll — 仅 x86-64
   
    这意味着在 Linux aarch64(云环境中非常常见)加载必然失败,且由于缺少 UnsatisfiedLinkError 
的捕获,不会优雅降级,而是直接崩溃。
   
    建议修复:
   
    1. 在 loadNativeShim() 中增加对 UnsatisfiedLinkError 的捕获,确保加载失败时优雅降级(loaded 保持 
false,系统正常运行但无 compaction filter):
   
    ```java
                  System.load(tempLib.getAbsolutePath());
                  loaded = true;
                  log.info("[CqCompactionFilterJni] Native library loaded from 
classpath: {}", tempLib.getAbsolutePath());
              } catch (IOException e) {
                  log.error("[CqCompactionFilterJni] Failed to load native 
shim", e);
              } catch (UnsatisfiedLinkError e) {
                  log.error("[CqCompactionFilterJni] Failed to load native shim 
library, "
                      + "platform may not be supported: {}", e.getMessage());
              }
    ```
   
    2. 补充 Linux aarch64 的 .so 文件,并在 Java 侧根据 os.arch 选择对应的库文件名。
   
    
────────────────────────────────────────────────────────────────────────────────
   
    ### English
   
    Issue: System.load() in loadNativeShim() can throw UnsatisfiedLinkError 
(e.g., when loading an x86-64 .so on Linux aarch64), but only IOException is 
caught. Since this method is called from a static {} initializer,
    an uncaught UnsatisfiedLinkError will propagate as 
ExceptionInInitializerError, making the CqCompactionFilterJni class permanently 
unusable for the entire JVM lifetime — any subsequent reference to the class 
will
    throw NoClassDefFoundError.
   
    The bundled native libraries currently only cover:
    - .so — x86-64 only
    - .dylib — arm64 only
    - .dll — x86-64 only
   
    This means on Linux aarch64 (very common in cloud environments) and macOS 
x86_64, loading will inevitably fail, and without catching 
UnsatisfiedLinkError, the system won't degrade gracefully — it will crash.
   
    Suggested fix:
   
    1. Catch UnsatisfiedLinkError in loadNativeShim() to ensure graceful 
degradation when loading fails (loaded stays false, system runs normally 
without the compaction filter):
   
    ```java
                  System.load(tempLib.getAbsolutePath());
                  loaded = true;
                  log.info("[CqCompactionFilterJni] Native library loaded from 
classpath: {}", tempLib.getAbsolutePath());
              } catch (IOException e) {
                  log.error("[CqCompactionFilterJni] Failed to load native 
shim", e);
              } catch (UnsatisfiedLinkError e) {
                  log.error("[CqCompactionFilterJni] Failed to load native shim 
library, "
                      + "platform may not be supported: {}", e.getMessage());
              }
    ```
   
    2. Bundle a Linux aarch64 .so , and select the correct library filename 
based on os.arch in the Java code.
   
    
────────────────────────────────────────────────────────────────────────────────
   
   
    问题: setMinPhyOffset() 方法在每次调用时以 INFO 级别记录日志。该方法由 cleanExpired() 
周期性触发(通常每隔几秒到几十秒一次),在生产环境中会产生大量重复日志,增加日志存储压力且淹没真正有价值的信息。
   
    建议修复: 将日志级别改为 DEBUG:
   
    ```java
          public static void setMinPhyOffset(long minPhyOffset) {
              long ptr = NATIVE_FILTER_PTR.get();
              if (ptr != 0) {
                  setMinPhyOffset0(ptr, minPhyOffset);
                  log.debug("CqCompactionFilter setMinPhyOffset={}", 
minPhyOffset);
              }
          }
    ```
   
    
────────────────────────────────────────────────────────────────────────────────
   
   
    Issue: setMinPhyOffset() logs at INFO level on every invocation. This 
method is called periodically by cleanExpired() (typically every few seconds), 
which produces high-volume repetitive log output in production,
    increasing log storage costs and drowning out genuinely useful information.
   
    Suggested fix: Change the log level to DEBUG:
   
    ```java
          public static void setMinPhyOffset(long minPhyOffset) {
              long ptr = NATIVE_FILTER_PTR.get();
              if (ptr != 0) {
                  setMinPhyOffset0(ptr, minPhyOffset);
                  log.debug("CqCompactionFilter setMinPhyOffset={}", 
minPhyOffset);
              }
          }
    ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to