18 de septiembre de 2013

Sybase, Unicode, y Java JDBC

Hoy necesité insertar un texto similar al siguiente en una base de datos Sybase ASE 15.x desde Java usando JDBC:

aaa aáa bbb’ aaa

El texto tenía tanto acentos como otros caracteres usuales en español, así como algunos otros no tan usuales. En la cadena de ejemplo, el noveno caracter no es un apóstrofo (RAE), sino comillas simples de apertura (RAE). Además, al final los puntos supensivos (RAE) no son tres caracter de punto (RAE), sino un solo caracter. Estos caracteres están definidos en el estándar Unicode.

Al intentar insertarla, el driver JDBC JConnect para Sybase lanzaba una excepción, diciendo que se había intentado insertar un registro con una columna con un valor de nulo. El problema no era que estuviera vacía la cadena, sino tenía que ver con la codificación de los caracteres.

Encontré dos soluciones:

1. Especificar el código de caracteres

Al conectarse desde Java usando JDBC, especificar la codificación que se usará [1][2].
Properties props = new Properties();
props.put("charset", "utf8");
Connection conn = DriverManager.getConnection(JDBC_URL, props);

Esto quizá implicará que se deberá cuidar cuáles funciones de texto en Sybase se ocupan. En Java, JDBC se encarga de hacer la conversión transparente.

2. Eliminar los caracteres inválidos

Hacer que Java no envíe caracteres que sean inválidos en la codificación que utiliza el servidor Sybase. En mi caso, estaba usando la codificación ISO-8859-1, así que en Java yo tenia que quitar o convertir los caracteres que no tenían representación en esa codificación. Para lo que yo necesitaba, no me importaba sustituirlos todos por algún caracter que no fuera una letra.

// texto es un String con la cadena "aaa aáa ‘bbb’ aaa…"
byte[] bytes = texto.getBytes(StandardCharsets.ISO_8859_1);
texto = new String(bytes, StandardCharsets.ISO_8859_1);

Esto provoca que los caracteres que no se puedan convertir se sustituyan con un caracter de cierre interrogación.

aaa aáa ?bbb? aaa?

Las letras acentuadas se convervan, pues la codificación ISO-8859-1 sí las contienen.

3. Una solución que no es solución

En Sybase se puede especificar que la columna almacenará una cadena que estará codificada usando Unicode [3][4].
CREATE TABLE Tabla (
   Texto UNIVARCHAR(50)
)
Esto hace que Sybase ocupe dos bytes para almacenar cada caracter. Sin embargo, a mí no me funcionó esta solución.

Finalmente

Existen otros detalles de este asunto: Java utiliza internamente Unicode, y específicamente UTF-16 para codificar las cadenas de caracteres, y que bajo esa codificación existen caracteres que ocupan 4 bytes, lo cual implica que en JDBC y Sybase su manejo deberá ser un poco diferente. Sin embargo, eso no lo necesito por hoy.

Referencias:

[1]
https://www.java.net//node/688046
[2]
http://www.sybase.com/detail?id=1009812#MARKER-9-243
[3]
http://es.wikipedia.org/wiki/ISO_8859-1
[4]
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.ase_15.0.sag1/html/sag1/sag1417.htm

13 de septiembre de 2013

Cómo exportar e importar datos en Java DB (Apache Derby)


Tengo una base que accedo de forma incrustada (embedded) en una aplicación Java 7. La base está hecha con Java DB (Apache Derby). Necesité respaldar y luego recuperar el respaldo de los datos. Para ello usé los siguientes comandos desde NetBeans.

Para exportar:

CALL SYSCS_UTIL.SYSCS_EXPORT_TABLE (null,'TABLA','ARCHIVO',null,null,null);

Para importar:

CALL SYSCS_UTIL.SYSCS_IMPORT_TABLE (null,'TABLA','ARCHIVO',null,null,null,0);

Más información: http://docs.oracle.com/javadb/10.4.1.3/tools/rtoolsimport91458.html

18 de junio de 2013

Tabla con esquinas redondeadas y que tenga una sombra incrustada dentro de ella

Necesité hacer una tabla HTML que se viera así:


