
Soy César Olea, programador desktop, Web y de sistemas embebidos. Originario de Ciudad Obregón, Sonora, México.
Actualmente he terminado mi maestría en Ciencias de la Computación y me dedico dar mantenimiento, administrar y programar el sitio aVeralCine.com, escribir en Geek&Roll, el Web-comic geeksofacto y distintos proyectos de programación. Mi trabajo oficial (o sea, el que paga las cuentas) es en Tiempo Development como Senior Software Engineer. Si eres un buen programador, hablas Inglés y te interesa trabajar en una empresa con excelente ambiente laboral y projectos interesantes, estamos buscando gente como tu.
Para contactarme puedes ![]()
enviarme un mensaje si estoy conectado a gTalk.

Geek&Roll es el blog donde escribo sobre programación, cracking, cultura geek, Software Libre, Internet, y más. En conjunto con Axel y Rafyta mantenemos un blog de contenido (casi todo) original.
Anoche, después de estar todo el día sin leer feeds (por mi berrinche contra los lectores actuales, pero ese es otro tema), me puse a actualizarme y me encontré con el nuevo gadget de apple: el Magic Trackpad.
Mi primera reacción fué pensar que era broma, es decir… ¿Un trackpad? ¿De verdad? pero al parecer la cosa iba en serio. Tan en serio que un bato en TechChrunch dice que el mouse ha muerto.
¿De verdad?
En general, los trackpad apestan. Son cansados y en la mayoria de los casos diseñados nada ergonómicamente, por lo que la industria de los micro-mouses tamaño frijol tuvo un boom a la par que la de las laptops (gracias a que por algún motivo la gente siente que para su laptop no debe usar un mouse tamaño normal).
El trackpad de apple (el nuevo o el de las Macbook Pro) es otra cosa. Es multitouch y acepta muchos gestures, por lo que la mayoria de las cosas las puedes hacer cómodamente sin andar cargando un mouse. Eso, claro para el uso casual.
En el uso profesional la cosa cambia un poco. Ahí si no creo que ningún trackpad la vaya a pegar, por lo menos no como los conocemos ahora. Si no me creen, intenten trabajar 8 horas en photoshop solamente con un trackpad, incluso con el de Apple, y no querer asesinar a alguien al final. ¿Ah verdad?
El mouse se inventó hace casi 50 años, pero sigue funcionando. Incluso el Magic Mouse (también de apple) es un mouse con una superficie multitouch, lo que me parece que reúne lo mejor de ambos mundos.
No es que sea aferrado. Yo estoy convencido de que el mouse es arcáico, y necesitamos nuevas maneras de interactuar con la máquina. En el área de la computación casual (de sofá que le dicen) hay propuestas ganadoras como la iPad, pero en el área especializada no las hay. Hay propuestas interesantes, como Photoshopear directamente en la pantalla con un stylus, pero aún así estas no pasan (hasta el momento) de curiosidades.
El mouse, viejito y todo, seguirá pateando traseros por un tiempo.
Ya que andamos en eso de hacer que Eclipse se vea bien en GNU/Linux, ahora le toca el turno a los iconos tanto de Eclipse como de Netbeans.
Normalmente tengo los dos IDEs instalados, y sus iconos de aplicación se ven pésimo a resoluciones altas como las que maneja Docky. Afortunadamente la solución es simple, reemplazarlos por unos de mayor resolución.
Para Eclipse, hay un excelente icono en formato SVG que sigue las especificaciones del proyecto Tango. Este icono lo encuentran en Gnome-Look.org.
Para Netbeans es más interesante, se puede usar el mismo icono que se usa en OSX. Resulta que cuando instalas Netbeans en OSX el icono se ve muy bien, pero usuarios de otros sistemas operativos nos tenemos que conformar con una versión de menor resolución. Afortunadamente podemos tomar el icono de OSX en formato icns y usar icns2png (disponible en tu distro favorita) para convertirlo a PNG. Ahora que si se quieren ahorrar esos pasos, solo click derecho y guardar como. Gracias este blog por el tip.
Blizzard puso Starcraft 2 completo para descarga desde su sitio Battle.net. ¿La única condición? no lo puedes jugar sino hasta el 27 de Julio, y claro, necesitas tener una llave válida para poder instalarlo, la cual adquieres al comprar el juego. Claro que esto lo aprovecharon un grupo de personas para intentar crackear la protección del instalador y del juego, permitiendo instalar el juego antes del 27 de Julio.
Por la información del foro, al parecer son dos instaladores. El primero se encarga de obtener, vía Internet, digamos el permiso para desencriptar un segundo instalador. Este segundo instalador encriptado se encarga de instalar el juego.
Hasta ahora se han tomado varias aproximaciones, desde simplemente modificar archivos de configuración del instalador y jugar con la configuración de hosts del sistema operativo, hasta analizar a listado muerto el instalador y ver en donde se hace el chequeo para la desencriptación del juego.
Uno de los últimos mensajes del foro dicen:
Ok, creo que lo tengo. En 004CDEF hay un chequeo booleano que verifica si la llave de autentificación es buena. Si lo es, se mueve al EULA y lo que le sigue. Sin embargo si es falsa, se mueve a 0044D012 lo que significa que el archivo nunca se desencripta. Esto significa que necesitamos modificar validdecryptionkey para que siempre regrese TRUE. Después de analizar esta llamada, hay dos chequeos: el chequeo de la fecha con una llave válida, y si la llave es inválida se salta la desencriptación.
¿Será un simple chequeo tipo chico bueno, chico malo? No lo se, pero me es muy interesante ver si logran crackear la protección antes de la fecha límite. Yo, como muchos otros, planeamos comprar el juego retail en cuanto salga pero no por eso me deja de parecer un reto excelente, además que no estaría mal poder jugar antes del 27 de Julio :)
Este post se irá actualizando con más información a como se vaya obteniendo.
Update: Aparentemente el instalador usa Salsa20 para la encriptación.
Update: Después de editar el ejecutable, han logrado saltarse el primer mensaje de error en donde falla al abrir el EULA. Ahora ya abre la ventana y muestra el EULA y procede a la instalación sin necesidad de editar XML alguno. Aún así se necesita desencriptar.
Update: Bueno al parecer alguien confirma mis sospechas (y era lo más lógico, Blizzard no son novatos en esto de la distribución online): La llave que pide el instalador, es necesaria para desencriptar los archivos. Aún modificando el instalador para que acepte cualquier llave (la simple modificación del salto propuesta por muchos), la llave correcta es necesaria para la rutina de desencriptado. Sin desencriptado no hay gloria.
Difícilmente alguien va a poder crackear esa rutina de desencriptado en tan poco tiempo. La única manera sería que la llave en si esté dentro del binario del juego algo que ya sabemos que no es así (Blizzard proporcionará la llave el 27 de Julio por Internet).
Por lo pronto la gente lo sigue intentando, pero cada vez se ve mas lejano.
Tradicionalmente Ubuntu no le ha dado la prioridad que debería a eclipse, mi IDE de preferencia a la hora de programar. La diferencia es más notable si, como yo, constantemente te encuentras cambiando entre sistemas operativos.
Notese como en Ubunto en el mismo espacio se muestra mucho menos área útil, ya que los botones y la interfaz en general ocupan más espacio del que deberían. El problema real está en GTK y sus limitantes, no en eclipse o SWT (el toolkit gráfico utilizado por eclipse). Para arreglarlo, al lanzar eclipse es posible especificarle a gnome que use un tema diferente, modificado especialmente para que eclipse use mejor el espacio disponible.
Lo primero es asegurarnos que las fuentes liberation-fonts se encuentran instaladas (en mi caso ya estaban instaladas):
sudo aptitude install ttf-liberation
Después descargamos este zip y lo descomprimimos en el directorio raíz donde se encuentra eclipse. El zip contiene dos archivos:
Ahora hacemos el shell script ejecutable:
chmod 755 ec
Y finalmente ejecutamos ec en vez de eclipse:
./ec
Eclipse en Ubuntu después de las modificaciones

