DBeaver 25.3.5 在 macOS 上 Dock 启动失败:完整排查与临时修复实战

8 阅读4分钟

结论先说:这是 launcher 的无参数启动路径不稳定。我的临时解法是:wrapper 显式传 --launcher.ini--launcher.library,并附加 -clean

TOC


1. 背景

在 macOS(Apple Silicon)环境里,DBeaver 升级到 25.3.5 后仍出现启动失败。表现并不唯一:

  • 点击 Dock 图标无反应或闪退
  • 命令行直接启动崩溃(exit 139
  • 某些修复尝试后出现:
    • The Dbeaver-bin executable launcher was unable to locate its companion shared library.

本文记录一次完整排查过程,并给出一个可复用的「更新后一条命令重打补丁」方案。


2. 环境信息

  • 系统:macOS 15.6.1 (24G90)
  • 架构:arm64 (Apple Silicon)
  • DBeaver:25.3.5
  • 安装目录:/Applications/DBeaver.app

3. 问题现象

3.1 无参数启动崩溃

执行:

/Applications/DBeaver.app/Contents/MacOS/dbeaver

结果:

  • exit 139
  • 生成 ~/Library/Logs/DiagnosticReports/dbeaver-*.ips

崩溃日志中可见主线程早期崩溃,且可稳定复现。

3.2 Dock 启动失败

Dock 触发 LaunchServices 启动,有时出现:

  • kLSNoExecutableErr
  • 或出现 companion library 相关报错

3.3 关键对比

实测存在一个重要差异:

  • 无参数:容易崩
  • 带参数(如 -clean):能进入完整启动链路(Eclipse + Java)

这说明问题集中在 launcher 的无参数路径。


4. 排查过程(时间线)

4.1 基础确认

  • 确认版本、路径、可执行文件类型
  • 检查崩溃日志:~/Library/Logs/DiagnosticReports/dbeaver-*.ips
  • 检查 DBeaver 日志:~/Library/DBeaverData/workspace6/.metadata/dbeaver-debug.log

结论:DBeaver 在很早期启动阶段崩溃,且与连接配置无关。

4.2 系统缓存侧排查

尝试并验证过:

  • 清除 quarantine:xattr -dr com.apple.quarantine /Applications/DBeaver.app
  • 重新注册应用:lsregister -f /Applications/DBeaver.app
  • 重启 Dock:killall Dock
  • 重建 Dock 项

这些动作可修复部分 LS 缓存异常,但无法从根本解决无参数崩溃。

4.3 第一次临时修复踩坑

早期方案将真实二进制重命名为 dbeaver-bin 并由脚本转发,导致:

  • The Dbeaver-bin executable launcher was unable to locate its companion shared library.

原因:Eclipse launcher 对自身路径/参数解析存在约束,简单改名会破坏默认 companion library 发现逻辑。

4.4 最终稳定方案

最终方案采用三点组合:

  1. 保留真实 launcher(命名为 dbeaver-real
  2. dbeaver 改为 wrapper,但显式传入
    • --launcher.ini
    • --launcher.library
    • -clean
  3. dbeaver.ini 中确保包含 -clean(幂等注入)

这样既绕过无参数崩溃,又规避 companion shared library 报错。


5. 最终脚本(可直接使用)

建议保存为:~/bin/fix-dbeaver-launch.sh

#!/bin/zsh
set -euo pipefail

APP="/Applications/DBeaver.app"
MACOS="$APP/Contents/MacOS"
ECLIPSE="$APP/Contents/Eclipse"
BIN="$MACOS/dbeaver"
REAL="$MACOS/dbeaver-real"
INI="$ECLIPSE/dbeaver.ini"

if [[ ! -d "$APP" ]]; then
  echo "[ERR] DBeaver not found: $APP"
  exit 1
fi

if [[ ! -f "$INI" ]]; then
  echo "[ERR] dbeaver.ini not found: $INI"
  exit 1
fi

# 1) Keep a copy of original Mach-O launcher and rename to dbeaver-real
if [[ -f "$BIN" ]] && file "$BIN" | grep -q 'Mach-O'; then
  TS=$(date +%Y%m%d-%H%M%S)
  cp -p "$BIN" "$MACOS/dbeaver.bin.$TS.bak"
  mv "$BIN" "$REAL"
fi

if [[ ! -f "$REAL" ]]; then
  echo "[ERR] Missing real launcher: $REAL"
  exit 1
fi

# 2) Ensure -clean exists in dbeaver.ini (launcher arg, before -vmargs)
if ! grep -qx -- '-clean' "$INI"; then
  TMP=$(mktemp)
  awk 'BEGIN{done=0}
       {
         if (!done && $0=="-vmargs") { print "-clean"; done=1 }
         print $0
       }
       END{ if (!done) print "-clean" }' "$INI" > "$TMP"
  mv "$TMP" "$INI"
fi

# 3) Find launcher library dir
LIB_DIR=$(ls -d "$ECLIPSE"/plugins/org.eclipse.equinox.launcher.cocoa.macosx.aarch64_* 2>/dev/null | head -n 1 || true)
if [[ -z "$LIB_DIR" ]]; then
  echo "[ERR] launcher library not found under: $ECLIPSE/plugins"
  exit 1
fi

# 4) Install robust wrapper as dbeaver
cat > "$BIN" <<WRAP
#!/bin/zsh
set -e
SCRIPT="\$0"
while [ -L "\$SCRIPT" ]; do
  LINK="\$(readlink "\$SCRIPT")"
  if [[ "\$LINK" == /* ]]; then
    SCRIPT="\$LINK"
  else
    SCRIPT="\$(cd "\$(dirname "\$SCRIPT")" && pwd)/\$LINK"
  fi
done
DIR="\$(cd "\$(dirname "\$SCRIPT")" && pwd)"
ECLIPSE_DIR="\$DIR/../Eclipse"
exec "\$DIR/dbeaver-real" \
  --launcher.ini "\$ECLIPSE_DIR/dbeaver.ini" \
  --launcher.library "$LIB_DIR" \
  -clean "\$@"
WRAP
chmod 755 "$BIN"

# 5) Refresh registration/cache
xattr -dr com.apple.quarantine "$APP" >/dev/null 2>&1 || true
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "$APP" >/dev/null 2>&1 || true
killall Dock >/dev/null 2>&1 || true

echo "[OK] DBeaver launch patch applied"
echo "     launcher: $BIN"
echo "     real bin: $REAL"

6. 使用方式

每次升级 DBeaver 后执行一条命令:

~/bin/fix-dbeaver-launch.sh

7. 验证建议

执行后可用以下方式快速验证:

open -n -b org.jkiss.dbeaver.core.product
open -na /Applications/DBeaver.app

并检查是否新增崩溃文件:

ls -lt ~/Library/Logs/DiagnosticReports/dbeaver-*.ips | head -n 3

8. Q&A

Q1:下次更新会覆盖这次修复吗?

会。更新通常覆盖整个 /Applications/DBeaver.app,所以补丁会丢失。

Q2:为什么不能只改 dbeaver.ini

只改 -clean 在部分情况下仍不稳。显式传 --launcher.ini + --launcher.library 可以规避 companion library 定位问题。

Q3:为什么会出现 companion shared library 报错?

因为改名/包装时没把 launcher 所需路径信息显式传递给真实二进制。

Q4:这个方案是永久修复吗?

不是。是工程化临时兜底,等待上游版本修复更稳妥。

Q5:如果 Dock 还是失败?

先移除 Dock 中 DBeaver,再从 /Applications/DBeaver.app 打开并重新固定;然后再跑一次脚本。

Q6:如何回滚?

最简单:重装 DBeaver 覆盖整个 .app


9. 结论

这次问题本质是 launcher 无参数启动路径在当前系统环境下不稳定,叠加 Dock/LaunchServices 行为导致体验更差。通过“显式参数 + wrapper + 缓存刷新”的方案,可以稳定绕过。

如果你的环境也有同类症状,建议将该脚本纳入个人升级后 checklist。