java - NPE en Win32ShellFolder2.access cuando se crea un nuevo JFileChooser como cuenta del sistema local en Windows 7
swing unit-testing (3)
Creo que es un problema de Java 7. Verifica tu versión y prueba con otra. O actualice su versión java.
He escrito pruebas de unidad para una GUI de Swing que crea JFileChooser. Dado que las pruebas unitarias se ejecutan en un servidor de compilación como un servicio, las pruebas de unidad deben ejecutarse como la cuenta del sistema local. Sin embargo, cuando las pruebas de la unidad intentan crear un nuevo JFileChooser, lanzan una NullPointerException.
Reduje el problema al de ejecutar la siguiente clase principal como cuenta de sistema local (NO ES EL CÓDIGO REAL)
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");
}
});
}
}
Usando el siguiente archivo de compilación.
<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>
Si ejecuto el código como mi propia cuenta de usuario, aparece JFileChooser (eso es todo lo que quiero que haga, ya que el código eliminado anteriormente obviamente no hace nada después de eso).
Si ejecuto el código anterior como la cuenta del sistema (por ejemplo, al instalar PsTools / PsExec y ejecutar PsExec.exe -s -i cmd.exe
para iniciar cmd como cuenta del sistema y luego ejecutar el jar, entonces obtengo el siguiente seguimiento de la pila:
[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)
¿Cómo puedo crear un objeto JFileChooser dentro de una JVM que ha sido iniciada por la cuenta del sistema local?
Actualmente estoy usando la versión JVM 1.7.0_25 de 32 bits y he probado tanto en Windows Server 2008 como en Windows 7. Existe otro requisito que significa que no puedo pasar de una JVM de 32 bits a una JVM de 64 bits.
He intentado varias sugerencias de Google, incluido.
- Pasando -Dswing.disableFileChooserSpeedFix = true
- Pasando -Duser.home =. /
- Pasando -Dtemp.dir = C: / temp
... pero ninguno cambió el resultado.
Gracias por cualquier ayuda.
Tuve un problema muy similar y logré resolverlo configurando el servicio que se ejecutará con una cuenta de administrador (en la configuración, no solo al iniciarlo como administrador). Tenga en cuenta que no podrá hacer esto con una cuenta de administrador que no tenga contraseña (bueno, no sin tocar el registro).
Esto no es un problema de JVM, sino un problema de permisos. Recientemente encontré un seguimiento de pila similar al ejecutar Java 8v92 en una máquina con Windows 10.
Para solucionarlo, configure el Servicio de Windows para que inicie sesión como una cuenta de administrador (inicie Servicios, resalte el servicio y muestre Propiedades, seleccione la pestaña Iniciar sesión en Windows 10):