在Windows 7中将新JFileChooser创建为本地系统帐户时Win32ShellFolder2.access中的NPE

我已经为创建JFileChooser的Swing GUI编写了unit testing。 由于unit testing作为服务在构建服务器上运行,因此unit testing需要作为本地系统帐户运行。 但是,当unit testing尝试创建新的JFileChooser时,它们会抛出NullPointerException。

我把问题简化为运行以下主类作为本地系统帐户(不是真正的代码)

package com.example.mcgr; import javax.swing.*; import java.io.IOException; public class FileChooserAsSystem { public static void main(String[] args) throws IOException { SwingUtilities.invokeLater(new Runnable() { public void run() { JFileChooser fileChooser = new JFileChooser(); fileChooser.showDialog(null, "Ok"); } }); } } 

使用以下构建文件。

                     

如果我将代码作为我自己的用户帐户运行,则会出现JFileChooser(这就是我想要的所有内容,因为上面的精简代码显然在此后没有做任何事情)。

如果我将上述代码作为系统帐户运行(例如,通过安装PsTools / PsExec并运行PsExec.exe -s -i cmd.exe来启动cmd作为系统帐户然后运行jar,那么我得到以下堆栈跟踪:

  [java] Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException [java] at sun.awt.shell.Win32ShellFolder2.access$200(Win32ShellFolder2.java:72) [java] at sun.awt.shell.Win32ShellFolder2$1.call(Win32ShellFolder2.java:242) [java] at sun.awt.shell.Win32ShellFolder2$1.call(Win32ShellFolder2.java:237) [java] at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) [java] at java.util.concurrent.FutureTask.run(FutureTask.java:166) [java] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [java] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [java] at sun.awt.shell.Win32ShellFolderManager2$ComInvoker$3.run(Win32ShellFolderManager2.java:502) [java] at java.lang.Thread.run(Thread.java:724) 

如何在本地系统帐户启动的JVM中创建JFileChooser对象?

我目前正在使用JVM版本1.7.0_25 32位并且已经在Windows Server 2008和Windows 7上进行了测试。还有一个要求意味着我无法从32位JVM切换到64位JVM。

我尝试了谷歌的各种建议,包括。

  • 传递-Dswing.disableFileChooserSpeedFix = true
  • 传递-Duser.home =。/
  • 传递-Dtemp.dir = C:/ temp

……但没有改变结果。

谢谢你的帮助。

这不是JVM问题,而是权限问题。 我最近在Windows 10机器上遇到了类似的运行Java 8v92的堆栈跟踪。

要解决此问题,请将Windows服务设置为以管理员帐户登录(启动“服务”,突出显示该服务并显示“属性”,然后选择“Windows 10中的登录”选项卡):

将Windows服务设置为使用管理员帐户

我相信是Java 7的问题。 检查您的版本并尝试使用其他版本。 或升级您的Java版本。

我碰巧有一个非常类似的问题,我设法解决它配置要使用管理员帐户执行的服务(在配置中,而不仅仅是启动它是管理员)。 请注意,您将无法使用没有密码的管理员帐户执行此操作(嗯,不是没有触及注册表)。