Archivos de Junio, 2008

Aumentar el tama√Īo de memoria de la m√°quina virtual en Java

24 de Junio de 2008

En Java, hay varios par√°metros para controlar el tama√Īo inicial y el tama√Īo m√°ximo que puede tomar la m√°quina virtual.

Adem√°s, hay que tener en cuenta el tipo de memoria sobre el que se quiere actuar: heap, non-heap (PermGen). Los valores por defecto que se dan corresponden a m√°quina virtuales de Sun, y son orientativos, porque pueden cambiar entre versiones de la m√°quina virtual. Los par√°metros son los siguientes, fij√°ndose a 128Mb.

  • -Xms128m: Tama√Īo de inicio de la m√°quina virtual de Java a 128Mb. El valor por defecto son 64Mb. Si se aumenta este valor, se elimina el tiempo que se tardar√≠a en aumentar el tama√Īo en memoria de la m√°quina virtual si se llegara el caso de que se necesitara m√°s memoria, por lo que aumentar√≠a el rendimiento en los casos que la aplicaci√≥n haga uso intensivo de la memoria.
  • -Xmx128m: Tama√Īo m√°ximo de la m√°quina virtual de Java a 128Mb.¬† El valor por defecto son 128Mb. Si la aplicaci√≥n supera el tama√Īo m√°ximo de memoria que marca este par√°metro, se lanza la excepci√≥n java.lang.OutOfMemoryError.¬† No conviene asignar a este par√°metro el m√°ximo de la memoria de la m√°quina porque si ya no queda memoria f√≠sica disponible (por la que usa el sistema operativo u otras aplicaciones) se pueden producir escrituras en memoria asignada a otros programas y provocar un aut√©ntico l√≠o.
  • -XX:PermSize=128m: Tama√Īo de inicio de la memoria de tipo PermGen a 128Mb. Arrancar la m√°quina virtual con un valor superior al por defecto agiliza la carga de aplicaciones, sobre todo en el caso de aplicaciones que hagan uso intensivo de este tipo de memoria (Spring, Hibernate…)
  • -XX:MaxPermSize=128m: Tama√Īo m√°ximo de la memoria de tipo PermGen a 128Mb. El valor por defecto son 64Mb. Si la aplicaci√≥n supera el tama√Īo m√°ximo de memoria para este tipo que marca este par√°metro, se lanza la excepci√≥n java.lang.OutOfMemoryError: PermGen space. El valor necesario para este par√°metro siempre suele ser menor que el de la memoria de tipo heap.

Si se quiere especificar un valor distinto de 128Mb, que se utiliza para todos los par√°metros como ejemplo para simplificar, bastar√≠a con sustituir el valor 128 del par√°metro con el que se desee, siempre que sean m√ļltiplos de 2 (64, 128, 256, 512, 768, 1024, 2048…)

Conocidos los tipos de memoria y los par√°metros que los controlan, ahora viene la pregunta, ¬Ņc√≥mo especifico estos valores para mi aplicaci√≥n? La respuesta es la misma para todos los casos: Los valores se especifican como par√°metros en el arranque de la m√°quina virtual que ejecutar√° la aplicaci√≥n. La diferencia estribar√° en c√≥mo se arranca la aplicaci√≥n: con un script, desde l√≠nea de comandos, mediante ant…

A continuación se dan distintos ejemplos de modificación de la memoria de distinta forma. No es necesario especificar todos los parámetros, se pueden especificar todos o ninguno (y se tomarían los valores por defecto)

Línea de comandos

  • Ejecuci√≥n de un jar: java -Xms128m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m¬† -jar example.jar
  • Ejecuci√≥n de una clase: java -Xms128m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m¬† com.programacionenjava.examples.MemoryExample

Ant

<java classname=”com.programacionenjava.examples.MemoryExample” fork=”yes” spawn=”true”>
<jvmarg value=”-Xms128m”/>
<jvmarg value=”-Xmx512m”/>
<jvmarg value=”-XX:PermSize=128m”/>
<jvmarg value=”-XX:MaxPermSize=128m”/>
<classpath refid=”execution.classpath”/>
</java>

