viernes, 30 de julio de 2010

java.lang.IllegalThreadStateException

Esta excepción tuve el gusto de conocerla hace poco y pareciera que era lanzada, en mi caso particular, cuando intentaba correr un hilo dos veces.

public class IllegalThreadStateExceptionExample {

protected FooThread fooThread = new FooThread();

public class FooThread extends Thread {
@Override
public void run() {
System.out.println("Foo Thread run!");
}
}

public void runThread() {
fooThread.start();
}

public static void main(String[] args) {
IllegalThreadStateExceptionExample example =
new IllegalThreadStateExceptionExample();
example.runThread();
example.runThread();
}
}

Resultado:

Foo Thread run!
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at IllegalThreadStateExceptionExample.runThread(IllegalThreadStateExceptionExample.java:14)
at IllegalThreadStateExceptionExample.main(IllegalThreadStateExceptionExample.java:20)

Según la documentación de la clase:

"Lanzada para indicar que un hilo no está en un estado apropiado para la operación solicitada."

Al parecer cuando un hilo termina su ejecución en el método "run()", queda en un estado en el cual no puede volver a ejecutarse. Se puede solucionar rápidamente simplemente instanciando un nuevo hilo.

martes, 20 de julio de 2010

Autenticación en Tomcat para acceso de direcciones de tipo UNC

Estuve lideando con un problema que me tomó un par de días resolver. Tengo un código en Java que utilizó para listar los archivos dentro de una carpeta. Uno simplemente crea una instancia de la clase java.io.File pasando en el constructor la ruta de la carpeta. Después solamente se llama el método "listFiles" y te retorna un arreglo con los archivos encontrados.

La ruta que necesitaba listar era de tipo UNC. La sintaxis utilizada por Microsoft para accesar una localidad de red compartida. Esta ruta estaba protegida con usuario y contraseña en el servidor. No obstante estos ya estaban guardados por windows de manera que no me volvía a preguntar por ellos cada vez que accesaba la dirección de red.

El problema en sí era que la clase de abajo (no es la misma, solo para usos de ejemplificación) funcionaba correctamente si la ejecutaba en línea de comandos. Pero si la usaba en mi aplicación web corriendo en Tomcat, la misma carpeta no se podía encontrar.


import java.io.File;

public class FolderLister {

public File[]listFiles(String address) {
File folder = new File(address);

if(folder.exists()) {
return file.listFiles();
}
return null;
}

public static void main(String [] args) {

FolderLister folderLister = new FolderLister();

File[] listOfFiles = folderLister.listFiles("\\\\remote-host\\path");

for (File f : listOfFiles) {
System.out.println(f.getName());
}
}
}
Intenté probar con el "catalina.policy" pero me di cuenta que nada tenía que ver con mi problema. Después de googlear con las palabras correctas encontré un foro donde indicaban que el Tomcat tenía que ser arrancado con el usuario que tenía acceso a la carpeta compartida. Esto se puede configurar fácilmente en las propiedades del servicio en la pestaña de "Log On".