martes, 20 de octubre de 2009

Cloud computing se llama esta filosofía

El concepto o filosofía "Cloud computing" (la computación está en la nube o la nube -metáfora de Internet- es el ordenador) es una idea antigua.

Ya Sun habló (fue su eslogan durante años) de "The network is the computer" y mucho antes Bill Gates predijo... "todo estará conectado a la Red" (claro que él pensaba que a su Red).

Lo que ha ocurrido es que ahora es "medio" posible (no se sabe si la posibilidad es madre de la filosofía o la filosofía madre de la posibilidad):
  1. Queremos acceder desde distintos dispositivos a nuestros aplicativos: móviles, netbooks, tv con tdt, pequeñas video-consolas, etc. Estos dispositivos no tienen capacidad para ejecutar pesadas aplicaciones ni discos duros voluminosos... así que "que todo esté en la Red es una ventaja".
  2. Hoy en día, es más o menos fácil y más o menos barato acceder a la Red, en cualquier sitio, con uno de estos dispositivos.
  3. Queremos socializarnos por la fuerza bruta: queremos tener miles de amigos en nuestro facebook, decir hasta "cuándo nos sacamos un moco" en el twitter y saber qué amigos tenemos a nuestro alrededor desde el móvil (hay un servicio Google que ya nos permite hacer esto). Lo extraño, quizá por esto, es que cada vez estemos más alarmados por la información que se tiene de nosotros y el uso que se hace de ella.
  4. Hay empresas que ya han visto negocio (sobre todo Google y Microsoft) pero que no nos dicen que nos espera a la vuelta de la esquina: primero utilízalo gratis, sin leer las condiciones del contrato, luego te mando publicidad y más tarde te hago pagar un poco por servicios "premium".
Suma el precio del dispositivo, el precio de la conexión (seguro que la pagas dos veces), el precio de la publicidad que te tragas y el precio de los X servicios que vas a contratar en modo "premium"... total "lo comido por lo servido".

De todas formas, la filosofía es imparable (los filósofos sólo tienen que pensar en qué, no en los resultados) así que os paso una lista, ejemplo, de Universidades (no hay ninguna española que yo vea) que utilizan uno o varios de estos servicios:

http://www.edustyle.net/gallery_other.php

viernes, 11 de septiembre de 2009

Intenciones de ORACLE para los clientes SUN

ORACLE ha publicado una declaración, sobre sus intenciones, para los clientes de SUN. Ver:

http://www.oracle.com/features/suncustomers.html

Sólo dice que va a gastar más dinero, de lo que SUN gastaba hasta ahora, en el desarrollo de SPARC y en el desarrollo de Solaris.

Además, dice que, pondrá más especialistas (el doble que SUN) asociados a la venta de hardware y servicios.

Pero, la frase más interesante es la que dice que, aumentará el rendimiento del hardware SUN mediante la integración de software ORACLE en esta plataforma.

Con esta última frase, y no diciendo nada con respecto a Java, JavaFX, Glassfish (SJSAS), Netbeans, MySQL... yo creo que ORACLE deja bastante claro cuáles serán sus intenciones con respecto a estos productos SUN.

miércoles, 22 de julio de 2009

Flex 3.3 y locale es_ES... por fin, Flex 3.3 en español!

Más de un lector me había pedido que crease la localización para la versión 3.3 (este SDK lleva un tiempo ya en el "mercado"). La verdad es que, no era consciente de que nadie la estuviese usando/esperando...

En el siguiente enlace FLEXSDK33-framework-locale-es_ES.zip
os dejo un .zip que podéis descomprimir en el directorio de vuestro Flex SDK 3.3 (primero creáis un directorio "es_ES" dentro del directorio "frameworks/locale" y luego copiáis allí los tres ficheros .swc que os dejo dentro del .zip) y simplemente añadiendo la siguiente opción al compilador "-locale es_ES" tendréis resuelto el asunto... al menos, el asunto español ;-)

También podéis modificar el fichero /frameworks/flex-config.xml para activar esta localización como la localización por defecto de vuestras compilaciones (es sencillo encontrar el lugar).

También podemos activar esta localización en el Flex Builder 3.0.2, que realmente utiliza un SDK que viene dentro del directorio "sdks" donde esté instalado este impresionante entorno de desarrollo.

Os dejo las versiones anteriores de estas "localizaciones" en:

domingo, 7 de junio de 2009

Google ha liberado Page-Speed

Google ha (recientemente) abierto el fuente de una herramienta, que ellos utilizan internamente, para optimizar sitios web. Además de "abrirla", la ponen a nuestra disposición.

Lo que se consigue realmente con ella es mayor velocidad en la carga de las páginas, una vez aplicas las recomendaciones dadas.

No es que la herramienta haga que las páginas se carguen más rápidamente, sino que te da pistas para que diseñes páginas que se cargarán más rápidamente.

Te ayuda en el análisis de tus páginas web, optimización de los css, optimización de los javascript, optimización de las imágenes y otras recomendaciones varias.

La he probado, prefiero comentar las cosas tarde pero probadas, y tengo que decir que satisface mis expectativas. De una forma sencilla, simplemente cargando la página a analizar desde el navegador y activando el análisis, nos informa de lo que podemos hacer (de forma sencilla) para mejorar el rendimiento de la misma.