Script

Si el arranque de la m√°quina virtual se produce en un script, hay que editar el script y a√Īadir estos par√°metros en la sentencia de arranque. El siguiente ejemplo muestra c√≥mo a√Īadir estos par√°metros en el script de arranque de un Tomcat.

  • En Windows: set JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=256m
  • En Linux: JAVA_OPTS=”$JAVA_OPTS -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=256m”

Por √ļltimo, recordamos que resolver el problema de una excepci√≥n de tipo java.lang.OutOfMemoryError simplemente aumentando el tama√Īo de la memoria virtual puede retrasar el problema pero no evitarlo si el problema es una fuga de memoria. Puedes encontrar m√°s informaci√≥n aqu√≠.

Tutorial. Clases en Java

23 de Junio de 2008

Las clases son los elementos fundamentales de Java. Todo en Java forma parte de una clase, es una clase o describe como funciona una clase. El conocimiento de las clases es fundamental para poder entender los programas Java.

Todas las acciones de los programas Java se colocan dentro del bloque de una clase o un objeto. Todos los métodos se definen dentro del bloque de la clase, Java no soporta funciones o variables globales. Así pues, el esqueleto de cualquier aplicación Java se basa en la definición de una clase.

Todos los datos básicos, como los enteros, se deben declarar en las clases antes de hacer uso de ellos. La palabra clave import puede colocarse al principio de un fichero, fuera del bloque de la clase. Es necesario declarar explícitamente las clases que se van a utilizar (import) que no estén dentro del paquete (package) al que pertenece la clase.

Los tipos de clases que podemos definir son:

  • abstract: Una clase abstract tiene al menos un m√©todo abstracto. Una clase abstracta no se instancia, sino que se utiliza como clase base para la herencia.
  • final: Una clase final se declara como la clase que termina una cadena de herencia. No se puede heredar de una clase final. Por ejemplo, la clase Math es una clase final.
  • public: Las clases public son accesibles desde otras clases, bien sea directamente o por herencia. Son accesibles dentro del mismo paquete en el que se han declarado. Para acceder desde otros paquetes, primero tienen que ser importadas.
  • synchronizable: Este modificador especifica que todos los m√©todos definidos en la clase son sincronizados, es decir, que no se puede acceder al mismo tiempo a ellos desde distintos threads; el sistema se encarga de controlar la concurrencia. Este mecanismo hace que desde threads diferentes se puedan modificar las mismas variables sin que haya problemas de que se sobreescriban.

Cuando se crea una nueva clase en Java, se puede especificar el nivel de acceso que se quiere para las variables de instancia y los métodos definidos en la clase:

  • public (public void CualquieraPuedeAcceder(){}): Cualquier clase desde cualquier lugar puede acceder a las variables y m√©todos de instacia p√ļblicos.
  • protected (protected void SoloSubClases(){}): S√≥lo las subclases de la clase y nadie m√°s puede acceder a las variables y m√©todos de instancia protegidos.
  • private (private String NumeroDelCarnetDeIdentidad;) Las variables y m√©todos de instancia privados s√≥lo pueden ser accedidos desde dentro de la clase. No son accesibles desde las subclases.
  • friendly (sin declaraci√≥n espec√≠fica, void MetodoDeMiPaquete(){}) Por defecto, si no se especifica el control de acceso, las variables y m√©todos de instancia se declaran friendly (amigas), lo que significa que son accesibles por todos los objetos dentro del mismo paquete, pero no por los externos al paquete. Es lo mismo que protected.

Resoluci√≥n de Cannot create JDBC driver of class ” for connect URL ‘null’ en Tomcat

19 de Junio de 2008

Durante el arranque de Tomcat, cuando la aplicación web lleva asociada una conexión a una base de datos, uno se puede encontrar un error con el siguiente mensaje

