Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NPE in Win32ShellFolder2.access when creating new JFileChooser as Local System Account in Windows 7

I have written unit tests for a Swing GUI that creates JFileChooser. Since the unit tests are run on a build server as a service, the unit tests need to run as the local system account. However, when the unit tests try to create a new JFileChooser, they throw a NullPointerException.

I've reduced the problem to that of running the following main class as local system account (NOT THE REAL CODE)

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");
            }
        });
    }
}

Using the following build file.

<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>

If I run the code as my own user account, the JFileChooser appears (that's all I want it to do as the above stripped down code obviously doesn't do anything after that).

If I run the above code as the system account (e.g. by installing PsTools/PsExec and running PsExec.exe -s -i cmd.exe to start cmd as system account and then running the jar, then I get the following stack trace:

 [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)

How can I create a JFileChooser object within a JVM that has been launched by the local system account?

I'm currently using JVM version 1.7.0_25 32bit and have tested on both Windows Server 2008 and Windows 7. There's another requirement that means I can't switch from a 32bit JVM to 64bit JVM.

I've tried various suggestions from Google including.

  • Passing -Dswing.disableFileChooserSpeedFix=true
  • Passing -Duser.home=./
  • Passing -Dtemp.dir=C:/temp

... but none changed the result.

Thanks for any help.

like image 899
user1857450 Avatar asked Nov 01 '22 00:11

user1857450


1 Answers

This is not a JVM issue but a permissions issue. I recently encountered a similar stack trace running Java 8v92 on a Windows 10 machine.

To fix this, set the Windows Service to log on as an Administrator account (launch Services, highlight the service and show Properties, select Log On tab in Windows 10):

Set Windows Service to use an Admin account

like image 116
sjgp Avatar answered Nov 15 '22 05:11

sjgp