Archivo de la categoría Tecnologia

Desbordamiento de enteros Vs. truncamiento/redondeo

Jueves, 26 de Julio de 2007

En Kriptopolis hay un post interesante que abre un debate sobre si Java es o no es explotable a partir del desbordamiento de enteros. Este “efecto”, que en C se puede combinar con otros para romper una aplicación, en Java se convierte en un truncamiento documentado del valor que supuestamente se desborda.
Está bien leer el artículo entero (y el original también en h4ck1t) y además los comentarios.

Personalmente creo que no es explotable. El caso solo se produce cuando necesitamos parsear un valor y utilizamos el método incorrecto.

Produce truncamiento:

short importe = Integer.valueOf(args[1]).shortValue();

No produce truncamiento (lanza excepcion si lo encuentra):

short importe = Short.valueOf(args[1]).shortValue();

Si necesitas un short ¿que sistema de parseado utilizarías? El segundo, ya que se apoya en el objeto wraper de short, que es java.lang.Short, el cual si lanza un NumberFormatException si el valor no “cabe” en un short (entre -32768 y 32767).

Varios

Viernes, 18 de Mayo de 2007

El que no encuentre nada raro en esta foto es que no sabe lo que es SQL:

addedsql.jpg

Visto en WTF


Y un enlace digno de portada. El mejor host que podáis conseguir. Y no es publicidad… y si no os lo creéis, miradlo vosotros: No Uptime. Con slogans tan buenos como estos:

We are constantly working to improve our server downtime.
Keeping you awake at night is our #1 priority.

Y cada vez que entras, hay un testimonio nuevo, el de ahora dice: “No Uptime used my credit card to buy porn magazines. This service is a sham!”

Estoy deseando recomendarselo a todos mis amigos.

Corta y pega código con estilo

Lunes, 7 de Mayo de 2007

Hay veces que tenemos que copiar y pegar, pero parece que Java nos pone trabas a ellos cuando resulta demasiado evidente.
Por ejemplo, supongamos este método de una clase ficticia:

public void chorrada() {
	StringBuffer sb = new StringBuffer();
	List temporal = new ArrayList();
	for (int n = 0; n<10; n++) {
		String hola = "hola";
		sb.append(n).append(hola);
		temporal.add(sb);
	}
}

Un código absurdo, pero eso no importa. Ahora coge este código, cópialo y pégalo tres veces seguidas, así:

public void chorrada() {
	StringBuffer sb = new StringBuffer();
	List temporal = new ArrayList();
	for (int n = 0; n<10; n++) {
		String hola = "hola";
		sb.append(n).append(hola);
		sb.append(n);
		temporal.add(sb);
	}
	StringBuffer sb = new StringBuffer();
	List temporal = new ArrayList();
	for (int n = 0; n<10; n++) {
		String hola = "hola";
		sb.append(n).append(hola);
		temporal.add(sb);
	}
	StringBuffer sb = new StringBuffer();
	List temporal = new ArrayList();
	for (int n = 0; n<10; n++) {
		String hola = "hola";
		sb.append(n).append(hola);
		temporal.add(sb);
	}
}

Si tienes un IDE moderno o compilas, verás que la segunda y tercera declaración de las variables sb y temporal fallan: “Variable sb is already define in the scope”, que viene a significar como que la variable ya está definida en el ámbito actual. ¿Y cuál es ese ámbito? El código del método, pero ¿porqué? pues porque está cerrado entre sus propias llaves {}. Fíjate que la variable hola está definida también tres veces, pero no falla al compilar. Eso es porqué su ámbito son las llaves {} del bucle for.
Bueno, una manera de evitar esto es añadirle unas llaves a nuestro código, sin más. Así:

public void chorrada() {
	{
		StringBuffer sb = new StringBuffer();
		List temporal = new ArrayList();
		for (int n = 0; n<10; n++) {
			String hola = "hola";
			sb.append(n).append(hola);
			sb.append(n);
			temporal.add(sb);
		}
	}
	{
		StringBuffer sb = new StringBuffer();
		List temporal = new ArrayList();
		for (int n = 0; n<10; n++) {
			String hola = "hola";
			sb.append(n).append(hola);
			sb.append(n);
			temporal.add(sb);
		}
	}
	{
		StringBuffer sb = new StringBuffer();
		List temporal = new ArrayList();
		for (int n = 0; n<10; n++) {
			String hola = "hola";
			sb.append(n).append(hola);
			sb.append(n);
			temporal.add(sb);
		}
	}
}

Ahora cada fragmento tiene su propio ámbito, podemos definir cuantas variables que queramos dentro, que una vez finalice este ámbito definido por sus propias llaves {}, las variables desaparecerán.
Así conseguiremos copiar y pegar con estilo, sin cambios, digno de un buen código spaghetti listo para sembrar el pánico, así que usar con precaución e intentar evitarlo… pero si no hay más remedio…

Diferencias y similutes entre C# y Java

Sábado, 5 de Mayo de 2007