Cannot create JDBC driver of class ” for connect URL ‘null’

Si aparece este mensaje, no se ha iniciado la conexión a la base de datos y, por lo tanto la aplicación no funciona.

Este error se puede dar cuando se realiza un cambio de versión, de un Tomcat 4.1.27/5.0.x a un Tomcat 5.5.x/6.0.x y no se tiene cuidado en adecuar las aplicaciones web a la nueva versión.

El problema viene del cambio de estructura del xml de configuraci√≥n de los contextos, context.xml. Concretamente, el elemento Resource pasa de definirse en 2 elementos, Resource y ResourceParams, a uno solo, Resource, d√≥nde los par√°metros son atributos de este √ļnico elemento. A continuaci√≥n se puede ver la diferencia entre las dos configuraciones para una conexi√≥n a una base de datos en postgres

Tomcat 4.1.27/5.0.x

	<Resource
        name="jdbc/BaseDeDatosPool"
        auth="Container"
        type="javax.sql.DataSource"
    />
    <ResourceParams name="jdbc/BaseDeDatosPool">
        <parameter>
            <name>driverClassName</name>
            <value>org.postgresql.Driver</value>
        </parameter>
        <parameter>
            <name>url</name>
            <value>jdbc:postgresql://127.0.0.1/mibasededatos</value>
        </parameter>
        <parameter>
            <name>username</name>
            <value>postgres</value>
        </parameter>
        <parameter>
            <name>password</name>
            <value></value>
        </parameter>
        <parameter>
            <name>maxActive</name>
            <value>20</value>
        </parameter>
    </ResourceParams>

Tomcat 5.5.X/6.0.x

<Resource name="jdbc/BaseDeDatosPool" auth="Container"
	type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
	url="jdbc:postgresql://127.0.0.1/mibasededatos"
	username="postgres" password="" maxActive="20"/>

Tomcat, al parsear el xml para inicializar el recurso, encuentra un error en el context.xml y la cadena de error que proporciona es Cannot create JDBC driver of class ” for connect URL ‘null’, que en un principio puede despistar porque no resulta claro. Basta con adecuar el xml de configuraci√≥n a la versi√≥n de Tomcat que se est√° utilizando para que deje de producirse.

El error se produce cuando el context.xml est√° malformado en la definici√≥n de recursos, por lo que se puede producir por otras causas diferentes de una cambio de versi√≥n, pero he centrado esta entrada en esta causa porque suele ser la m√°s com√ļn

Separadores en Java

18 de Junio de 2008

Sólo hay un par de secuencias con otros caracteres que pueden aparecer en el código Java; son los separadores simples, que van a definir la forma y función del código. Los separadores admitidos en Java son:

() Рparéntesis. Para contener listas de parámetros en la definición y llamada a métodos. También se utiliza para definir precedencia en expresiones, contener expresiones para control de flujo y rodear las conversiones de tipo.

{} Рllaves. Para contener los valores de matrices inicializadas automáticamente. También se utiliza para definir un bloque de código, para clases, métodos y ámbitos locales.

[] Рcorchetes. Para declarar tipos matriz. También se utiliza cuando se referencian valores de matriz.

; – punto y coma. Separa sentencias.

, Рcoma. Separa identificadores consecutivos en una declaración de variables. También se utiliza para encadenar sentencias dentro de una sentencia for.

. Рpunto. Para separar nombres de paquete de subpaquetes y clases. También se utiliza para separar una variable o método de una variable de referencia.

Arrays en Java

17 de Junio de 2008

Se pueden declarar en Java arrays de cualquier tipo:

	char s[];
	int iArray[];

Incluso se pueden construir arrays de arrays:

	int tabla[][] = new int[4][5];

Los límites de los arrays se comprueban en tiempo de ejecución para evitar desbordamientos y corrupción de memoria.

En Java un array es realmente un objeto, porque tiene redefinido el operador []. Tiene un método: length. Se puede utilizar este método para conocer la longitud de cualquier array.

	int a[][] = new int[10][3];
	a.length;         /* 10 */
	a[0].length;      /*  3 */

