Crear funciones Nativas en Java...DLL

Bueno a veces es necesario crear funciones que sean dependientes del Sistema y que por lo tanto no pueden ser implementadas en Java, para eso existe JNI (Java Native Interface), que sirve para llamar a funciones nativas del Sistema y que pueden estar en un DLL (En Windows). Bien ahora veremos cómo crear una función nativa y que está sea llamada en Java. Lo primero que tenemos que hacer es crear una clase, y que tenga definido un método nativo, a su vez, la clase cargara una librería que se llamara "Project1" (así fue como le puso mi compilador de C jajaja) luego en el main, instanciaremos el objeto y llamaremos a la función:

public class HelloWorld {

public native void sayHello();

static {
System.loadLibrary("Project1");
}

public static void main(String[] args) {
new HelloWorld().sayHello();
}


}

El ejemplo es muy simple, sólo tenemos una clase con un método nativo, un bloque estático que carga una librería de nombre Project1, y un main, el cual crea la instancia y manda a llamar al método.Y ahora solo compilamos la clase:

javac HelloWorld.java

Ahora lo que tenemos que hacer es crear un header de C, que contenga la definición de la función que tenemos que implementar, Java tiene una herramienta para esto y entonces vamos a la línea de comandos de nuevo y tecleamos:

javah HelloWorld

Vamos a la carpeta donde estaba nuestra clase y ahi podemos ver que hay un archivo llamado HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_sayHello
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


Este Header contiene la definición de la función que va a llamar la librería, ahora solo tenemos que crear una implementación que lucirá más o menos cómo esto:


#include
#include "HelloWorld.h"
#include

JNIEXPORT void JNICALL
Java_HelloWorld_sayHello(JNIEnv *env, jobject obj)
{
printf("Hello world Im a C Function\n");
return;
}


Y tenemos que compilar esto en un DLL, que es la parte un poco tediosa aunque si ya has usado alguna vez un compilador de C o C++ no tiene gran problema, puedes usar Borland, Blodshed Dev C++ ó el Visual C++. Yo lo compile con el Blodshed Dev C++ y aquí van las instrucciones:

1.- Una vez que tengas el archivo HelloWorld.h, abre el Bloodshed Dev C++ y crea un nuevo proyecto en la misma carpeta donde está el archivo, el proyecto especifica que sea de tipo DLL. (He aquí porque mi dll se llama Project1 jaja)

2.- Ve a Tools->Compiler Options, cuando abra el cuadro de diálogo, ve a la pestaña de Directories y luego a C++ Includes. (o a C includes dependiendo del tipo de proyecto que hayas creado) Ahi haz clic en el botoncito ese que es como una carpetita, y ve hasta donde este instalado tu Java y agrega la siguientes carpetas $JAVA_HOME\include y $JAVA_HOME\include\win32, donde $JAVA_HOME = Directorio donde está instalado tu Java, en mi caso: C:\Program Files\Java\jdk1.6.0_11, entonces mis rutas quedan así:
C:\Program Files\Java\jdk1.6.0_11\include
C:\Program Files\Java\jdk1.6.0_11\include\win32

3.- En el archivo .cpp que crea automáticamente el IDE copia el Siguiente código:

#include
#include "HelloWorld.h"
#include

JNIEXPORT void JNICALL
Java_HelloWorld_sayHello(JNIEnv *env, jobject obj)
{
printf("Hello world Im a C++\n");
return;
}

