Minientrada

Error increible de Java con Windows 7

En el mundillo Java los fallos a veces pasan, y a veces pasan sin ser culpa de Java. Y esas veces hay que celebrarlo, porque son las menos.

Coincidiendo con la migración de Windows XP a Windows 7 en los entornos de usuario, una de nuestras aplicaciones java realizada con tecnología RCP (Rich Client Platform), decidió sin previo aviso que no quería arrancar. Los síntomas eran claros, al pinchar sobre el ejecutable, en nuestra recién estrenada instalación de Windows 7, la aplicación comenzaba el arranque y se cerraba sin llegar a mostrar la ventana inicial. Lo que nos extrañaba es que la misma versión de la aplicación en Windows XP funcionara correctamente.

El error.

En una aplicación cliente, relativamente «compleja», como es ésta; con accesos a base de datos mediante JDBC, con clientes EJB que se conectan a EJBs publicados en un servidor J2EE, e informes generados con BIRT, muchas variables podían influir en el mal funcionamiento. Lo que no sospechaba, ni por asomo, es que algo tan tonto como el tipo de letra pudiera influir en una aplicación java, sin embargo la ejecución de la aplicación RCP era clara al respecto ya que las trazas dejaban el siguiente rastro:

java.util.MissingResourceException: Wrong font data format. Value is: «MS Sans Serif-negrita-12 «

at org.eclipse.jface.resource.FontRegistry.makeFontData(FontRegistry.java:767)

at org.eclipse.jface.resource.FontRegistry.readResourceBundle(FontRegistry.java:860)

at org.eclipse.jface.resource.FontRegistry.readResourceBundle(FontRegistry.java:342)

at org.eclipse.jface.resource.FontRegistry.(FontRegistry.java:286)

at org.eclipse.jface.resource.FontRegistry.(FontRegistry.java:308)

at org.eclipse.jface.resource.JFaceResources.getFontRegistry(JFaceResources.java:342)

 

Windows 7 y los DPI de las fuentes.

 

Los monitores planos (LCD, TFT…) tienen un tamaño fijo de pixel o «resolución» con la que muestran los elementos en pantalla. Cuando un usuario, desde el sistema operativo, cambia a una resolución menor para ver más grande el tamaño de la letra, el monitor combina y ajusta los pixeles de tamaño fijo para conseguir la nueva resolución. Este proceso degrada la calidad de la imagen vista en pantalla haciendo que todo, no solo el texto, se vea peor.

Para evitar esto, Windows permite el aumento de tamaño de las fuentes y de las ventanas manteniendo la resolución nativa del monitor. Gracias a este método se obtienen imágenes más nítidas al poder utilizar el tamaño original de los píxeles para componerlas.

En Windows 7, para hacer que la resolución del sistema operativo corresponda con la resolución nativa de la pantalla y en ciertas resoluciones altas, para que las letras se muestren a un tamaño aceptable establece por defecto la configuración 120 DPI (dots per inch) de las fuentes. La configuración normal de las fuentes es 96 DPI. Esto implica que en 120DPI se usa un 125% de DPI más grande que lo habitual.

Si el usuario vuelve a 96 DPI, es decir, vuelve al tamaño de fuente normal, las fuentes TrueType, que permiten escalado, se ajustan automáticamente. Sin embargo, las fuentes basadas en bitmaps (imágenes), como MS Sans Serif, deben utilizar el fichero de fuentes adecuado a la resolución. Por tanto, en la instalación de Windows 7 debería existirá un fichero de fuentes para 96DPI y otro para 120DPI.

Sin embargo, si a la hora de instalar Windows 7 la resolución de pantalla es una resolución alta (por ejemplo, 1900×1200) se establece las fuentes por defecto a 120 DPI y no se instalan las fuentes 96 DPI ya que se considera que no se van a utilizar.

