JDK 7u51, Derby Network y Security Manager
Tal y como indican las notas de la versión de Java 7u51, esas que no solemos leer, hay un cambio en los permisos predeterminados para los sockets. Esto significa que las aplicaciones ya no pueden abrir libremente cualquier socket que deseen por encima del puerto 1024, sino que ahora están restringidos al rango de puertos efímeros ("ephemeral ports" en inglés).
Aunque las notas de la versión sugieren que el cambio no va a afectar a la mayoría de las aplicaciones, la primera bofetada me la he llevado hoy con NetBeans y una base de datos Derby a la que accedo mediante la ventana Services de NetBeans. Donde antes, al intentar arrancar la base de datos, aparecían unas cuantas líneas informativas en la ventana Output sin mayor trascendencia, hoy, tras actualizar a JDK 7u51, aparecía un mensaje de error en esa ventana y un diálogo con una excepción.
El mensaje era "access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve")", seguido de la traza completa de la excepción. Hay que quedarse con este dato para poder arreglarlo.
La forma de arreglarlo, para los que como yo no solemos usar un Security Manager, es lanzar la herramienta de políticas, que yo he encontrado en el directorio bin del JDK (también está en el directorio bin del JRE). La herramienta se llama "policytool"; en mi caso, con Linux, la he lanzado mediante "/usr/local/jdk1.7/bin/policytool &".
Esta página tiene una guía sobre el uso de esta herramienta. Los pasos que yo he seguido para el problema concreto de Derby en NetBeans han sido los siguientes:
- Clic en el botón Agregar entrada de política
- Codebase: yo he ido "a lo bruto" y he puesto file:/usr/local/jdk1.7/-. Es decir, estoy dando permiso a todos los archivos class y jar que hay dentro de ese directorio y todos sus subdirectorios ("-" al final). Luego he afinado un poco más y lo he cambiado por "file:/usr/local/jdk1.7/db/lib/*".
- Si el permiso es para todos los archivos class de un directorio (no los JAR), debéis poner la ruta completa terminada en "/" (pero recordad comenzar siempre con file:).
- Si el permiso es para todos los archivos class y JAR de un directorio, debéis poner la ruta completa terminada en "/*".
- Si el permiso es para todos los archivos class y JAR de un directorio y sus subdirectorios, debéis poner la ruta completa terminada en "/-".
- Si el archivo estuviera firmado y tuvierais el alias en vuestro keystore, incluiríais el alias en SignedBy. Para Derby yo no he puesto nada.
- Las entradas de Principal no las he tocado (¿alguien se anima a comentar para qué sirven?). Lo que yo he entendido es que permiten limitar desde que clase llamante se debe invocar la clase a la que damos permisos para que ésta disponga de ellos.
- A continuación hay que pulsar el botón "Agregar permiso". Aparece un diálogo que nos pide cuatro datos:
- El primero es el tipo de permiso y en este momento es cuando tenemos que recordar el mensaje de error. Para Derby, el permiso, recurso o clase que se intentaba usar es java.net.SocketPermission (en el desplegable, simplemente SocketPermission).
- El segundo es el destino y ahí debemos escribir "localhost:1527", como figuraba en el mensaje de error.
- El tercero son las acciones. Es un desplegable con varias opciones y, en este caso, tenemos que añadir dos de ellas que también se mencionaban en el mensaje de error: listen y resolve. Basta con elegir la primera del desplegable, que aparecerá en la casilla de valores, y elegir la segunda otra vez del desplegable, para que la casilla de valores ponga "listen, resolve".
- El último valor, Firmado por, yo lo he dejado en blanco.
- Aceptamos el diálogo de permisos, aceptamos el diálogo de política ("Listo" al pie) y, de vuelta en la ventana principal de la aplicación, elegimos Archivo -> Guardar. Nos pedirá una ubicación y nombre. De acuerdo con la guía de usuario, el nombre de la política por defecto es ".java.policy" y se ubica en el directorio del usuario. En Linux es $HOME, en Windows no sé si será HOMEPATH (y, en Mac, ni idea, lo siento).
Una vez guardado, si volvéis a probar a conectar a la base de datos desde NetBeans, ya no deberíais tener problema. Recordad, si queréis hacer cambios en la política, que debéis grabarla para que surta efecto, no basta con que la veáis modificada en la herramienta de políticas.
Espero que la explicación os resulte útil y os evite algún dolor de cabeza que otro.
Nota: noticia enviada por rickiees
Reader Comments (6)
Buenas:
necesito solucionar esto, creo que está relacionado con lo que comentas pero no sabría ni por dónde empezar:
java.lang.ExceptionInInitializerError
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.exe4j.runtime.LauncherEngine.launch(Unknown Source)
at com.exe4j.runtime.WinLauncher.main(Unknown Source)
Caused by: java.lang.NullPointerException
at com.aeat.informativas.PlataformaInformativas.<clinit>(Unknown Source)
... 6 more
Más información sobre otras sorpresitas que ha traído esta Update aquí:
http://www.javahispano.org/portada/2014/1/22/oracle-ha-introducido-un-bug-en-java-7-update-51que-esta-rom.html
Con la información que das, Beatriz, no se te va a poder ayudar. No llega.
Gracias por responder. El problema lo tengo al intentar abrir una aplicación de la Agencia Tributaria. Tengo descargada la aplicación y al intentar abrirla sale lo que puse en la primera entrada:
java.lang.ExceptionInInitializerError
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.exe4j.runtime.LauncherEngine.launch(Unknown Source)
at com.exe4j.runtime.WinLauncher.main(Unknown Source)
Caused by: java.lang.NullPointerException
at com.aeat.informativas.PlataformaInformativas.<clinit>(Unknown Source)
... 6 more
Esta es la página desde la que me he descargado la aplicación:
http://www.agenciatributaria.es/AEAT.internet/Inicio_es_ES/_Configuracion_/_Acceda_directamente/_A_un_clic_/Descarga_de_programas_de_ayuda/Declaraciones_Informativas/Declaraciones_Informativas.shtml
Soy contable no tengo ni idea de programar.
Utilizo windows server 2008.
Gracias de nuevo.
@beatriz
Acabo de descargar e instalar la aplicación para Windows, desde esa página, y se inicia sin problemas con Windows 8.1 y JavaSE 1.7.0_51 (64 bits)
tengo un problema al ejecutar la aplicacion java ya compilada en jar,,, me dice error al conectar en el puerto local 1527 con el mensaje coneccion refused:connect ....... no me conecta a la base de datos y puse un boton para testear y me tira el error coneccion refused ,,,,, lo raro que para que funcione la aplicacion debo conectarme manualmente desde netbens ,,,SERVICES ,, DATABASE ,,, mi base de datos clik derecho connect y me conecta entonces el programa funciona y el testeo tambien no me da errores ,,,,, ya no se cual es el problema ,,,,, ayuda plis que puede ser
public class ingresodatos {
Connection ingresodatos = null;
public Connection conectar() {
try{
Class.forName("org.apache.derby.jdbc.ClientDriver");
ingresodatos= DriverManager.getConnection("jdbc:derby://localhost:1527/MALLNODO;create=true;user=mallnodo;password=mallnodo");
}catch(ClassNotFoundException | SQLException e){
JOptionPane.showMessageDialog(null, e);
}
return ingresodatos;
}
}
nombre base de datos MALLNODO
usuario mallnodo
password mallnodo