Introducción a GNU GCJ

java

Si algo he aprendido en el desarrollo de mi proyecto de fin de carrera es a utilizar GNU GCJ, cuáles son sus características, qué puede aportar a Java y cómo se utiliza. Cuando empecé a investigar busqué tutoriales sobre cómo compilar con este software y me encontré con apenas un par de ellos medianamente decentes pero insuficientes para mi propósito, que era compilar una librería de clases bastante grande.

Casi todo lo que he aprendido lo he hecho mirando tutoriales en inglés, leyendo la documentación y puede que aparentemente no sea gran cosa pero no fue sencillo. En esta entrada quiero dejar una introducción al uso básico de GCJ y en un futuro ir completando el manual con algunos posts más.

1 – ¿Por qué GCJ?

En primer lugar debemos preguntarnos qué es GNU GCJ. Este software se desarrolló como alternativa al compilador de Java desarrollado por Sun Microsystems. La idea principal era la de no caer en la trampa de Java promulgada por Richard Stallman en muchos de sus discursos que consiste en que el API de Java fue liberado pero no podemos utilizar Java libremente porque el Java Runtime Enviroment (JRE) no posee las tres libertades básicas.

La problemática de Java es que, según numerosos estudios, es un lenguaje más lento que otros como C/C++ lo que se atribuye principalmente al uso de una máquina virtual para ejecutar código. En Java no compilamos a código nativo sino que compilamos a lo que se conoce como bytecodes, la unidad interpretada por la máquina virtual. Ésta, además de intervenir como inconveniente en el rendimiento, otorga la principal ventaja del lenguaje e idea principal de su desarrollo, la portabilidad.

Con GCJ rompemos, en cierto modo, la idea con la que se concibió el lenguaje ya que cuando compilamos lo hacemos a código objeto nativo en lugar de a bytecodes lo que permite una ejecución directa de las aplicaciones. Aún así, disponemos también de una herramienta libre conocida como GIJ (GNU Interpreter for Java) que es otra implementación de la máquina virtual aunque su rendimiento es verdaderamente malo.

Además de estas características, GCJ incorpora una interfaz conocida como CNI (Compiled Native Interface) que permite mezclar código escrito en C/C++ con código Java mediante pequeñas modificaciones en la sintaxis del lenguaje de modo que, si lo utilizamos para implementar partes críticas de código, conseguiremos programas mucho más rápidos.

En resumen, con GCJ podemos construir aplicaciones Java nativas que, por tanto, no van a necesitar un software adicional para su ejecución. Además, el aspecto más importante es que nuestras aplicaciones serán completamente libres ya que el software ha sido desarrollado bajo licencia GNU GPL.

2 – Un ejemplo sencillo

GCJ viene incorporado en la familia de compiladores GCC que se puede obtener de la página web oficial. Dado que es un software imprescindible en UNIX, está disponible en los repositorios de cualquier distribución de GNU/Linux. El funcionamiento es similar al resto de compiladores, debemos dar un fichero de entrada y se nos proporcionará uno de salida. El software posee su propia implementación del API de Java incluida en una librería llamada libgcj que se instala junto con el compilador.

Como ficheros de entrada se permite código fuente .java, clases compiladas a bytecodes .class y colecciones de clases .jar o .zip.

La salida puede ser bien código objeto sin enlazar o un ejecutable ya enlazado. Como primer ejemplo vamos a compilar el clásico hola mundo de Java. Por el momento, el fichero se ubicará en nuestro HOME; la compilación y ejecución también se hará desde nuestro HOME. El código es el siguiente:

// Fichero HolaMundo.java
public class HolaMundo {
        public static void main(String[] args) {
           System.out.println("¡Hola, mundo!");
        }
 }

Como podemos ver, es el código más simple del mundo, no se utiliza ninguna clase externa, solamente el método System.out.println que es un estándar del API de Java implementado en libgcj. Para compilar y ejecutar la clase tradicionalmente en Java haríamos lo siguiente (previa instalación del JDK de Sun):

 $ javac HolaMundo.java
 $ java HolaMundo
¡Hola, mundo!

Cada clase que componga una librería Java puede implementar un método main propio. Cuando ejecutamos código con la máquina virtual siempre lo hacemos de una clase en concreto pero cuando lo que tenemos es un ejecutable tiene que haber un método main forzosamente y siempre el mismo. Por este motivo es necesario indicar a GCJ qué clase es la que contiene el método principal durante el enlace. Así, la compilación, enlace y ejecución respectivamente sería:

 $ gcj -c HolaMundo.java
 $ gcj --main=HolaMundo HolaMundo.o -c Hola
 $ ./Hola
¡Hola, mundo!

Hasta ahora hemos aprendido cómo se compila una clase simple. Esto es lo más sencillo y se puede encontrar sin mucha dificultad en Internet. El problema surge cuando lo que tenemos es una colección de clases con dependencias cruzadas, cuando esta colección está estructurada en paquetes, cuando queremos automatizar la compilación porque son muchas clases las que queremos compilar, etc.

3 – Próximos posts

Más adelante explicaré cómo es la implementación del CLASSPATH, qué opciones de compilación tenemos disponibles, qué características se comparten con el compilador de C, cómo podemos automatizar la compilación por medio de un Makefile, cómo funcionan las dependencias, etc.

Continuación: El classpath de GCJ.

Espero comentarios si os interesa el tema, un saludo.

Anuncios

5 pensamientos en “Introducción a GNU GCJ

  1. Gracias! lo curioso es que esta entrada es la más vista hasta el momento y nadie ha hecho ningún comentario aparte de ti. Pero bueno… menos trabajo jeje

    Visitad http://plagatux.es !

  2. hola muy interesante tu post, quería agregar también que hace tiempo ya se esta ‘tratando’ de implementar las librerías NO LIBRES de java esta bastante avanzado para ser un reemplazo de uso de las librerías utilizadas en la versión 1.4 de java

    pueden encontrar más información (en ingles) en la pagina del proyecto http://www.gnu.org/software/classpath/

    saludos

  3. Sólo una pequeña observación sobre la línea
    gcj –main=HolaMundo HolaMundo.o -c Hola
    El último paŕametro es -o , no -c…

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s