Por tanto, si se utiliza el tamaño 96DPI, se encontrará con que para ciertos tipos de letra los ficheros no existen, y como en nuestro caso, dará un error. La aplicación RCP utiliza un sistema de ventanas que lo independiza del sistema operativo. Este sistema de ventanas es conocido como JFace y está basado en SWT (Standar Widget Tookit). Este sistema utiliza las fuentes normales de 96DPI y todo junto provoca el fallo.

Las soluciones. Considerando las particularidades de nuestro entorno se puede optar por varias soluciones. A continuación se muestran en orden de prioridad:

 

  • Incluir las fuentes 96DPI en la instalación de Windows 7.
  • Cambiar el tipo de fuente que utiliza la aplicación RCP para que use una fuente TrueType (que no dan problemas en el escalado).
  • Parchear Windows 7 para que utilice las fuentes 120DPI cuando de fuentes bitmap se trata.

 

Incluir las fuentes 96DPI en la instalacion de Windows 7 Las fuentes en Windows 7 se instalan de diferentes maneras. El método más sencillo es descargar la fuente, descomprimirla, hacer doble click en el archivo .FON y finalmente hacer click en el botón «Instalar».

Las fuentes se pueden descargar desde los siguentes links:

Cambiar el tipo de fuente de la aplicación RCP

La aplicación RCP utiliza jFace para la implementación de la interfaz de usuario. Es en esta interfaz donde se configuran los tipos de fuente que se utilizan en la aplicación. La configuración se realiza en el fichero jfacefonts_es.properties que se encuentra en la ruta \\plugins\org.eclipse.jface.nl_es_0.2.0.v20080615043401\org\eclipse\jface\resource

Estos ficheros de propiedes contienen el tipo de fuentes que se utilizan en diferentes tipos de controles pertenecientes a la interfaz de usuario. Es en este fichero donde estará especificado el tipo de letra Sans Serif que tendremos que sustituir por un tipo de letra TrueType.

En nuestro caso el cambio realizado es el siguiente:

org.eclipse.jface.bannerfont.0=Tahoma-bold-8

org.eclipse.jface.headerfont.0=Tahoma-bold-12

Parchear Windows 7 para que utilice las fuentes 120DPI.

Parchear Windows 7 implica tocar el registro. Esta opción, aunque válida, no es recomendable pues lo que se hace es trampear el sistema. La trampa consiste en que para determinados casos, en vez de utilizar el fichero de fuentes que debería utilizarse (96DPI), que es el correcto pero no está instalado, se utilice el fichero de fuentes incorrecto pero existente en el sistema (el de 120DPI).

Aún así, dejo aquí la solución por si alguien tiene prisa en sacar adelante su programa y no tiene tiempo de aplicar las soluciones anteriormente recomendadas.

Lo primero que hay que hacer es acceder al registro de Windows 7 utilizando la herramienta regedit.

Una vez dentro del editor del registro se busca la clave MS Sans Serif 8,10,12,14,18,24 que se encuentra en la ruta HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts\.

El truco es cambiar el valor existente en esa entrada, SSERIFF.FON por el valor SSERIFE.FON

is set to SSERIFF.FON on a system which started at 125% DPI. The setting is set to SSERIFE.FON on a system which started at 100% DPI. Notice that one character of the file name changes from F to E.

The actual font files used might be different on Windows systems for other languages or code pages. See the table below for the file names:

While we are fixing the MS Sans Serif font, we can also fix the MS Serif and Courier fonts. These are the Registry settings MS Serif 8,10,12,14,18,24 and Courier 10,12,15 values in the same registry key. See the table below for the file names:

To fix the system you need to change the settings to new file names (changing the appropriate letter from F to E) and reboot.

Note: The registry changes do not take effect until the system has been restarted. You MUST reboot after making the registry changes.

Below are the contents of Font Fix.reg file to make the changes for an English system:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts] «MS Sans Serif 8,10,12,14,18,24″=»SSERIFE.FON» «MS Serif 8,10,12,14,18,24″=»SERIFE.FON» «Courier 10,12,15″=»COURE.FON»

Links. Windows 7, bitmap fonts and Microsoft Dynamics GP

Deja un comentario