Para crear un array en Java hay dos métodos básicos. Crear un array vacío:

	int lista[] = new int[50];

o se puede crear ya el array con sus valores iniciales:

	String nombres[] = {
		"Juan","Pepe","Pedro","Maria"
		};

Esto es equivalente a:

	String nombres[];
	nombres = new String[4];
	nombres[0] = new String( "Juan" );
	nombres[1] = new String( "Pepe" );
	nombres[2] = new String( "Pedro" );
	nombres[3] = new String( "Maria" );

No se pueden crear arrays estáticos en tiempo de compilación:

	int lista[50];  // generará un error en tiempo de compilación

Tampoco se puede rellenar un array sin declarar el tama√Īo con el operador new:

	int lista[];
	for( int i=0; i < 9; i++ )
		lista[i] = i;

Convertir un String en un entero

16 de Junio de 2008

El siguiente trozo de c√≥digo convierte una cadena de texto (“23”), en un entero (int)

   try{
      int i = Integer.parseInt("23")
      int j = Integer.parseInt("aaa")
   }catch(NumberFormatException e){
   }

El método estático parseInt forma parte del jdk de Java, por lo que no es necesario incluir ninguna librería para hacer esta sencilla transformación.

S√≠ que hay que tomar precauciones por si acaso el String que se quiere transformar realmente no es un n√ļmero. En este caso, segunda llamada al m√©todo en el c√≥digo de ejemplo, en el m√©todo saltar√≠a una excepci√≥n del tipo NumberFormatException

Literales en Java

13 de Junio de 2008

Un valor constante en Java se crea utilizando una representación literal de él. Java utiliza cinco tipos de elementos: enteros, reales en coma flotante, booleanos, caracteres y cadenas, que se pueden poner en cualquier lugar del código fuente de Java. Cada uno de estos literales tiene un tipo correspondiente asociado con él.

Enteros:

  • byte¬†¬†¬† 8 bits¬†¬†¬† complemento a dos
  • short¬†¬†¬† 16 bits¬†¬†¬† complemento a¬† dos
  • int¬†¬†¬† 32 bits¬†¬†¬† complemento a dos
  • long¬†¬†¬† 64 bits¬†¬†¬† complemento a dos

Reales en coma flotante:

  • float¬†¬†¬† 32 bits¬†¬†¬† IEEE 754
  • double¬†¬†¬† 64 bits¬†¬†¬† IEEE 754¬†

Booleanos:

  • true
  • false

Caracteres:

¬†Por ejemplo: a¬†¬†¬†¬†¬†¬† \t¬†¬†¬†¬†¬† \u????¬†¬†¬† [????] es un n√ļmero unicode
 
Cadenas:

¬†¬†¬† Por ejemplo: “Esto es una cadena literal”

 

Palabras clave reservadas (keywords)

12 de Junio de 2008

Aquí podéis encontrar un listado de las palabras clave reservadas (keywords)en el lenguaje de programación Java. Estas palabras no se pueden utilizar como identificadores en los programas. Las palabras const y goto están reservadas aunque actualmente no se utilizan. true, false y null, aunque puedan parecer palabras clave, realmente son literales, aunque tampoco los podéis usar en vuestros programas como identificadores.

abstract     continue     for     new     switch
assert***     default     goto*     package     synchronized
boolean     do     if     private     this
break     double     implements     protected     throw
byte     else     import     public     throws
case     enum****     instanceof     return     transient
catch     extends     int     short     try
char     final     interface     static     void
class     finally     long     strictfp**     volatile
const*     float     native     super     while

*           No se usa
** ¬†¬†¬† ¬† ¬†¬†¬† A√Īadido en la versi√≥n 1.2
*** ¬†¬†¬† ¬† ¬†¬†¬† A√Īadido en la versi√≥n 1.4
**** ¬†¬†¬† A√Īadido en la versi√≥n 5.0