Para esto, usé CSS:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <title>Table with inset shadow and round corners</title>
 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
 <style>
  table.tabla {
   width: 500px;
   margin: 0 auto; /* centrado */

   background: white;

   /* sombra interior */
   /* Ver http://css-tricks.com/snippets/css/css-box-shadow/ */
   box-shadow: inset 1px 1px 1px 0px #999999;
   
   /* esquinas redondeadas */
   /* Ver http://border-radius.com/ */
   border-radius: 10px;
  }
  table.tabla > tbody > tr:first-child > td:first-child { /* celda superior izquierda */
   border-top-left-radius: 10px;
  }
  table.tabla > tbody > tr > td:first-child { /* celdas de la primera columna  */
   border-left: 1px solid #999999;
  }
  table.tabla > tbody > tr:last-child > td:first-child { /* celda inferior izquierda */
   border-bottom-left-radius: 10px;
  }
  table.tabla > tbody > tr:last-child > td:last-child { /* celda inferior derecha */
   border-bottom-right-radius: 10px;
  }
  table.tabla > tbody > tr:nth-child(even) { /* celdas de los renglones pares */
   background: #e7e7e7;
  }
 </style>
</head>
<body>
 <table cellpadding=0 cellspacing=0 class="tabla">
  <tr>
   <td>abc</td>
   <td><table><tr><td>123</td><td>456</td></tr><tr><td>123</td><td>456</td></tr></table></td>
   <td>ghi</td>
  </tr>
  <tr>
   <td>abc</td>
   <td><table><tr><td>123</td><td>456</td></tr><tr><td>123</td><td>456</td></tr></table></td>
   <td>ghi</td>
  </tr>
  <tr>
   <td>abc</td>
   <td><table><tr><td>123</td><td>456</td></tr></table></td>
   <td>ghi</td>
  </tr>
  <tr>
   <td>abc</td>
   <td><table><tr><td>123</td><td>456</td></tr></table></td>
   <td>ghi</td>
  </tr>
  <tr>
   <td>abc</td>
   <td><table><tr><td>123</td><td>456</td></tr></table></td>
   <td>ghi</td>
  </tr>
 </table>
</body>
He aquí este código ejecutándose en el navegador:

abc
123456
123456
ghi
abc
123456
123456
ghi
abc
123456
ghi
abc
123456
ghi
abc
123456
ghi

27 de febrero de 2013

Parte de JavaFX para iOS y Android será como Open Source

Richard Bair anunció que Oracle liberará como Open Source la implementación de JavaFX para iOS y Android de JavaFX en un par de meses. Sin embargo, en una actualización matizó que sólo se liberará el sistema gráfico y de ventanas (Prism y Glass), para que la comunidad pueda experimentar. Para saber más de Prism y Glass, consultar JavaFX Architecture and Framework.

6 de febrero de 2013

Maven: Cómo mostrar la versión en la aplicación web

Si necesitas mostrar el número de versión del sistema en una aplicación web construída con Maven, puedes hacer que Maven la escriba en un archivo al momento de construir el WAR, y luego puedes usar una JSP para mostrar el contenido de dicho archivo. Para ello, necesitas configurar el filtrado de los recursos de la aplicación web en el maven-war-plugin. Un ejemplo:

Archivo src/main/webapp/version.txt:
${project.version}

Archivo src/main/webapp/index.jsp:
Versión: 

Archivo pom.xml:
<plugin>
  <groupid>org.apache.maven.plugins</groupid>
  <artifactid>maven-war-plugin</artifactid>
  <version>2.3</version>
  <configuration>
    <webresources>
      <resource>
        <!-- sustituye propiedades de Maven en el contenido de los archivos -->
        <filtering>true</filtering>
        <directory>src/main/webapp</directory>
        <includes>
          <include>**/version.txt</include>
        </includes>
      </resource>
    </webresources>
  </configuration>
</plugin>

30 de enero de 2013

Oracle: 'Debemos arreglar la seguridad en Java'

Imagen por :-Derek
'Debemos arreglar la seguridad en Java', reconocen dos empleados de alto nivel de Oracle [1].

Milton Smith, Lider de Seguridad de Java, y Donald Smith, Director de Desarrollo de Producto en OpenJDK, tuvieron una conferencia telefónica con varios líderes de los grupos de usuarios de Java (JUGs) [2].

Cuando se les cuestionó porqué el instalador de Java también instala la barra de herramientas de Internet del sitio Ask.com, comentaron: 'Esto es algo que Sun inició [...] No puedo discutir el asunto.'

También, ante la pregunta si Java se podría actualizar automáticamente como ya lo hace el navegador Google Chrome y el plugin de Adobe Flash, respondieron: "No hay planes [...] podría ser".

Parafraseando la cancion de Carly Rae Jepsen: 'Hey, Java's broken, and this is crazy, but here’s my bytecode, so fix it, maybe?'

[1] Referencia: JAXenter.
[2] Publicacón de Oracle con el audio: Oracle Speaks up on Java Security.