5

我为创建 JFileChooser 的 Swing GUI 编写了单元测试。由于单元测试作为服务在构建服务器上运行,因此单元测试需要作为本地系统帐户运行。但是,当单元测试尝试创建新的 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");
            }
        });
    }
}

使用以下构建文件。

<project>

<target name="clean">
    <delete dir="build"/>
</target>

<target name="compile" depends="clean">
    <mkdir dir="build/classes"/>
    <javac srcdir="src" destdir="build/classes"/>
</target>

<target name="jar" depends="compile">
    <mkdir dir="build/jar"/>
    <jar destfile="build/jar/FileChooserAsSystem.jar" basedir="build/classes">
        <manifest>
            <attribute name="Main-Class" value="com.example.mcgr.FileChooserAsSystem"/>
        </manifest>
    </jar>
</target>

<target name="run">
    <java jar="build/jar/FileChooserAsSystem.jar" fork="true"/>
</target>

</project>

如果我以我自己的用户帐户运行代码,则会出现 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

...但没有人改变结果。

谢谢你的帮助。

4

3 回答 3

2

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

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

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

于 2016-08-18T14:27:56.290 回答
0

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

于 2014-10-30T19:47:53.190 回答
0

我相信是 Java 7 的问题。检查您的版本并尝试使用另一个版本。或者升级你的java版本。

于 2014-06-10T16:42:17.500 回答