Comentarios en Java

11 de Junio de 2008

En Java hay tres tipos de comentarios:

// comentarios para una sola línea
 
/* comentarios de una o
más líneas
*/
 
/** comentario de documentación, de una o más líneas
*/

Los dos primeros tipos de comentarios son los que todo programador conoce y se utilizan del mismo modo. Los comentarios de documentación, colocados inmediatamente antes de una declaración (de variable o función), indican que ese comentario ha de ser colocado en la documentación que se genera automáticamente cuando se utiliza la herramienta de Java, javadoc. Dichos comentarios sirven como descripción del elemento declarado permitiendo generar una documentación de nuestras clases escrita al mismo tiempo que se genera el código.

En este tipo de comentario para documentación, se permite la introducción de algunos tokens o palabras clave, que harán que la información que les sigue aparezca de forma diferente al resto en la documentación.

Tutorial. Características de Java

10 de Junio de 2008

Las características principales que nos ofrece Java respecto a cualquier otro lenguaje de programación, son:

Es SIMPLE :

Java ofrece toda la funcionalidad de un lenguaje potente, pero sin las caracter√≠sticas menos usadas y m√°s confusas de √©stos. C++ es un lenguaje que adolece de falta de seguridad, pero C y C++ son lenguajes m√°s difundidos, por ello Java se dise√Ī√≥ para ser parecido a C++ y as√≠ facilitar un r√°pido y f√°cil aprendizaje.

Java elimina muchas de las caracter√≠sticas de otros lenguajes como C++, para mantener reducidas las especificaciones del lenguaje y a√Īadir caracter√≠sticas muy √ļtiles como el garbage collector (reciclador de memoria din√°mica). No es necesario preocuparse de liberar memoria, el reciclador se encarga de ello y como es un thread de baja prioridad, cuando entra en acci√≥n, permite liberar bloques de memoria muy grandes, lo que reduce la fragmentaci√≥n de la memoria.