He encontrado en Javahispano un enlace a un artículo muy bueno donde explica con ejemplos de código, todas y cada una de las diferencias y similitudes entre C# y Java. Es un artículo ideal si conoces Java y te vas a meter a programar en C#. Puede que te ahorres unos cuantos tutoriales.

C# From a Java Developer’s Perspective

09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0

Sábado, 5 de Mayo de 2007



Enlace al video en YouTube

Y todo empezó aquí
Más información:

Consejos para programar con Swing

Miércoles, 25 de Abril de 2007

Un listado de consejos y buenas prácticas para desarrollar en Swing, , por cortesía de Chuidang.
No son patrones, no son trucos, son consejos desde el dolor de haber sufrido durante tiempo fruto de la experiencia y del día a día. No los pases por alto si te vas a meter de cabeza con Swing.

  • En la aplicación sólo debe haber un único JFrame, correspondiente a la aplicación principal. Todas las ventanas secundarias deben ser JDialog. Todas las ventanas secundarias deben tener una ventana padre, que es a partir de la cual se despliega. Es decir, todos los JDialog secundarios deben tener como padre al JFrame principal. Si desde un JDialog se va a visualizar otro, este segundo debe tener como padre al primero, y así sucesivamente.
  • Evita en lo posible los JDialog modales, o ten muy en cuenta su jerarquía de padres. El primer JDialog modal no tiene problemas si le pones su padre adecuadamente. Si tienes un JDialog modal visible, no muestres otro JDialog secundario, salvo que también sea modal y sea hijo del anterior. Si pones visibles a la vez dos JDialog modales y no son el uno hijo del otro, tendrás problemas al intentar escribir en ellos o cerrarlos.
  • Nunca heredes de JFrame o JDialog o JApplet para hacer tus ventanas. Hazlo siempre de un componente que no sea ventana y que no te limite. Si tus ventanas heredan de JPanel, podrás ponerlas siempre que quieras dentro de un JFrame, un JDialog, un JInternalFrame, un JApplet o incluso incrustarlas en otro JPanel. Si tu ventana hereda de JFrame, está condenada a ser un JFrame toda su vida.
  • Reaprovecha las ventanas, no se las dejes al recolector de basura. Si un botón, al apretarlo, visualiza un JDialog, no hagas un new de JDialog cada vez que pulsas el botón. Es mejor hacer sólo un new la primera vez y guardarselo. En las siguientes veces bastará con hacer setVisible(true) y setVisible(false). Para que el recolector de basura libere una ventana, además de lo habitual, hay como minimo que llamar al método dispose() de dicha ventana  -cosa que mucha gente no sabe- , para que el sistema de eventos de teclado y ratón eliminen todas las referencias que tienen a ella. De todas formas, incluso así no tengo muy claro que los JDialog se liberen siempre y, desde luego, en versiones anteriores de java, los JFrame NUNCA se liberaban. La excusa de SUN es que como sólo debía haber un JFrame principal, no tenía sentido liberarlo.
  • Los layouts para situar componentes no son tan complicados, sólo hay que ponerse a ello. No uses el layout null, ya que tu ventana no será redimensionable y puedes tener problemas si cambia la fuente de letra, si tu programa se ejecuta en otro sistema operativo, se cambia el look & feel, etc.
  • Una vez que sepas los layouts simples, tenderás a hacer ventanas grandes a base de anidar muchos JPanel que a su vez tienen dentro JPanel que su vez tienen dentro JPanel, todos ellos con un layout simple. Eso hace ventanas muy pesadas y que consumen mucho. Aprende a usar el GridBagLayout para hacer un solo panel con todo. La excepción a esto es que tengas pequeños JPanel reutilizables, como un editor de coordenadas geográficas que pida latitud, norte/sur, longitud, este/oeste, un panel que pida usuario y password, etc.
  • Todos los eventos de ratón y teclado se ejecutan en el mismo hilo que repinta las ventanas. Si en un actionPerformed(), keyPressed(), … tu código tarda mucho o pretendes que se pinte algo en una ventana, simplemente no lo hará hasta que tu código termine. Si tu código en un actionPerformed() va a tardar mucho o tiene que pintar cosas en la ventana, lanza un hilo aparte para hacer esa tarea y termina el actionPerformed() lo antes posible.

Groovy: un chat

Lunes, 23 de Abril de 2007

Tok es un programa de chat escrito en Groovyen dos horas por el autor de SH*TMORES, un blog sobre ingeniería de software. El autor (no he logrado encontrar cómo se llama) se quedó sin ADSL unos días, y decidió dedicar su tiempo libre a “aprender un poco más de Groovy”. Cogió su ejemplar de Groovy in Action, y en un par de horas tenía una sencilla aplicación de chat cliente-servidor.
El cliente tiene 63 líneas de código, el servidor solo 33, y la conectividad entre ambos se realiza mediante XML-RPC.

Vía Groovy.or.ges, el post original aquí

Cada día estoy más convencido de que tengo que aprender Groovy. Ya. Ahora. Solo de pensar la de cientos de líneas que me puedo ahorrar programando lo mismo que hago en Java pero en Groovy se me hace la boca agua.

