java - 是什么导致 sun.awt.shell.Win32ShellFolder2.initSpecial() 抛出 InternalError?

标签 java windows winapi

我们的一些 Windows 用户在启动我们的应用后不久就得到了这个堆栈跟踪:

java.lang.InternalError: Could not bind shell folder to interface
  at sun.awt.shell.Win32ShellFolder2.initSpecial(Native Method) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolder2.access$300(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolder2$1.call(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolder2$1.call(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolderManager2$ComInvoker.invoke(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.ShellFolder.invoke(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolder2.<init>(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolderManager2.getNetwork(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolder2.getFileSystemPath(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolder2.access$400(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolder2$10.call(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolder2$10.call(Unknown Source) ~[na:1.7.0_25]
  at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) ~[na:1.7.0_25]
  at java.util.concurrent.FutureTask.run(Unknown Source) ~[na:1.7.0_25]
  at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:1.7.0_25]
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:1.7.0_25]
  at sun.awt.shell.Win32ShellFolderManager2$ComInvoker$3.run(Unknown Source) ~[na:1.7.0_25]
  at java.lang.Thread.run(Unknown Source) ~[na:1.7.0_25]

观察:

  • 堆栈跟踪中的每一帧都是 JDK 中的内容,而不是我们的代码中的内容。
  • 这种情况只发生在 Windows 上,但我们在 Vista 和 Windows 7 上都遇到过这种情况的报告。
  • Java 的各种版本都会出现这种情况:1.6.0_19、1.6.0_21、1.7.0_11、1.7.0_25。
  • 该问题只发生在我们的少数用户身上,但对这些用户来说是 100% 可重复的。不幸的是,除了展示此问题之外,我们无法看到这些用户系统的任何共同点,而且我们的开发人员都没有亲身经历过。
  • 我对 Oracle 错误数据库的搜索没有发现具有相同或相似堆栈跟踪的错误。
  • 网络上似乎有很多关于这个特定问题的帖子,但没有人知道是什么原因造成的。

无论问题是什么,我都不希望 Oracle 修复它,如果它确实是一个 JDK 错误 --- 但如果我们知道是什么触发了该错误,我们至少可以帮助受其困扰的用户。任何人都可以阐明导致这种情况发生的原因吗?

编辑:相关的原生函数是这个,来自ShellFolder2.cpp :

JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_initSpecial
    (JNIEnv* env, jobject folder, jlong desktopIShellFolder, jint folderType)
{
    // Get desktop IShellFolder interface
    IShellFolder* pDesktop = (IShellFolder*)desktopIShellFolder;
    if (pDesktop == NULL) {
        JNU_ThrowInternalError(env, "Desktop shell folder missing");
        return;
    }
    // Get special folder relative PIDL
    LPITEMIDLIST relPIDL;
    HRESULT res = fn_SHGetSpecialFolderLocation(NULL, folderType,
        &relPIDL);
    if (res != S_OK) {
        JNU_ThrowIOException(env, "Could not get shell folder ID list");
        return;
    }
    // Set field ID for relative PIDL
    env->CallVoidMethod(folder, MID_relativePIDL, (jlong)relPIDL);
    // Get special folder IShellFolder interface
    IShellFolder* pFolder;
    res = pDesktop->BindToObject(relPIDL, NULL, IID_IShellFolder,
        (void**)&pFolder);
    if (res != S_OK) {
        JNU_ThrowInternalError(env,
            "Could not bind shell folder to interface");
        return;
    }
    // Set field ID for pIShellFolder
    env->CallVoidMethod(folder, MID_pIShellFolder, (jlong)pFolder);
}

为了达到“无法绑定(bind)”异常,看起来像pDesktop != NULLrelPIDL检索成功,但 pDesktop->BindToObject()返回 S_OK 以外的内容. pDesktop是一个 IShellFolder* ,这显然是在 Windows 的 <shellapi.h> 中定义的.更糟糕的是,Java 丢弃了 IShellFolder::BindToObject 返回的错误代码。 .

所以,我想问题可以简化为:什么会导致 IShellFolder::BindToObject失败?

编辑 2:自 Win32ShellFolderManager2.getNetwork()是什么叫Win32ShellFolder2主管 Win32ShellFolderManager2.java:181 ,我们可以看到 Win32ShellFolder2.initSpecial 的最后一个参数必须是 Win32ShellFolder2.NETWORK .那么,用户的网上邻居文件夹是否有问题?

最佳答案

好吧,有几个报告与您的类似(例如 this one from jEditthis one from codenameonethis one - 在德语中 - 这看起来像是一个 JFileChooser 错误,其堆栈跟踪与您的非常接近在 Windows 7 和 Java 6 中)。所有这些似乎都以某种方式与 JFileChooser 和/或文件浏览有关。

所以我会通过以下两种方式之一来解决这个问题:

要么走耗时的/非投机的道路,并使用 jstack 等工具转储受影响的安装。 , VisualVMJConsole直到您能够找出问题的根本原因(可能是也可能不是 JFileChooser)。如果您选择该路径,请记住必须远程访问其中一个受影响的安装或来自技术娴熟的用户的帮助。

或者尝试走捷径,假设问题确实出在 JFileChooser(如轶事证据所示)并发布一个自定义版本,用 FileDialog 替换 JFileChooser| .如果它在受影响的机器上按预期运行,则关闭;否则,请轻拍自己的后背,尝试走“漫长而曲折的道路”。

关于java - 是什么导致 sun.awt.shell.Win32ShellFolder2.initSpecial() 抛出 InternalError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17644390/

相关文章:

java - 可以在 Room 数据库的构造函数中使用 @Ignore 字段吗?

java - 如何有效地测试目录中是否存在具有匹配文件名(正则表达式或通配符)的文件?

java - 如何从自定义 Java 桌面应用程序启动 NXP 产品 JCOPShell (jcshell.bat)

java - Hadoop。具有统计信息的字数统计

windows - Windows 8.1 应用程序中的 Google Analytics

c++ - 如何为 VS2008 __forceinline 函数?

javascript - html5 和 js 中的地理定位 - 我拒绝但我想接受 - 如何重置?

c++ - VirtualProtectEx 函数失败 - 错误 487,仅在 Windows XP 上

c++ - 如何检查调用 CallwindowProc 时窗口过程是否未损坏?

c - 以编程方式监视 XP 上的 CPU 负载