Java reduce en un 50% los errores más comunes de programación con lenguajes como C y C++ al eliminar muchas de las características de éstos, entre las que destacan:

  • aritm√©tica de punteros
  • no existen referencias
  • registros (struct)
  • definici√≥n de tipos (typedef)
  • macros (#define)
  • necesidad de liberar memoria (free)

Es ORIENTADO A OBJETOS :

Java implementa la tecnología básica de C++ con algunas mejoras y elimina algunas cosas para mantener el objetivo de la simplicidad del lenguaje. Java trabaja con sus datos como objetos y con interfaces a esos objetos. Soporta las tres características propias del paradigma de la orientación a objetos: encapsulación, herencia y polimorfismo. Las plantillas de objetos son llamadas, como en C++, clases y sus copias, instancias . Estas instancias, como en C++, necesitan ser construidas y destruidas en espacios de memoria.

Java incorpora funcionalidades inexistentes en C++ como por ejemplo, la resoluci√≥n din√°mica de m√©todos. Esta caracter√≠stica deriva del lenguaje Objective C, propietario del sistema operativo Next. En C++ se suele trabajar con librer√≠as din√°micas (DLLs) que obligan a recompilar la aplicaci√≥n cuando se retocan las funciones que se encuentran en su interior. Este inconveniente es resuelto por Java mediante una interfaz espec√≠fica llamada RTTI ( RunTime Type Identification ) que define la interacci√≥n entre objetos excluyendo variables de instancias o implementaci√≥n de m√©todos. Las clases en Java tienen una representaci√≥n en el runtime que permite a los programadores interrogar por el tipo de clase y enlazar din√°micamente la clase con el resultado de la b√ļsqueda.

Es DISTRIBUIDO :

Java se ha construido con extensas capacidades de interconexión TCP/IP. Existen librerías de rutinas para acceder e interactuar con protocolos como http y ftp . Esto permite a los programadores acceder a la información a través de la red con tanta facilidad como a los ficheros locales.

La verdad es que Java en sí no es distribuido, sino que proporciona las librerías y herramientas para que los programas puedan ser distribuidos, es decir, que se corran en varias máquinas, interactuando.

Es ROBUSTO :

Java realiza verificaciones en busca de problemas tanto en tiempo de compilaci√≥n como en tiempo de ejecuci√≥n. La comprobaci√≥n de tipos en Java ayuda a detectar errores, lo antes posible, en el ciclo de desarrollo. Java obliga a la declaraci√≥n expl√≠cita de m√©todos, reduciendo as√≠ las posibilidades de error. Maneja la memoria para eliminar las preocupaciones por parte del programador de la liberaci√≥n o corrupci√≥n de memoria. Tambi√©n implementa los arrays aut√©nticos , en vez de listas enlazadas de punteros, con comprobaci√≥n de l√≠mites, para evitar la posibilidad de sobreescribir o corromper memoria resultado de punteros que se√Īalan a zonas equivocadas. Estas caracter√≠sticas reducen dr√°sticamente el tiempo de desarrollo de aplicaciones en Java.

Además, para asegurar el funcionamiento de la aplicación, realiza una verificación de los byte-codes , que son el resultado de la compilación de un programa Java. Es un código de máquina virtual que es interpretado por el intérprete Java. No es el código máquina directamente entendible por el hardware, pero ya ha pasado todas las fases del compilador: análisis de instrucciones, orden de operadores, etc., y ya tiene generada la pila de ejecución de órdenes.

Java proporciona, pues:

  • Comprobaci√≥n de punteros
  • Comprobaci√≥n de l√≠mites de arrays
  • Excepciones
  • Verificaci√≥n de byte-codes

Es de ARQUITECTURA NEUTRAL :

Para establecer Java como parte integral de la red, el compilador Java compila su código a un fichero objeto de formato independiente de la arquitectura de la máquina en que se ejecutará. Cualquier máquina que tenga el sistema de ejecución ( run-time ) puede ejecutar ese código objeto, sin importar en modo alguno la máquina en que ha sido generado. Actualmente existen sistemas run-time para Solaris, SunOs, Windows, Windows NT, Linux, Irix, Aix, Mac, Apple y probablemente haya grupos de desarrollo trabajando en el portado a otras plataformas.

El c√≥digo fuente Java se “compila” a un c√≥digo de bytes de alto nivel independiente de la m√°quina. Este c√≥digo (byte-codes) est√° dise√Īado para ejecutarse en una m√°quina hipot√©tica que es implementada por un sistema run-time, que s√≠ es dependiente de la m√°quina.

Es SEGURO :

La seguridad en Java tiene dos facetas. En el lenguaje, caracter√≠sticas como los punteros o el casting impl√≠cito que hacen los compiladores de C y C++ se eliminan para prevenir el acceso ilegal a la memoria. Cuando se usa Java para crear un navegador, se combinan las caracter√≠sticas del lenguaje con protecciones de sentido com√ļn aplicadas al propio navegador.

El lenguaje C, por ejemplo, tiene lagunas de seguridad importantes, como son los errores de alineaci√≥n . Los programadores de C utilizan punteros en conjunci√≥n con operaciones aritm√©ticas. Esto le permite al programador que un puntero referencie a un lugar conocido de la memoria y pueda sumar (o restar) alg√ļn valor, para referirse a otro lugar de la memoria. Si otros programadores conocen nuestras estructuras de datos pueden extraer informaci√≥n confidencial de nuestro sistema. Con un lenguaje como C, se pueden tomar n√ļmeros enteros aleatorios y convertirlos en punteros para luego acceder a la memoria:

printf( “Escribe un valor entero: ” );
scanf( “%u”,&puntero );
printf( “Cadena de memoria: %sn”,puntero );

Otra laguna de seguridad u otro tipo de ataque, es el Caballo de Troya . Se presenta un programa como una utilidad, resultando tener una funcionalidad destructiva. Por ejemplo, en UNIX se visualiza el contenido de un directorio con el comando ls . Si un programador deja un comando destructivo bajo esta referencia, se puede correr el riesgo de ejecutar código malicioso, aunque el comando siga haciendo la funcionalidad que se le supone, después de lanzar su carga destructiva. Por ejemplo, después de que el caballo de Troya haya enviado por correo el /etc/shadow a su creador, ejecuta la funcionalidad de ls persentando el contenido del directorio. Se notará un retardo, pero nada inusual.

El código Java pasa muchos tests antes de ejecutarse en una máquina. El código se pasa a través de un verificador de byte-codes que comprueba el formato de los fragmentos de código y aplica un probador de teoremas para detectar fragmentos de código ilegal -código que falsea punteros, viola derechos de acceso sobre objetos o intenta cambiar el tipo o clase de un objeto-.

Si los byte-codes pasan la verificaci√≥n sin generar ning√ļn mensaje de error, entonces sabemos que:

  • El c√≥digo no produce desbordamiento de operandos en la pila
  • El tipo de los par√°metros de todos los c√≥digos de operaci√≥n son conocidos y correctos
  • No ha ocurrido ninguna conversi√≥n ilegal de datos, tal como convertir enteros en punteros
  • El acceso a los campos de un objeto se sabe que es legal: public, private, protected
  • No hay ning√ļn intento de violar las reglas de acceso y seguridad establecidas

El Cargador de Clases también ayuda a Java a mantener su seguridad, separando el espacio de nombres del sistema de ficheros local, del de los recursos procedentes de la red. Esto limita cualquier aplicación del tipo Caballo de Troya , ya que las clases se buscan primero entre las locales y luego entre las procedentes del exterior.

Las clases importadas de la red se almacenan en un espacio de nombres privado, asociado con el origen. Cuando una clase del espacio de nombres privado accede a otra clase, primero se busca en las clases predefinidas (del sistema local) y luego en el espacio de nombres de la clase que hace la referencia. Esto imposibilita que una clase suplante a una predefinida.

En resumen, las aplicaciones de Java resultan extremadamente seguras, ya que no acceden a zonas delicadas de memoria o de sistema, con lo cual evitan la interacci√≥n de ciertos virus. Java no posee una sem√°ntica espec√≠fica para modificar la pila de programa, la memoria libre o utilizar objetos y m√©todos de un programa sin los privilegios del kernel del sistema operativo. Adem√°s, para evitar modificaciones por parte de los crackers de la red, implementa un m√©todo ultraseguro de autentificaci√≥n por clave p√ļblica. El Cargador de Clases puede verificar una firma digital antes de realizar una instancia de un objeto. Por tanto, ning√ļn objeto se crea y almacena en memoria, sin que se validen los privilegios de acceso. Es decir, la seguridad se integra en el momento de compilaci√≥n, con el nivel de detalle y de privilegio que sea necesario.

Dada, pues la concepci√≥n del lenguaje y si todos los elementos se mantienen dentro del est√°ndar marcado por Sun, no hay peligro. Java imposibilita, tambi√©n, abrir ning√ļn fichero de la m√°quina local (siempre que se realizan operaciones con archivos, √©stas trabajan sobre el disco duro de la m√°quina de donde parti√≥ el applet), no permite ejecutar ninguna aplicaci√≥n nativa de una plataforma e impide que se utilicen otros ordenadores como puente, es decir, nadie puede utilizar nuestra m√°quina para hacer peticiones o realizar operaciones con otra. Adem√°s, los int√©rpretes que incorporan los navegadores de la Web son a√ļn m√°s restrictivos. Bajo estas condiciones (y dentro de la filosof√≠a de que el √ļnico ordenador seguro es el que est√° apagado, desenchufado, dentro de una c√°mara acorazada en un bunker y rodeado por mil soldados de los cuerpos especiales del ej√©rcito), se puede considerar que Java es un lenguaje seguro y que los applets est√°n libres de virus.

Respecto a la seguridad del código fuente, no ya del lenguaje, JDK proporciona un desemsamblador de byte-code, que permite que cualquier programa pueda ser convertido a código fuente, lo que para el programador significa una vulnerabilidad total a su código. Utilizando javap no se obtiene el código fuente original, pero sí desmonta el programa mostrando el algoritmo que se utiliza, que es lo realmente interesante. La protección de los programadores ante esto es utilizar llamadas a programas nativos, externos (incluso en C o C++) de forma que no sea descompilable todo el código; aunque así se pierda portabilidad. Esta es otra de las cuestiones que Java tiene pendientes.

Es PORTABLE :

Más allá de la portabilidad básica por ser de arquitectura independiente, Java implementa otros estándares de portabilidad para facilitar el desarrollo. Los enteros son siempre enteros y además, enteros de 32 bits en complemento a 2. Además, Java construye sus interfaces de usuario a través de un sistema abstracto de ventanas de forma que las ventanas puedan ser implantadas en entornos Unix, Pc o Mac.

Es INTERPRETADO :

El intérprete Java (sistema run-time) puede ejecutar directamente el código objeto. Enlazar (linkar) un programa, normalmente, consume menos recursos que compilarlo, por lo que los desarrolladores con Java pasarán más tiempo desarrollando y menos esperando por el ordenador.

Existe la idea inexacta de que Java es más lento en ejecución que otros lenguajes por ser interpretado, pero las continuas mejoras que Sun realiza en las máquinas virtuales y la arquitectura del sistema, hacen que esa idea preconcebida ya no sea cierta. Java puede ser comparado en términos de velocidad con otros lenguajes de alto nivel.

La verdad es que Java para conseguir ser un lenguaje independiente del sistema operativo y del procesador que incorpore la m√°quina utilizada, es tanto interpretado como compilado. Y esto no es ning√ļn contrasentido, me explico, el c√≥digo fuente escrito con cualquier editor se compila generando el byte-code. Este c√≥digo intermedio es de muy bajo nivel, pero sin alcanzar las instrucciones m√°quina propias de cada plataforma y no tiene nada que ver con el p-code de Visual Basic. El byte-code corresponde al 80% de las instrucciones de la aplicaci√≥n. Ese mismo c√≥digo es el que se puede ejecutar sobre cualquier plataforma. Para ello hace falta el run-time, que s√≠ es completamente dependiente de la m√°quina y del sistema operativo, que interpreta din√°micamente el byte-code y a√Īade el 20% de instrucciones que faltaban para su ejecuci√≥n. Con este sistema es f√°cil crear aplicaciones multiplataforma, pero para ejecutarlas es necesario que exista el run-time correspondiente al sistema operativo utilizado.

Es MULTITHREADED :

Al ser multithreaded (multihilo), Java permite muchas ejecuciones simult√°neas en un programa. Los threads (a veces llamados, procesos ligeros), son b√°sicamente peque√Īos procesos o piezas independientes de un gran proceso. Al estar los threads contruidos en el lenguaje, son m√°s f√°ciles de usar y m√°s robustos que sus hom√≥logos en C o C++.

El beneficio de ser miltithreaded consiste en un mejor rendimiento interactivo y mejor comportamiento en tiempo real. Aunque el comportamiento en tiempo real est√° limitado a las capacidades del sistema operativo subyacente (Unix, Windows, etc.), a√ļn supera a los entornos de flujo √ļnico de programa (single-threaded) tanto en facilidad de desarrollo como en rendimiento.

Cualquiera que haya utilizado la tecnología de navegación concurrente, sabe lo frustrante que puede ser esperar por una gran imagen que se está trayendo. En Java, las imágenes se pueden ir trayendo en un thread independiente, permitiendo que el usuario pueda acceder a la información en la página sin tener que esperar por el navegador.

Es DINAMICO :

Java se beneficia todo lo posible de la tecnología orientada a objetos. Java no intenta conectar todos los módulos que comprenden una aplicación hasta el tiempo de ejecución.