El resultado es un eclipse con un espacios mucho más normales en las tabs y los iconos de la barra de herramientas, aprovechando mejor el espacio y mejorando la experiencia de usar este IDE en Ubuntu.
Si se quiere modificar la entrada del menú para lanzar eclipse, lo cual a su vez tiene el efecto de permitirnos de lanzar eclipse con el nuevo tema desde Gnome Do, o Docky por ejemplo, lo que se tiene hacer es editar el script ec y dejarlo de la siguiente manera:
#!/bin/sh GTK2_RC_FILES=/home/usuario/eclipse/gtkrc-sar /home/usuario/eclipse/eclipse
Lo que estamos haciendo es utilizar rutas absolutas en vez de relativas. En este caso estoy suponiendo que eclipse se encuentra instalado en /home/usuario/eclipse/ hay que editar el archivo para que concuerde con el sistema de cada quien.
Con esta modificación al script, en el menú principal podemos agregar una entrada para eclipse (si no es que ya tenemos una) poniendo como comando lo siguiente:
sh /home/usuario/eclipse/ec
Ahora sí, tanto Gnome Do como un lanzador de Docky creado a partir del menú principal deberán de iniciar eclipse con el nuevo tema.
Gracias a Sarath Chandra por el post original.
Cuando de reproducir música se trata, GNU/Linux tiene opciones para todos: amarok, banshee, BMP, exaile, rhythmbox, xmms, et al. En lo personal, cuando quiero escuchar mi colección de mp3s por tiempo indefinido uso rhythmbox, que me permite mantener mi colección, editar los tags ID3, buscar, enviar a last.fm, descargar portadas de CDs, descargar la letra, entre muchas otras cosas. Por lo general hay un player para todos, algunos prefieren la navaja suiza que es amarok, o el me-parezco-a-winamp-retro xmms.
Aún con todas las opciones que existen, hay un caso de uso que no consigo cubrir. Hay veces en las que quiero escuchar uno o varios mp3 pero sin agregarlos a una biblioteca, ni a una playlist ni nada por el estilo. Sólo doble click y que comience a escucharse. Lo que necesito es un player que:
Por default gnome incluye rhythmbox, pero para poder escuchar algo tienes que agregarlo a tu biblioteca o a la cola. También esta el Movie Player que se incluye con gnome y puede reproducir mp3, pero no tiene soporte para last.fm (que yo sepa. Sólo me interesa el scrobbler, es decir enviar el track a mi cuenta en last.fm)
Los dos players que investigué fueron VLC y Exaile, y estos fueron mis resultados:
VLC
VLC se integra bastante bien al escritorio gnome, excepto por su icono del system tray que se ve muy feo en Ubuntu 10.04. Además no tiene caso tenerlo ahí para reproducir unos cuantos mp3s, así que hay que deshabilitarlo utilizando el switch –no-qt-system-tray. Para hacer esto, abrir el programa Main Menu y en la sección de Sonido y Video, seleccionar VLC media player, click en Propiedades y en el comando utilizar vlc %U –no-qt-system-tray
Una vez hecho lo anterior, lo que sigue es habilitar el scrobbler. Para esto los redirijo a este sitio que lo explica con fotitos y toda la cosa. Hay que ir directamente a la sección que dice Enable Last.fm Scrobbling Option In VLC Media Player. Con la versión de VLC que viene en Ubuntu, no es necesario tener el cliente de last.fm abierto para que VLC pueda hacer uso del scrobbler.
Hablando del scrobbler, el soporte que tiene en VLC podría ser mejor. VLC reporta el track sólo hasta que haya terminado de reproducirse, y no reporta el estado de “Now playing” como lo hacen otros (rhythmbox por ejemplo) pero cumple con lo básico.
VLC se abre en pocos segundos, el soporte para distintos formatos es impresionante, y otro bonus es que no depende de librerías presentes en el sistema operativo, sino que hace uso de sus propios codecs. También reproduce video, y aunque uno de mis requerimientos era que de preferencia se limitara a música, VLC es mi reproductor de video por default por lo que ya estaba instalado en mi sistema. Además es multiplataforma. VLC rocks!
Exaile
Exaile es un player específicamente para gnome con una interfaz GTK+. Se integra perfectamente al escritorio gnome, con soporte para descarga de portadas, notificaciones y OSD entre otras cosas. Sin embargo todas estas cosas salen sobrando en este caso.
De primera instancia, hay que configurar algunas opciones de exaile para que funcione como lo necesitamos. Afortunadamente todo lo podemos encontrar en el diálogo de preferencias, que es mucho más simple que el de VLC ya que exaile se encarga sólo del audio y de nada mas (un plus en este caso). Las opciones que cambio son:
El soporte del scrobbler en exaile es mejor que el de VLC, además de contar con una opción importante: al presionar Ctrl + B, se deshabilita el scrobbler lo cual es muy útil cuando vamos a reproducir algo que no queremos que se envíe a last.fm como por ejemplo un podcast o un chiste de polo polo.
Exaile también abre en pocos segundos y cumple con el requerimiento de dedicarse a sólo audio. Su soporte de last.fm es mejor que el de VLC y tiene el plus de poder habilitarse y deshabilitarse fácilmente. También exaile se integra mejor con el escritorio gnome.
Veredicto
Lo único que no me gusta de exaile es que no puedo reducir su interfaz a lo mínimo necesario, cosa que en VLC es muy sencillo. Si pudiera lograr lo anterior con exaile, sería mi reproductor elegido pero por esta razón me quedo con VLC.
¿Tienen consejos sobre otros reproductores que debería de probar?
Una de las cosas que me agrada de Windows 7 es su galería de temas de escritorio, los cuales ahora incluyen una pequeña pero agradable funcionalidad que permite estar cambiando el fondo de pantalla cada determinado tiempo. Algunos temas incluyen fondos de pantalla de alta resolución con imágenes muy adecuadas para este propósito.
Por fortuna podemos utilizar esos mismos fondos de pantalla, obtenidos directamente de los temas de Windows 7, en nuestro escritorio Gnome además de rotarlos de la misma manera. Para eso vamos a utilizar lo siguiente:
Instrucciones:
sudo aptitude install p7zip-full p7zip-rar p7zip
7za e Mexico.rar -o Mexico/
Lo que nos debe crear una nueva carpeta llamada Mexico con las imágenes de fondo dentro y un archivo Mexico.theme que no vamos a utilizar.
Es importante mencionar que solamente estamos haciendo uso de los fondos de pantalla, y no sonidos, colores u otros recursos del tema. Por último, una imagen de mi escritorio.
Desde que Google mostró al mundo su port de Quake 2 a JavaScript usando GWT, no me podía sacar una pregunta de la cabeza: ¿Cómo hacen para cargar los recursos (como por ejemplo los modelos de los jugadores, o los niveles) desde el servidor al cliente, para su uso por el motor del juego en JavaScrip? ¿Es posible obtener archivos binarios del servidor, guardarlos en el sistema de archivos local, y ejecutarlos finalmente por una aplicación en JavaScript? La respuesta obviamente era sí, pero no sabía cómo.
Pero una consulta al código fuente del proyecto quake2-gwt aclaró las dudas. El secreto es sobreescribir un tipo MIME, lo que le permite al objeto XMLHttpRequest recibir respuestas binarias en vez de texto, para lo cual es más comúnmente utilizado.
function load_binary_resource(url) {
var req = new XMLHttpRequest();
req.open('GET', url, false);
//XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
return req.responseText;
}
En GWT necesitamos hacer uso de una funcion JavaScript nativa (JSNI) para lograr lo mismo:
private native void overrideMimeType(XMLHttpRequest req, String mimeType) /*-{
req.overrideMimeType(mimeType);
}-*/;
Y finalmente crear un objeto XMLHttpRequest, hacer la petición y procesar los datos binarios en el cliente:
XMLHttpRequest req = XMLHttpRequest.create();
overrideMimeType(req, "text/plain; charset=x-user-defined");
req.setOnReadyStateChange(new ReadyStateChangeHandler(){
//procesar la respuesta binaria
});
req.open("GET", "archivo.binario");
req.send();
Para convertir la respuesta en un InputStream, en este caso utilizando GWT y clases de emulación io y nio que tomé prestadas del proyecto quake2-gwt:
response = xhr.getResponseText(); byte[] responseBytes = new byte[sbb.stringToByteBuffer(response).remaining()]; InputStream inputStream = new ByteArrayInputStream(responseBytes);
En este punto pueden usar el InputStream como lo harían en un programa Java tradicional, por ejemplo si cargaron los bytes de una imagen, pueden aplicarle filtros a-la-photoshop, en tiempo real, en el cliente, sin necesidad de procesamiento en el servidor mas allá de descargar la imagen.
En el pasado, cuando comprabas una computadora con Windows preinstalado, normalmente se incluía un disco de recuperación con el cual podías reinstalar el sistema operativo de manera desatendida, dejándolo como de fábrica. Sin embargo, en años recientes esta práctica es cada vez menos común, reemplazando el disco de recuperación por una partición “especial” que contiene la imagen de recuperación más el software necesario para arrancar desde la partición y reinstalar la imagen.
Este es el caso de las computadoras HP. Al iniciar, el BIOS te presenta con la oportunidad de presionar una tecla (F11 en el caso de la imagen) para arrancar la partición de recuperación. El problema es que cualquier modificación del Master Boot Record (MBR) elimina la posibilidad de arrancar la partición de recuperación presionando F11. El MBR puede ser modificado por actualizar el mismo Windows (por ejemplo si tu PC la compraste con Vista y actualizas a Win7 o desactualizas a WinXP), o por instalar otros sistemas operativos como GNU/Linux o OS X.
Después de un largo proceso a prueba y error (los detalles más adelante), descubrí que es posible arrancar la partición de recuperación utilizando GRUB. Este programa es un gestor de arranque muy popular en GNU/Linux, es Free Libre Open Source Software y es utilizado en muchas distribuciones GNU/Linux, como por ejemplo Ubuntu.
Si necesitas restaurar tu sistema operativo, pero no puedes arrancar tu partición de recuperación, puedes seguir los siguientes pasos:
Instala GNU/Linux en la partición donde estaba Windows. Si tu sistema venía con Win7 preinstalado, seguramente tendrás 3 particiones actualmente. La primera de 100 MB es reservada para el sistema, la segunda es el espacio disponible para el usuario y el sistema operativo, y finalmente la tercera es la partición de recuperación.
Instalar Ubuntu es muy sencillo. Se descarga la imagen de Ubuntu y se graba a un CD-R. Al instalar, se debe tener extremo cuidado de no sobreescribir la partición de recuperación, y sólo utilizar las primeras dos particiones. Es necesario borrar las primeras dos particiones, crear una sola partición del espacio liberado al borrar las otras dos y finalmente instalar Ubuntu en la nueva partición.
El instalador te lanza una advertencia de que no se ha especificado una partición swap, lo cual está bien por ahora. El único propósito de esta instalación de Ubuntu es instalar GRUB en el MBR, de tal manera que nos deje arrancar la partición de recuperación.
Al terminar la instalación de Ubuntu, la PC reinicia y GRUB arranca. GRUB agrega entradas al menú de inicio automáticamente para cada sistema operativo instalado en el disco. En este caso GRUB detecta la partición de recuperación como una instalación de Windows. Lo último que queda es seleccionar la opción de arrancar Windows, lo que automáticamente inicia el proceso de recuperación.
¿Qué puede salir mal?
Otros intentos.
Palabras finales.
De nuevo GNU/Linux al rescate. En este caso GRUB es el héroe de la película, aunque también el hecho de sobreescribir Windows por GNU/Linux es necesario, de otra manera el arranque de la recuperación no funciona.
Mi teoría es que no es necesario instalar GNU/Linux, tan solo eliminar las dos particiones de Windows e instalar GRUB en el MBR y la nueva partición, configurándolo para arrancar la partición de recuperación. Esto no lo he probado, pero de poderse sería un proceso mucho menos tardado.
El WUSB54GC de Linksys es un dongle WiFi USB. Lo compré pensando en que lo podría usar en Ubuntu sin mayor complicación, pero no fue así. El driver necesario se incluye así que no hay necesidad de descargar nada, sin embargo se necesita configuración adicional.
Lo primero es asegurarnos que el hotspot al que nos queremos conectar usa WEP o WPA. Al inicio intenté conectarme a un hotspot con WPA2 y nunca logré conectarme. Cambiar la configuración a WPA arregló el problema.
Lo siguiente es editar el archivo blacklist.conf
sudo gedit /etc/modprobe.d/blacklist.conf
Agregar la siguiente línea al final:
blacklist rt2800usb
Y listo, al conectar el dongle el sistema debe reconocer las redes inalámbricas disponibles y conectarse sin problemas.
Soy un geek de la emulación desde que supe se podía emular el SNES en mi modesta Pentium 2. Desde entonces he utilizado varios emuladores y hasta programado un simulador por mi cuenta (para el microcontrolador 68HC11 de Motorola).
Lo que me lleva a este post: el NES. El NES es interesante ya que es el sistema más emulado que hay, aún así crear un emulador del NES no es tarea fácil. Además las computadoras (y otros gadgets) de hoy tienen lo suficiente para emularlo sin penalización en la velocidad. También, su CPU (MOS 6502 ligeramente modificado) de 8 bits fue el CPU elegido para la mítica Commodore 64, el Atari 2600, Terminator y Bender.
En el NES se usan dos chips principales: el CPU y el PPU (Picture Processing Unit). Este último es exclusivo para cálculos relacionados con gráficos. El CPU también se encarga del manejo del audio gracias a una unidad de procesamiento de audio (APU por sus siglas en Inglés) incluída en el mismo chip. La señal de audio es semi-analógica, y el chip se encarga de generar 4 señales y un canal de muestreo que reproduce sonido basado en el contenido de un sector de la memoria:
Con la combinación de esas señales se genera la música y efectos de sonido que escuchamos en los juegos, que en este momento se me viene a la mente los temas de cada boxeador del Punch Out! original.
Sobre gráficos, el PPU tiene a su disposición 16kb de memoria, lo cual es menor a lo que ocupa en memoria una sola textura de juegos más recientes. En memoria, existe un sector para los sprites y otro para el fondo (background). Todos los gráficos se guardan en bloques de 8×8, los cuales en conjunto forman sprites o el fondo del juego. El NES puede utilizar 54 colores diferentes, aunque sólo puede direccionar 16 colores para fondos, y 16 colores para sprites a la vez.
Su sucesor, el 5A22 fue el encargado de cimentar a Nintendo como el líder indiscutible de la siguiente era: la de los 16 bits. Además del 5A22, el PPU era capaz del famoso Mode 7 para crear efectos de perspectiva vistos en juegos como F-Zero, Super Mario Kart, Super Castlevania IV y los Final Fantasy’s que aparecieron en el SNES.
Con todas estas limitantes, el NES nos entregó juegos tan importantes como Super Mario Bros 1 y 3, The Legend of Zelda, Contra, Metroid, Final Fantasy, Mega Man y Metal Gear.