Y ve a Execute->Compile, y tu programa debe compilar y generar un archivo de nombre "Project1.dll" (o como le hayas puesto al proyecto.

Luego sólo ve a linea de comandos de nuevo y ejecuta:


java HelloWorld


Y el resultado debe ser:
Hello world Im a C Function

Y así has llamado a una función nativa :D Felicidades!

Espero te haya servido

Saludos!

Classpath en Java

Bueno, cuando estamos empezando a programar en Java, siempre existe la pregunta ¿Qué es el Classpath? Bueno, pues es muy simple, como lo dice su nombre es la ruta de clases que serán usadas para compilar y/o ejecutar un programa. Y su función es poder acceder a clases que están fuera del proyecto, cómo alguna librería externa, existen dos principales formas de configurar un Classpath, la 1era es configurar una variable de entorno del sistema de nombre CLASSPATH, y ahi ir colocando cada una de las carpetas o archivos *.jar que tenemos. La 2da es Compilar escribiendo directamente el Classpath como un parámetro al compilador de está forma:


javac -cp "RUTA" HolaMundo.java


Bueno ahora, para encontrar un uso, imaginemos que tenemos una libería de clases en la carpeta C:/lib, y ahí se encuentra la clase "Libreria"


public class Libreria {


public static void imprimir(String mensaje) {
System.out.println(mensaje);
}

}


Ahora imagina que la quieres usar en otro programa :

public class HolaMundo {

public static void main(String[] args) {

Libreria l = new Libreria();
l.imprimir("Hola Mundo");
}

}


Para poder compilar esto, tenemos que indicarle al compilador el CLASSPATH, que va a usar para compilar la clases y para eso hacemos esto:


javac -cp "C:\lib" HolaMundo.java


Y también para correr el programa se requiere especificar el classpath de la misma manera ya que de lo contrario obtendremos NoClassDefFoundError, porque no va a encontrar todas las clases necesarias. Entonces lo que hacemos es algo muy similar, excepto que está vez tenemos que indicar también la ruta en la que estamos y eso se hace con un "punto":


java -cp "C:\lib;." HolaMundo


Y con eso ya podemos corre nuestra clase.


Saludos!

Envío de paquetes entre VLANs

Para poder hacer envio de paquetes entre VLANs tenemos que hacer uso de algún dispositivo de capa 3, ya sea un Router o un Switch de capa 3.

La configuración para un Router Cisco es la siguiente:

Router#(config) interface f0/0.X                   //[ interface.númeroVlan ]

Router#(config-if) encapsulation dot1Q X    //[X = Número VLAN]

Router#(config-if) ip address address mask

Hay que configurar la interfaz f0/0 para cada de las VLANs

Usar cuentas de correo como Live ID

Si tenemos alguna cuenta que no sea "@msn, @hotmail, @live" aún podemos tener acceso a los servicios que ahora todo el suite de Live nos proporciona. Para poder realizar esto tenemos que entrar a:

http://www.passport.net

Le damos click al link donde podemos agregar una cuenta existente, nos pedirá nuestros datos, los agregamos y LISTO! podemos empezar a usar nuestra cuenta de correo (ej. Gmail) para servicios Live.

NOTA: En la parte de la contraseña no es necesaria que sea la misma contraseña que usamos para accesar a nuestro mail, y recordemos que por lo mismo cambios a la contraseña del mail no harán cambios a la contraseña del Live ID

Compilar todo un paquete java

Cuando compilamos un archivo java tenemos que usar la herramienta "javac"

javac Archivo.java

El problema lo tenemos cuando tenemos los archivos en paquetes y tenemos que compilar estos paquetes. Podriamos compiilar archivo por archivo pero tendriamos problema si estos archivos tienen referencias entre ellos por lo que habría compilar en un orden especifico los archivos. Para solucionar esto nos tenemos que poner en el directorio "root" del proyecto y aplicar la herramienta javac:

javac paquete/subpaquete/*.java

Esto nos compilará todo los archivos en ese paquete sin problemas, sin tener que estar compilando uno por uno.

Singleton: Mejorado

El Singleton, que presenté en mi entrada anterior es la implementación más común de un Singleton, sin embargo aun tiene algunos defectos, entre ellos está es que si esa clase la hacemos serializable, en cada ejecución se crearían diferentes instancias del singleton y tendríamos que crear un método para proteger esto. Y también tenemos el problema de que se puede accesar al constructor privado utilizando el API Reflection. Entonces aquí tenemos una forma más elegante de crear un Singleton:







public enum Singleton {

INSTANCE;

public void doSomething() {

}

}





Y luego cuando lo quisieramos usar, lo único que tendríamos que hacer sería esto:




public class Principal {

public static void main(String[] args) {
Singleton.INSTANCE.doSomething();
}

}




Y con eso tenemos una mejor y más sencilla implementación de un Singleton que nos garantiza que siempre será una única instancia.
SaludoSS!



Referencias:

Blooch, J. Effective Java 2nd Edition

Singleton en Java

Bien, un Singleton en términos muy generales es un objeto del cuál sólo podremos tener una instancia (es decir sólo podemos construir un objeto de esa clase durante la ejecución del programa). Programar un Singleton en Java es muy sencillo, lo único que tenemos que hacer es evitar que otras clases tengan acceso al constructor de mi clase singleton, y ¿cómo se hace eso? Pues sólo tenemos que hacer el constructor Privado, y luego hacemos un método que nos regrese la única Instancia creada.



public class Singleton {


//LA UNICA INSTANCIA QUE SERÁ CREADA
//LA CREAMOS DESDE QUE SE CARGUE LA CLASE
private static Singleton instancia = new Singleton();


//HACEMOS EL CONSTRUCTOR PRIVADO
//PARA QUE SÓLO PUEDA INSTANCIA OBJETOS DESDE LA MISMA CLASE
private Singleton() {
}


//MÉTODO PARA OBTENER LA INSTANCIA
public Singleton getInstance() {
return instancia;
}



}





En este ejemplo la instancia se crea, desde que se crea la clase, pero a veces es mejor crear la instancia hasta que se pide, entonces el código quedaría algo así:


public class Singleton {



//CREAMOS LA REFERENCIA
//AUNQUE AL INICIO APUNTA A NULL
private static Singleton instancia ;


//HACEMOS EL CONSTRUCTOR PRIVADO
//PARA QUE SÓLO PUEDA INSTANCIA OBJETOS DESDE LA MISMA CLASE
private Singleton() {
}


//MÉTODO PARA OBTENER LA INSTANCIA
public Singleton getInstance() {
if(instancia==null) //SI ES NULL
instancia = new Singleton(); //LO INSTANCIAMOS
return instancia;
}



}



Y con esto creamos nuestra clase Singleton, Luego ya le podemos programar métodos adicionales que son los servicios que va a ofrecer.

Saludos

Borrar Archivos con Java

Para poder borrar archivos del disco duro, primero tenemos que realizar una clase File

java.io.File file = java.oi.File("String con la ruta");
file.delete();



Este método nos regresa un boolean si es que lo pudo borrar.

En caso de que necesitemos crear archivos temporales y que se borren cuando terminemos el programa, podemos hacer uso de otro método de la clase file.


java.io.File file = java.oi.File("String con la ruta");
file.deleteOnExit();



Este metodo es void, pues como no es instantaneo no puede garantizar el borrado del archivo. Los archivos se borraran cuando el programa que los llamó se cierre.

Introducción a ANT

Nivel: Intermedio

ANT es una herramienta que se utiliza cuándo se está realizando un proyecto de programación y es necesario estar repitiendo tareas repetitivas cómo la compilación y la construcción. Ant está hecho en Java y es muy similar a Make, pero con las ventajas de ser multiplataforma y de no depender de las instrucciones del sistema operativo, sino que se configura con archivos XML. ANT es un proyecto open-source de la Apache Software Foundation.

Bien para comenzar a usar ANT, lo primero que hay que hacer es descargarlo de la página de apache, pueden escribir en google ANT y será alguno de los primeros resultados, sino aquí está la liga:

http://ant.apache.org/bindownload.cgi

Una vez que hayas descargado ANT, descomprime el arcihvo, ve al directorio /bin y agrega ese directorio al PATH de la Computadora, para que de esta forma, lo puedes llamar fácilmente y no tengas que escribir la ruta completa desde la línea de comandos. Probablemente tengas algunos problemas con el nombre de la carpeta, por los puntos y los guiónes medios, lo que yo hice fue cambiarle el nombre de la carpeta, y así el PATH me quedó asi: C:\ant\bin. También es necesario que tengas Java al menos 1.4. Finalmente para comprobar que lo hiciste bien escribe en una línea de comandos (MS-DOS).ant -version

Y si lo configuraste bien entonces verás información acerca de la versión de Ant que hayas descargado, sino está bien configurado te dirá que ant no es un comando reconocido.

Bien, ahora si vamos a la parte de usar ANT :D. Como ya mencione ANT es una herramienta que sirve para realizar procesos que es necesario repetir muchas veces cuándo estamos desarrollando un proyecto, cómo por ejemplo estar compilando y que tengamos una buena organización de directorios, y queremos separar nuestros archivos fuente de los ya compilados. Y que además se genere automáticamente un jar para correrlo.

Para usar ANT lo único que tenemos que hacer es crear un archivo XML de configuración el cual contendrá las instrucciones de que es lo queremos hacer. En ANT tenemos que configurar un target, que es la opción que va a ejecutar y luego las tareas que queremos que realice cuando seleccionemos ese objetivo. Bien para iniciar, vamos a establecer un nuevo proyecto, crearemos una carpeta que se llamara introduccionant, y ahí meteremos dos archivos:

HolaMundo.java (El Archivo que vamos a compilar y correr con ant)
build.xml (El Archivo de configuración de ANT)

HolaMundo.java
public class HolaMundo {

public static void main(String[] args) {

System.out.println("Hola Mundo");

}

}


build.xml


basedir="."
default="compilar">


debug="true"
deprecation="false"
optimize="false"
failonerror="true">






Primero definimos un proyecto, le damos un nombre, le ponemos el directorio base, en este caso es el mismo y por eso estamos poniendo el "." y el Target que por default va a ejecutar es el de nombre compilar. 

Después de eso tenemos que definir el target, el cuál tiene nombre compilar (es el default) Y en seguida se colocan las tareas que queremos realizar, en este caso solo queremos llamar a javac para que compile los archivos, nuestro directorio destino será el mismo y además colocamos unas opciones adicionales. Además cuando usamos javac, es obligatorio que tengamos definido donde están los archivos fuente por eso definimos también el directorio fuente que en este caso y por simplicidad también es el mismo.

Ahora lo único que tenemos que hacer es ir a una línea de comandos ir al directorio introduccionant y ejecutar el comando:

ant

Una vez esto el resultado dirá que el build se ha hecho satisfactoriamente y para los que han usado NetBeans, verán que la salida de consola es igual a la del IDE, esto es porque NetBeans utiliza Ant para hacer el build de nuestros proyectos. Y si vas al directorio utilizando un Explorador verás que tu archivo .class ya fue creado y puedes escribir en la línea de comandos: 

java HolaMundo

Linea de Comandos con Ant

Bien con eso hemos compilado nuestro primer programa utilizando ant, ahora lo único que tenemos que hacer es agregar más opciones a nuestro archivo build.xml para que podamos realizar más cosas utilizando ANT.

Saludos