Se llama "Page Speed" (se puede descargar desde http://code.google.com/intl/es-ES/speed/page-speed) y es un añadido al plugin "Firebug" de "Firefox".

La instalación de "Firebug" debería ser una obligación para todos los desarrolladores de contenido/aplicaciones web.

martes, 12 de mayo de 2009

Exception : Unsupported major.minor version

Estaba ya un poco harto de la excepción "Unsupported major.minor version". Mis condiciones de trabajo hacen que no "despliege" mis aplicaciones Java siempre en la misma máquina, con lo que me encuentro con diferentes entornos en los que es necesario que estas aplicaciones funcionen correctamente. Estos entornos, muchas veces, no son controlados por mí.

Uno de los elementos, de estos entornos, que más me influyen es: la versión de la máquina virtual Java (JVM) que hay instalada en ellos. Si la máquina virtual Java es una revisión menor que la de mi entorno de desarrollo... tendré problemas. Si la máquina virtual Java es una revisión menor que la utilizada por quien compiló las librerías (en formato JAR) que utilizo en mis aplicaciones... tendré problemas.

Pero, ¿cómo sé con qué versión de máquina virtual han sido compiladas el conjunto de clases de mi aplicación? Sé que cada .class tiene unos primeros bytes que me informan de ello, pero, ¿alguién ha desarrollado ya alguna utilidad que lea estos bytes y me haga un sencillo informe con el resultado de su lectura?

Curiosamente, me costó menos desarrollar esta pequeña utilidad que encontrarla en Internet (no fuí capaz de encontrarla, realmente).

La he llamado "CheckJvmVersion" y la "dono" ;-)
import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;

public class CheckJvmVersion {

public static void main(String[] argv) {
JarFile[] jar = null;
String dir = "";
if (argv.length <= 1) {
if (argv.length == 1) {
if (argv[0].endsWith(".jar")) {
jar = new JarFile[1];
try {
jar[0] = new JarFile(argv[0]);
} catch (IOException e) {
System.out.println("No se ha podido leer el fichero jar: " + argv[0]);
System.exit(-1);
}
} else {
dir = argv[0];
int j = 0;
String[] ljar = new File(dir).list();
jar = new JarFile[ljar.length];
for (int i = 0; i < ljar.length; i++) {
if (ljar[i].endsWith(".jar")) {
try {
jar[j++] = new JarFile(argv[0] + System.getProperty("file.separator") + ljar[i]);
} catch (IOException e) {
System.out.println("No se ha podido leer el fichero jar: " + ljar[i]);
System.exit(-1);
}
}
}
}
} else {
dir = ".";
int j = 0;
String[] ljar = new File(dir).list();
jar = new JarFile[ljar.length];
for (int i = 0; i < ljar.length; i++) {
if (ljar[i].endsWith(".jar")) {
try {
jar[j++] = new JarFile(ljar[i]);
} catch (IOException e) {
System.out.println("No se ha podido leer el fichero jar: " + ljar[i]);
System.exit(-1);
}
}
}
}
} else System.out.println("Uso: CheckJvmVersion [<jar-file>]");
if (jar != null && jar.length > 0) {
try {
for (int i = 0; i < jar.length; i++) {
if (jar[i] != null) {
System.out.println("Leyendo el fichero jar [" + jar[i].getName() + "]: ");
List<String> l = new ArrayList<String>();
for (Enumeration e = jar[i].entries(); e.hasMoreElements();) {
ZipEntry ze = (ZipEntry) e.nextElement();
InputStream is = jar[i].getInputStream(ze);
DataInputStream dis = new DataInputStream(is);
try {
int magic = dis.readInt();
if(magic == 0xcafebabe) {
int minor = dis.readUnsignedShort();
int major = dis.readUnsignedShort();
String version = "";
if ((major + "." + minor).equals("45.3")) version = "1.0";
else if ((major + "." + minor).equals("45.3")) version = "1.1";
else if ((major + "." + minor).equals("46.0")) version = "1.2";
else if ((major + "." + minor).equals("47.0")) version = "1.3";
else if ((major + "." + minor).equals("48.0")) version = "1.4";
else if ((major + "." + minor).equals("49.0")) version = "1.5";
else if ((major + "." + minor).equals("50.0")) version = "1.6";
else version = "?";
if (!l.contains(version)) l.add(version);
}
} catch (IOException ie) {}
dis.close();
}
for (Iterator iter = l.iterator(); iter.hasNext();) System.out.println("JVM-" + iter.next() + " " + (isEmpty(dir) ? jar[i].getName() : replace(replace(jar[i].getName(), dir, "", -1), System.getProperty("file.separator"), "", -1)));
}
}
} catch (IOException e) {
System.out.println(e.getMessage());
System.exit(-1);
}
}
}

private static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}

//@param max - maximum number of values to replace, or <code>-1</code> if no maximum
private static String replace(String text, String searchString, String replacement, int max) {
if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) return text;
int start = 0;
int end = text.indexOf(searchString, start);
if (end == -1) return text;
int replLength = searchString.length();
int increase = replacement.length() - replLength;
increase = (increase < 0 ? 0 : increase);
increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
StringBuffer buf = new StringBuffer(text.length() + increase);
while (end != -1) {
buf.append(text.substring(start, end)).append(replacement);
start = end + replLength;
if (--max == 0) break;
end = text.indexOf(searchString, start);
}
buf.append(text.substring(start));
return buf.toString();
}

}
Recibe un único argumento (que puede ser un fichero JAR o un directorio) y te dice las diferentes versiones de JVM utilizadas para compilar las clases que hay empaquetadas en las librerías (en formato JAR) localizadas.

En caso de no pasarle ningún argumento, busca dentro del directorio "local" desde el que lanzas el comando.