A JavaScript NES emulator.
An implementation of a 8 queen problem solver using Simulated Annealing in Javascript.
Everlasting Flame 1.2 w/OS 5 fix.
A TextMate syntax compatible source editing widget. Current adapters are for SWT.

public void doGet(HttpServletRequest request, HttpServletResponse response){
String uriRequest = request.getRequestURI();
//parse to obtain only the last part
String uriRequest = uriRequest.substring(uriRequest.lastIndexOf("/")+1);
}
Same thing for doPost().
ClientBundle introduced in GWT 2.0 allows you to bundle images and other resources in one file, this file is cached forever resulting in fewer server request.
That being said, GWT introduces a concept they call perfect caching. It works by splitting your application in several files named something like .cache.html and the md5 part always change when your application code or resources change. Then there's the bootstrap script, which contains the logic to look for the correct <md5>.cache.html file and load it. The bootstrap should never be cached.
In your app server, you need to configure it something like this (Apache in this case)
<Files *.nocache.*>
ExpiresDefault "access"
</Files>
<Files *.cache.*>
ExpiresDefault "now plus 1 year"
</Files>
In this case it's set to cache for one year. As far as I know there's no setting to cache forever, that only means a very high expiration time.
In the case of Tomcat, as far as I know there's no cache control so it has to be done manually by setting the proper HTTP headers. This can be automated by the use of filters.
/*Please don't use this in production!*/
public class CacheFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
//cache everything for one year
response.addHeader("Cache-Control", "max-age=31556926");
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) {
this.fc = filterConfig;
}
public void destroy() {
this.fc = null;
}
}
Then map the filter in tomcat or derivatives (such as glassfish), in web.xml:
<filter>
<filter-name>cachingFilter</filter-name>
<filter-class>CacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cachingFilter</filter-name>
<url-pattern>*.cache.*</url-pattern>
</filter-mapping>
The question is tagged as GWT so based on that... to do it entirely on the client, you can use the com.google.gwt.user.client.Window class.
Window.open(linkURL, "_self", "");
On the first println() you are overriding the toString() method from the anonymous myAbstractClass instance, therefore you get the string returned by your overriden toString() method, that's the default behavior of the println() function.
On the second println(), you are not overriding the toString() method, so println() uses the default one (inherited from Object).
On a side note, try formatting your code correctly, is much easier to read and understand.
abstract class myAbstractClass{}
public class Main {
public static void main(String[] args) {
System.out.println(new myAbstractClass(){
public String toString(){
return "myAbstractClass toString";
}
});
System.out.println(new myAbstractClass(){
public String myFunction(){
return "myAbstractClass myFunction";
}
});
}
}
3- The solr I have downloaded came with Jetty. Is Jetty a Servlet container?
Yes, Jetty is a Web server and Servlet container. A servlet container is a web server that interacts with servlets, and you need one of those to host your servlets, execute them, etc.
An application server typically hosts many other facilities, such as security, authentication, Java Mail, EJB container, and many others.
First, in your JSP import the class you are trying to use:
<%@ page import="com.mypackage.MyClass" %>
Then you can use that class as you would normally do:
<%
MyClass c = new MyClass();
c.getSomeProperty();
%>
To fill the control, you iterate your array and set the value argument of the option tag:
<select>
<%while (myList.next()){%>
<option><%out.print(c.getName());%></option>
<%}%>
</select>
As you can see, there's mixed Java code and HTML. First it outputs the select tag, then on Java code there's a while loop iterating a list of objects. This could be your ResultSet, an array or some other collection. For each iteration it creates an option tag with some value, this would be the value you want the user to see.
This is the basic approach, using only JSP. But there are many tag libraries, for example JSTL, that provide things like iteration so you can write things like:
<select name="mySelect">
<foreach collection="<%= myCollection %>" var="mybean">
<%= mybean.getOptionTag() %>
</foreach>
</select>
In the first place, your Book instance above contains errors. Here's what I suppose it should look like:
public class Book{
public String name = "myName";
public List authors = new ArrayList();
public String subject = "mySubject";
public Book(){
}
}
Now:
{"Book":{"name":"myName", "authors":"", "subject":["mySubject"]}}
Are you sure this is what xstream is returning for the Book object listed above? This doesn't seems right, since the subject property is a String and not a String[] or other type of collection. The JSON encoding for the first example you give (book without authors) should be:
{"Book":{"name":"myName", "authors":"", "subject":"mySubject"}}
Unless your Book looked something like this:
public class Book{
public String name = "myName";
public List authors = new List();
public String[] subject = {"mySubject"};
public Book(){
}
}
Bottom line: make sure you are not declaring your subject as a collection.
As a bonus tip, try to post working code on your questions. It's easier that way to get meaningful answers.
So my guess is that your Book class is declaring subject to be some kind of collection
Yes that could very well be the problem. Legacy ports (parallel and serial port) support in Java is provided by the Java Communications API, which relies on native code to support low level access to those ports. That API it's an extension to the JDK and not part of it.
Of course it could also be that on the new machine the user running your program doesn't have permissions to access the port, which is a different problem.
EDIT: For cross platform support for legacy ports, hell even if you only intend to use your program in one platform I recommend RXTX, an open source replacement for JavaComm.
If you want to store your images in the database instead of just a path to reference the image, the column that will hold your image need to be of BLOB type.
CREATE TABLE upload (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
content LONGBLOB NOT NULL,
PRIMARY KEY(id)
);
From your BlackBerry program (warning, untested):
//First param is a Bitmap, second is quality
JPEGEncodedImage encodedImage = JPEGEncodedImage.encode(image, 100);
byte imageBytes[]=encodedImage.getData();
//The HTTP connection stuff
HttpConnection conn = (HttpConnection) Connector.open(SERVER_URL, Connector.READ_WRITE);
conn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_TYPE, HttpProtocolConstants.CONTENT_TYPE_MULTIPART_FORM_DATA);
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LENGTH, String.valueOf(imageBytes.length));
//Change this part to what your server side code expects
String contDisp="Content-Disposition:form-data; uploadedimage=YOUR_IMAGE_NAME;filename=\"Image.jpg\"";
String contEnc = "Content-Transfer-Encoding: binary";
String type="Content-Type:image/jpeg";
OutputStream out= conn.openOutputStream();
out.write(imageBytes);
out.flush();
out.close();
So basically you use HttpConnection to setup the headers for a POST request, with multipart form data as content type. There are other headers that may be needed, to know exactly what you need (not BlackBerry specific) check the HTTP/1.1 protocol specification.
How to actually store the image into the database will depend on your server side implementation. This can be anything from PHP, ASP, JSP or any server side technology that allows you to talk to your MySQL instance.
Create a dummy object:
class MyDummyRequest implements HTTPServletRequest{
//implement your own methods, for example:
public Map getParameterMap(){
Map myMap = new HashMap();
//put the params you need inside myMap
return myMap;
}
}
If you want to avoid creating dummy objects for test purposes you may look into one of the available mocking libraries for Java, such as Mockito.
With the accept attribute, you list the mime types to accept.
<form action="form_action.asp" accept="image/gif, image/jpeg">
First name: <input type="text" name="fname" /><br />
Last name: <input type="text" name="lname" /><br />
Your image: <input type="file" name="pic" id="pic" /><br />
<input type="submit" value="Submit" />
</form>
Taken from here.
As other said, as long as you have Java installed and avoid using native code, you should be good to go. One thing to note is that you can usually run a JAR file just by double clicking it, and it opens like a native executable (on Windows this is how it works by default, on other OSes you can configure this behavior).
Such JAR files are called executable JAR files. If what you want to create is an executable JAR file, then you need to add a manifest file that tells the Java virtual machine (JVM) the name of the main class. Executable JAR files also can be run on the command line by doing:
java -jar myprogram.jar
If your JAR is not an executable JAR, then to run your program you have to add the JAR to your classpath and then execute the main class. To add a JAR to the classpath:
java -classpath path/to/your/program.jar com.mypackage.Main
Option 2 doesn't make much sense, or at least it's not as clear to me as option 1. With option 1 you don't need to handle user interaction inside your space object. You could have in your main class or a separate class dedicated to handle user interaction:
public void move(Player p, int spaces){
Space landingSpace = board.getLandingSpace(p,spaces);
landingSpace.land(p); //apply your logic here
}
As you can see, the Space class is responsible for checking the Player p that intends to land on that space. It applies any custom logic, checks if it has enough money, if it's something that the player owns, etc. Each subclass of Space will have its own set of rules, as you described in option 1.
I think I need to use the String[] overloaded method for exec
Exactly! Change your command to be a String array. The array must contain the command and its arguments:
String[] command = {"cmd","/c", "concat2.vbs", arg1, arg2};
Process p = Runtime.getRuntime().exec(command);
concat2.vbs should be on Window's execution path (same directory, or configured in the PATH environment variable)
Check out the documentation for the Runtime class.
You need to:
String out = result.getConsoleOutput().replaceAll("\n", "<br/>");
transOut.getElement().setInnerHTML(out);
Note the setInnerHTML() instead of setInnerText()
See my answer here: http://stackoverflow.com/questions/2413722/gwt-processbuilder/2413770#2413770 Other answers in the same question provide useful advice as well.
It's not exactly about HSQLDB and GWT, but the cause of the error is the same: Google App Engine doesn't support all Java EE classes. Check the Will it play in GAE? page to know if your particular feature/library is available for GAE.
Yes, it's possible with ant. A jar file is basically a zip with a special manifest file. So to unjar, we need to unzip the jars. Ant includes an unzip task.
To unzip/unjar all the jar files in your project:
<target name="unjar_dependencies" depends="clean">
<unzip dest="${build.dir}">
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
</unzip>
</target>
Obviously you need to declare ${build.dir} and ${lib.dir} first. The line <include name="**/*.jar" /> tells ant to include all files that end up with the jar extension, you can tweak that include to suit your needs.
To pack everything into a jar, you use the jar task:
<target name="make_jar" depends="compile, unjar_dependencies">
<jar basedir="${build.dir}"
destfile="${dist.dir}/${project_name}.jar">
<manifest>
<attribute name="Main-Class" value="${mainclass}" />
</manifest>
<fileset dir="${build.dir}">
<include name="**/*.class" />
</fileset>
<fileset dir="${src.dir}">
<include name="applicationContext.xml" />
<include name="log4j.properties" />
</fileset>
</jar>
</target>
In this example, we include different filesets. In one fileset we are including all compiled classes. In another fileset we include two config files that this particular project depends upon.
Initial request is the request that the browser does in order to display the page with the ${customer.name} tag. Postback happens when the browser posts some or all page values and then the same page that was posted in the first place is returned to the client. This might happen for example as a result of a validation error.
Knowing if the current view being rendered is a result of a postback is useful. For example you might want to display a message as a result of a postback, but not every time the page is refreshed.
There may be some performance overhead of calling the getAge() method many many times, but I suggest you consider The Sad Tragedy of Micro-Optimization Theater.
I would ask how they are approaching the problem, and in particular if they took current research results from vehicle wireless sensor networks, since that's an area I was researching into when in grad school.
Also some published papers on the actual implementation and experimentation results would be great.
Did you try subclassing DeckPanel and overriding onComplete()?
public MyDeckPanel extends DeckPanel{
@Override
protected void onComplete(){
super.onComplete();
//What you want to do once the animation completes
}
}
Call setVisible(false) on your main JFrame before capturing the screen. When the screen capturing process is finished, call setVisible(true) to get your GUI showing up again.
To capture the screen, you can use the Robot class. It contains a createScreenCapture method that receives rectangle coordinates which will be captured in a BufferedImage.
Wrap your TextArea and list in a new panel with a BorderLayout manager. Basically the BorderLayout manager lets you arrange components using north, south, east, west and center coordinates. The components at the center takes all available space as the parent container has more space available to it.
private JPanel createContentPane() {
JPanel pane = new JPanel(); //this is your main panel
JPanel textAreaPanel = new JPanel(new BorderLayout()); //the wrapper
//Some more code...
//Then at the end
//Make your TextArea take the center
textAreaPanel.add(TextArea, BorderLayout.CENTER);
//And the list to the east
textAreaPanel.add(list, BorderLayout.EAST);
pane.add(textAreaPanel);
pane.add(buttonPanel);
return pane;
}
The cool thing is that you can nest panels inside other panels, adding them different layout managers to get your desired layout.
On an unrelated note, try to follow Java naming conventions. Instead of JTextArea TextArea use JTextArea textArea. It makes it easier for you and people reading your code to understand it.
A great reference for an implementation of hashCode() is described in the book Effective Java. After you understand the theory behind generating a good hash function, you may check HashCodeBuilder from Apache commons lang, which implements what's described in the book. From the docs:
This class enables a good hashCode method to be built for any class. It follows the rules laid out in the book Effective Java by Joshua Bloch. Writing a good hashCode method is actually quite difficult. This class aims to simplify the process.
If you want to further reduce the code size, minify and gzip or deflate it. Beware that gzipped code needs to be uncompressed before it's executed, thus causing a delay. The jQuery download page offers an already minified and gzipped version.
Another option you could look into is using CND hosted jQuery, that is jQuery hosted by third party organizations such as Google or Microsoft. Details in the jQuery download page.
But what if I want to make the swing worker class a non-inner class. Should I need to pass label as an argument to the constructor of swing worker class so that the process() method can access.
That's perfectly fine. From the SwingWorker documentation:
class PrimeNumbersTask extends
SwingWorker<List<Integer>, Integer> {
PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
//initialize
}
@Override
public List<Integer> doInBackground() {
while (! enough && ! isCancelled()) {
number = nextPrimeNumber();
publish(number);
setProgress(100 * numbers.size() / numbersToFind);
}
}
return numbers;
}
@Override
protected void process(List<Integer> chunks) {
for (int number : chunks) {
textArea.append(number + "\n");
}
}
}
JTextArea textArea = new JTextArea();
final JProgressBar progressBar = new JProgressBar(0, 100);
PrimeNumbersTask task = new PrimeNumbersTask(textArea, N);
task.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
task.execute();
Notice the constructor PrimeNumbersTask(JTextArea textArea, int numbersToFind). They pass the JTextArea to update.
When you use ==, you are comparing if two variables hold reference to the same Object. In other words s1 == s2 is like asking: are the s1 and s2 variables referring to the same String object? And that's not true, even when both String objects have the same "abc" value.
When you use equals(), you are comparing the value of both objects. Both objects may not be the same, but their value (in this case "abc") is the same, so it returns true.
How do you define whether an object is equal to another? That's up to you. In this case the String object already defines this for you, but for example if you define a Person object, how do you know if a person P1 is equal to P2? You do that by overriding equals() and hashCode().
Because the set structure (notice how your hashmap is backed by a set) does not allows two equal objects to be stored. That's how sets behave.
Now, You may be fooled to think that both a1 and a2 are equal, but if they don't override equals or hashCode then for Java they are not equal. However with your strings s1 and s2, they are indeed equal because the String implementation already overrides the equals and hashCode methods. Try doing s1.equals(s2) and you'll get a true as result. If you do a1.equals(a2) you'll get false.
At the end, your hashset contains a1, a2 and s1.
You extended your question, so to answer that...
s1 and s2 are not referring to the same object, they are two different String objects but both represent the same set of characters. Since they are not the same object, System.out.println(s1 == s2) prints false. They are equal(), but not the same object.
Check out Jrar. It's not pure Java, it makes use of rar and unrar programs that must be available in your PATH.
I'm struggling to get association right on Grails. Let's say I have two domain classes:
class Engine {
String name
int numberOfCylinders = 4
static constraints = {
name(blank:false, nullable:false)
numberOfCylinders(range:4..8)
}
}
class Car {
int year
String brand
Engine engine = new Engine(name:"Default Engine")
static constraints = {
engine(nullable:false)
brand(blank:false, nullable:false)
year(nullable:false)
}
}
The idea is that users can create cars without creating an engine first, and those cars get a default engine. In the CarController I have:
def save = {
def car = new Car(params)
if(!car.hasErrors() && car.save()){
flash.message = "Car saved"
redirect(action:index)
}else{
render(view:'create', model:[car:car])
}
}
When trying to save, I get a null value exception on the Car.engine field, so obviously the default engine is not created and saved. I tried to manually create the engine:
def save = {
def car = new Car(params)
car.engine = new Engine(name: "Default Engine")
if(!car.hasErrors() && car.save()){
flash.message = "Car saved"
redirect(action:index)
}else{
render(view:'create', model:[car:car])
}
}
Didn't work either. Is Grails not able to save associated classes? How could I implement such feature?





