You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java17下从ACLEntry获取SID:无需反射方案及反射异常解决

解决方案

一、无需反射的替代方法

依赖sun.nio.fs.WindowsUserPrincipals$User这类内部API存在版本兼容性风险,推荐通过Windows系统原生能力根据用户名查询SID:

方法1:调用Windows命令行工具解析输出

通过wmic命令根据用户名提取对应SID,示例代码如下:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public class SidUtils {
    public static String getSidByUsername(String username) throws Exception {
        // 处理域名+用户名格式(如DOMAIN\user),提取纯用户名部分
        String pureUsername = username.contains("\\") ? username.split("\\\\")[1] : username;
        Process process = new ProcessBuilder("wmic", "useraccount", "where", "name='" + pureUsername + "'", "get", "sid")
                .redirectErrorStream(true)
                .start();
        
        String output = new BufferedReader(new InputStreamReader(process.getInputStream()))
                .lines()
                .collect(Collectors.joining("\n"));
        
        // 过滤输出,提取有效SID行
        for (String line : output.split("\n")) {
            String trimmedLine = line.trim();
            if (!trimmedLine.isEmpty() && !trimmedLine.equals("SID")) {
                return trimmedLine.toLowerCase();
            }
        }
        throw new IllegalArgumentException("无法找到用户 " + username + " 的SID");
    }
}

使用时直接传入UserPrincipal的名称即可:

UserPrincipal userPrincipal = aclEntry.principal();
String sid = SidUtils.getSidByUsername(userPrincipal.getName());

方法2:调用Windows原生API(需引入JNA依赖)

如果追求更高性能和可靠性,可通过JNA直接调用Windows的LookupAccountNameAPI,需添加JNA相关依赖(如net.java.dev.jna:jna和net.java.dev.jna:jna-platform),通过原生API完成用户名到SID的转换,避免命令行解析的开销。

二、绕过反射异常的临时方案

若必须延续原有反射逻辑,需在Java启动参数中添加模块开放配置,允许未命名模块访问java.base下的sun.nio.fs包:

--add-opens java.base/sun.nio.fs=ALL-UNNAMED

注意:该方案依赖Java内部未公开API,未来版本存在被移除的风险,仅作为临时过渡方案使用,不推荐长期依赖。

内容的提问来源于stack exchange,提问作者Paul Curran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 04:40:26