Tok client

 1 import groovy.swing.SwingBuilder
 2 import groovy.net.xmlrpc.XMLRPCServerProxy as Proxy
 3 import groovy.net.xmlrpc.XMLRPCServer as Server
 4
 5 import java.net.ServerSocket
 6 import java.awt.BorderLayout as BL
 7 import javax.swing.WindowConstants as WC
 8
 9
10 def swing = new SwingBuilder()
11 def content = new StringBuffer()
12 def remote = new Proxy('http://localhost:8081/')
13
14 newMsg = swing.action( name:'newMessage', closure: {
15     msg = remote.chat( swing.inputMsg.text )
16     //content << " ${msg}"
17     //swing.msgPane.text = content
18     swing.inputMsg.text = ""
19 } )
20
21 def frame = swing.frame( title:'Tok' ) {
22     // Menu bar
23     menuBar {
24         menu('File') {
25             menuItem 'Quit'
26         }
27         menu('Edit') {
28         }
29         menu('Help') {
30             menuItem 'About'
31         }
32     }
33
34     // Panel
35     panel( layout: new BL() ) {
36         scrollPane( constraints: BL.CENTER ) {
37             editorPane( id:'msgPane', editable:false, preferredSize:[60, 100],
38                         editorKit: new javax.swing.text.html.HTMLEditorKit() )
39         }
40         panel(constraints: BL.SOUTH) {
41             textField(id:'inputMsg', columns:20)
42             button( action:newMsg, 'Go' )
43         }
44     }
45 }
46 content << "Tok session started on ${new Date().toString()}"
47 swing.msgPane.text = content
48
49 // Perform client registration to the chat network
50 int ticket = remote.register()
51 println "TICKET: ${ticket}"
52 def server = new Server()
53 server.startServer( new ServerSocket(ticket) )
54
55 server.update = { msg ->
56     print msg
57     content << "${msg}"
58     swing.msgPane.text = content
59 }
60
61 frame.pack()
62 frame.setDefaultCloseOperation( WC.EXIT_ON_CLOSE )
63 frame.show()

Tok Server

 1 import groovy.net.xmlrpc.XMLRPCServer as Server
 2 import groovy.net.xmlrpc.XMLRPCServerProxy as Proxy
 3 import java.net.ServerSocket
 4
 5
 6 def ticket = 9991
 7 def clients = []
 8
 9 def server = new Server()
10
11 server.chat = { msg ->
12     println msg
13         clients.each { client ->
14             //client.update( msg )
15             updateClient(client, msg)
16     }
17 }
18
19 def updateClient(client, msg) {
20     try {
21         client.update( msg )
22     } catch (Exception ex) {
23         println ex
24     }
25 }
26
27 server.register = {
28     clients << new Proxy("http://localhost:${ticket}")
29    return ticket++
30 }
31
32 def socket = new ServerSocket(8081)
33 server.startServer(socket)

Seguridad en algoritmos HASH

Lunes, 23 de Abril de 2007

Desde el año 2004 aproximadamente, cuando saltaron las primeras noticias escandalosas sobre la ruptura de MD5, la seguridad que ofrecen los algoritmos de HASH a nuestros esquemas de cifrado ha sido una cuestión que se ha puesto en entredicho. ¿Qué seguridad ofrecen estos algoritmos? ¿Resulta computacionalmente complejo romper uno de estos algoritmos? ¿Qué solución se debe adoptar?

Sigue leyendo el artículo completo:

(Artículo original de LordHASH)

Algunas caras de la programación Ajax

Viernes, 20 de Abril de 2007


Los creadores de jQuery, Yahoo! User Interface (YUI), Dojo Toolkit y Google Web Toolkit (GWT) tomada en el Web 2.0 panel.
Y ¿donde están los creadores de Mootols y Prototype?

Vía Ajaxian

Sobrecarga de métodos y casting de null

Martes, 17 de Abril de 2007

Supongamos que hemos sobrecargado un método en Java de la siguiente manera

public static void metodoSobrecargado(List miscosas) {
}

public static void metodoSobrecargado(String[] miscosas) {
}

Tenemos dos métodos llamados “metodoSobrecargado”, cada uno de ellos acepta un tipo de parámetro distinto e incompatible entre sí.

Ahora supongamos que necesitamos llamar a uno de ellos, pero pasándole null como parámetro. Podríamos intentar esto:

public static void metodoSobrecargado(String[] args) {

    metodoSobrecargado( null );   // Falla!!

}

Pero falla estrepitosamente al compilar. Podemos optar por no sobrecargar el método, meterle algún parámetro más a uno de ellos con el fin de poder diferenciarlos o, simplemente, podemos hacer un casting a null para que se adapte al tipo esperado por el método que elijamos, así:

public static void metodoSobrecargado(String[] args) {

    metodoSobrecargado( (List)null );

    metodoSobrecargado( (String[])null );

}

Puede parecer elemental, pero seguro que más de uno no se lo sabía.