# 客调系统 龙芯/麒麟 移植修复 ## 问题背景 客运调度命令智能化管理系统(北京北辰信息科技)原是 Windows 平台 Java Swing 应用, 通过 IcedTea-Web (javaws) 启动 JNLP 文件运行,后端 WebLogic T3 协议。 移植到龙芯 (loongarch64) 麒麟 V10 SP1 遇到以下问题。 ## 报错与修复原理 ### 问题一:ATK 无障碍框架权限 ``` java.security.AccessControlException: access denied ("java.io.FilePermission" "/usr/bin/xprop" "execute") at org.GNOME.Accessibility.AtkWrapper. ``` GNOME 桌面自动加载 ATK 无障碍技术,初始化时调用 `Runtime.exec("/usr/bin/xprop")`, javaws 沙箱禁止执行外部命令。 **修复**:`-Djavax.accessibility.assistive_technologies=` 禁用 ATK。 ### 问题二:BeautyEye LookAndFeel 不支持 Linux ``` UnsupportedLookAndFeelException: BeautyEye windows-platform L&F not supported on this platform ``` 应用硬编码使用 `BeautyEyeLookAndFeelWin`,该类继承 `com.sun.java.swing.plaf.windows.WindowsLookAndFeel`,后者仅 Windows JDK 才有。 **修复**:重写 `BeautyEyeLookAndFeelWin` 改为继承跨平台版 `BeautyEyeLookAndFeelCross`, 编译后放入完整 beautyeye jar,通过 `-Xbootclasspath/a:` 挂到 JVM bootstrap classloader。 ### 问题三:NoSuchMethodError ``` NoSuchMethodError: BeautyEyeLookAndFeelWin.initLookAndFeelDecorated()V at BeautyEyeLookAndFeelCross. ``` `BeautyEyeLookAndFeelCross` 的静态初始化块会调用 `Win.initLookAndFeelDecorated()`, 替换类缺少此方法。 **修复**:在替换类中完整实现此静态方法。 ### 问题四:JAR 签名校验 ``` SecurityException: Invalid signature file digest for Manifest main attributes ``` 原始 beautyeye jar 带有数字签名,修改 class 后签名失效。 **修复**:删除 jar 中的 `.SF` / `.DSA` / `.RSA` 签名文件。 ### 问题五:环境变量不生效(GUI/终端均报错) 应用通过桌面双击启动,不经过 bash,`~/.bashrc` 中的 `export` 不会被加载; 终端启动时 `.bashrc` 非交互式守卫也会跳过。且不同应用需要的参数不同, 不宜全局设置。 **修复**:不写全局环境变量,改为在 `.desktop` 快捷方式的 `Exec` 行中用 `env _JAVA_OPTIONS="..." javaws ...` 按应用分别传参。每个 `.desktop` 文件 只带自己需要的参数,互不干扰。 ### 问题六:启动界面中文乱码 应用原是 Windows 平台开发,界面字体依赖 Windows 自带中文字体(如宋体、微软雅黑)。 麒麟系统虽有中文字体,但 OpenJDK 8 的 JRE 缺少 `fontconfig.properties` 配置, 无法将 Java 逻辑字体映射到系统中文字体,导致界面中文显示为方框或乱码。 **修复**:将系统中文字体链接到 JRE 的 `lib/fonts/fallback/` 目录,Java 在渲染 字符遇到缺字时自动回退到这些字体。 ## 文件说明 ``` change_data/ ├── README.md # 本文档 ├── BeautyEyeLookAndFeelWin.java # 替换类源码(备份) ├── beautyeye-1.0-fixed.jar # 编译后的完整补丁 jar ├── 客调系统.desktop # 桌面快捷方式(放到 ~/桌面/ 即可双击启动) └── start.sh # 备用手动启动脚本(终端下使用) 1_data/ # 电子运统46 的相关文件 ├── README.md ├── 电子运统46.desktop ├── 电子运统46.jnlp └── construct.ini ``` ### beautyeye-1.0-fixed.jar 包含修复后 `BeautyEyeLookAndFeelWin.class` + 原 beautyeye 全部 166 个类, 已去除签名文件。挂到 bootstrap classpath 后,无论 javaws 如何更新缓存, JVM 始终优先加载此版本。 ### 客调系统.desktop 要点 ```ini # Exec 行用 env 只为本次启动设置 _JAVA_OPTIONS,不影响其他 Java 程序 Exec=env _JAVA_OPTIONS="-Djavax.accessibility.assistive_technologies= -Xbootclasspath/a:/path/to/beautyeye-1.0-fixed.jar" /usr/bin/javaws "xxx.jnlp" # Path 行确保工作目录正确,应用能找到 config.ini 等相对路径文件 Path=/home/loongson/桌面/TDMS_DDML/TDMS_DDML ``` ### BeautyEyeLookAndFeelWin.java 修改要点 ```java // 原始: extends WindowsLookAndFeel (仅 Windows 可用) // 修改: extends BeautyEyeLookAndFeelCross (跨平台) static void initLookAndFeelDecorated() { // 被 Cross. 调用,必须保留 if (frameBorderStyle == osLookAndFeelDecorated) { JFrame.setDefaultLookAndFeelDecorated(false); JDialog.setDefaultLookAndFeelDecorated(false); } else { JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); } } ``` --- ## 新机器完整配置步骤 ### 前置条件 | 组件 | 要求 | |------|------| | CPU | 龙芯 loongarch64 | | OS | 麒麟 V10 SP1 | | JDK | OpenJDK 1.8.0_282 Loongson build | | IcedTea-Web | 系统自带 | | 网络 | 可访问后端 WebLogic 服务器 | | 权限 | 需要 sudo(仅步骤三字体配置) | | JNLP文件 | 已放置在可访问路径 | ### 步骤一:放置补丁 jar(仅客调系统需要) ```bash # 在 Kylin 机器上执行,选择一个固定路径 mkdir -p /opt/ktms-fix cp beautyeye-1.0-fixed.jar /opt/ktms-fix/ chmod 644 /opt/ktms-fix/beautyeye-1.0-fixed.jar ``` > 路径一旦确定不要在 `.desktop` 里改变。 ### 步骤二:安装桌面快捷方式 将 `.desktop` 文件复制到桌面,根据实际情况修改其中的路径: ```bash cp 客调系统.desktop ~/桌面/ chmod +x ~/桌面/客调系统.desktop ``` `.desktop` 文件自带启动参数,无需额外配置环境变量。每个应用独立一份: - **客调系统.desktop** → ATK + BeautyEye 补丁 - **电子运统46.desktop** → ATK + JNDI 工厂类(电子运统46 不需要 BeautyEye 补丁) > 首次双击时 UKUI 可能提示"是否信任",点信任即可。之后双击直接启动。 ### 步骤三:配置中文字体(消除界面乱码) ```bash sudo mkdir -p /usr/lib/jvm/java-8-openjdk-loongarch64/jre/lib/fonts/fallback sudo ln -sf /usr/share/fonts/gb/国标黑体.ttf \ /usr/lib/jvm/java-8-openjdk-loongarch64/jre/lib/fonts/fallback/GB-HT.ttf sudo ln -sf /usr/share/fonts/gb/国标宋体.ttf \ /usr/lib/jvm/java-8-openjdk-loongarch64/jre/lib/fonts/fallback/GB-SS.ttf ``` > 仅需执行一次,所有 Java 应用共享。不需重启,下次启动 Java 程序即生效。 ### 步骤四:验证 双击桌面上的 `.desktop` 快捷方式启动应用。验证成功的标志: - 启动过程终端/日志无 ERROR - 界面中文正常显示(非方框或问号) - 出现登录界面并能连接后端 **客调系统**:`kc.log` 中出现 INFO 日志,无 ERROR: ``` [INFO] 客车调图系统URL地址:t3://10.102.16.134:7011/ [INFO] 日班计划URL地址:t3://10.102.3.150:7001/ [INFO] 客调URL地址:t3://10.102.3.153:7001/ ``` **电子运统46**:`yt46.log` 中无 `NoInitialContextException`,无 ERROR。 不应出现以下任何错误: - ~~AccessControlException (xprop)~~ - ~~UnsupportedLookAndFeelException~~ - ~~NoSuchMethodError~~ - ~~SecurityException (signature digest)~~ - ~~NoInitialContextException (JNDI)~~ - ~~界面中文乱码(方框/问号)~~ ### 终端手动启动(调试用) 如果需要在终端启动而非双击桌面图标,需手动指定工作目录和参数: ```bash # 客调系统 cd ~/桌面/TDMS_DDML/TDMS_DDML export _JAVA_OPTIONS="-Djavax.accessibility.assistive_technologies= -Xbootclasspath/a:/path/to/beautyeye-1.0-fixed.jar" javaws 客运调度命令智能化管理系统.jnlp # 电子运统46 cd ~/桌面/env/whyt46station export _JAVA_OPTIONS="-Djavax.accessibility.assistive_technologies= -Djava.naming.factory.initial=weblogic.jndi.WLInitialContextFactory" javaws 电子运统46.jnlp ``` ## 各应用参数对照 | 应用 | ATK 禁用 | BeautyEye 补丁 | JNDI 工厂 | .desktop | |------|----------|---------------|-----------|----------| | 客调系统 | 需要 | 需要 | 不需要 | 客调系统.desktop | | 电子运统46 | 需要 | 不需要 | 需要 | 电子运统46.desktop | ## 原理 ``` .desktop 文件双击 └─ Exec=env _JAVA_OPTIONS="..." /usr/bin/javaws "xxx.jnlp" └─ 仅为本次 javaws 及其子 java 进程设置 _JAVA_OPTIONS ├─ -Djavax.accessibility.assistive_technologies= → 禁用 ATK ├─ -Djava.naming.factory.initial=... → JNDI 工厂(部分应用需要) └─ -Xbootclasspath/a:beautyeye-1.0-fixed.jar → 优先加载补丁类(仅客调需要) Path= 指定工作目录 → config.ini / kc.log 等相对路径文件都能正确找到 本方案隔离性:每个 .desktop 的 _JAVA_OPTIONS 仅对自身有效, 系统上其他 Java 程序不受任何影响。 JVM 类加载层级(优先级从高到低): Bootstrap ClassLoader ← -Xbootclasspath/a 挂载 ★ 补丁在此 ↑ Extension ClassLoader ↑ JNLPClassLoader ← javaws 缓存(会被服务端更新覆盖) 此处加载的同名类被 Bootstrap 层遮蔽,不生效 ```