我们的一些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错误---但如果我们知道是什么引发了错误,我们至少可以帮助我们的用户受到它的影响。任何人都可以了解导致这种情况发生的原因吗?
编辑:相关的原生函数来自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);
}
为了达到“无法绑定”异常,看起来pDesktop != NULL
和relPIDL
成功检索,但pDesktop->BindToObject()
会返回S_OK
以外的内容。 pDesktop
是IShellFolder*
,显然是在Windows的<shellapi.h>
中定义的。更糟糕的是,Java抛弃了IShellFolder::BindToObject
返回的错误代码。
所以,我想这个问题简化为:什么可能导致IShellFolder::BindToObject
失败?
编辑2 :由于Win32ShellFolderManager2.getNetwork()
正在Win32ShellFolderManager2.java:181调用Win32ShellFolder2
ctor,我们可以看到Win32ShellFolder2.initSpecial
的最后一个参数必须是Win32ShellFolder2.NETWORK
。那么,用户的Network Neighborhood文件夹可能出现问题吗?
答案 0 :(得分:2)
嗯,有几个类似于你的报告(如this one from jEdit,this one from codenameone和this one - 德语 - 这似乎是一个JFileChooser
错误,堆栈跟踪非常在Windows 7和Java 6中接近你的。所有这些似乎都以某种方式与JFileChooser
和/或文件浏览相关。
所以我会用两种方法之一来解决这个问题:
使用jstack,VisualVM或JConsole等工具进行耗时/非投机的道路并转储受影响的安装,直到您能够隔离根目录为止问题的原因(可能是也可能不是JFileChooser
)。如果您选择该路径,请记住必须远程访问其中一个受影响的安装或技术娴熟的用户提供帮助。
或尝试采用快捷方式,假设问题确实是JFileChooser
(如轶事证据所示)并发布自JFileChooser
替换FileDialog的自定义版本。如果它在受影响的机器上按预期运行,则关闭案例;否则就给自己轻拍一下,试试并采取“漫长而曲折的道路”#34;
答案 1 :(得分:0)
有同样的问题,答案是 java.awt.FileDialog
如果您查找VbScript解决方案&#34;打开文件对话框&#34;,似乎没有COM类为大多数Windows平台执行此任务