Programación Cliente-Servidor  

Posted by Danny in

Java es un nuevo lenguaje de programación, como tantos otros. Así que uno se pregunta el por qué del revuelo que se ha formado con su aparición. La respuesta no es inmediatamente obvia si se observa el asunto desde el punto de vista de la programación tradicional, porque aunque resuelve algunos de los problemas típicos de este tipo de programación, lo que verdaderamente es importante es que también resuelve los problemas que se generan en Internet, en la Telaraña Mundial, en el World-Wide-Web, en la Web.

Internet puede resultar algo misterioso al principio, sobre todo porque se utiliza un vocabulario propio, que hasta que no se domina, uno anda un poco despistado. Pero, en esencia, Internet es un sistema Cliente-Servidor gigante. La idea primaria de un sistema cliente-servidor es que debe haber un sitio donde se centraliza la información, que se desea distribuir bajo demanda a un conjunto de personas o máquinas.

La clave de este concepto radica en que si se produce un cambio en la información del sistema central, inmediatamente es propagada a los receptores de la información, a la parte cliente. Luego, el concepto básico es muy simple; el problema se presenta cuando hay solamente un servidor que tiene colgados a muchos clientes, en que el rendimiento general del sistema decrece de forma exponencial al aumento del número de clientes.

El funcionamiento de la Web sigue este mismo principio. Inicialmente, se solicita una información a un servidor y éste envía de vuelta un fichero que será interpretado por el navegador (el cliente) que lo formateará para visualizarlo en la máquina cliente. El navegador fue el primer paso adelante en la expansión de Internet, ya que permitía visualizar un mismo fichero en plataformas diferentes sin hacerle cambio alguno; pero su finalidad principal es la visualización de ficheros, no la interactividad con el usuario, ni la posibilidad de ejecutar programas en la parte del usuario, en la parte cliente del sistema.

Para proporcionar un poco de interactividad, se dotó al lenguaje HTML de ciertos mecanismos básicos de entrada de datos, como botones, cajas de selección, campos de texto, y algunos otros; pero la carga que incorporaban al sistema caía del todo dentro del lado del servidor, con lo cual, si había muchos clientes colgando, el colapso del servidor era casi seguro. Así que surgieron algunas alternativas a los CGI, para que se pudiese descargar al servidor de tanto trabajo y que el cliente realizase también operaciones.

Plug-ins

Esto son piezas de código que se incorporan al navegador y le indican que "a partir de ahora dispones de una nueva característica". Hay carasterísticas que se añaden a los navegadores a través de plug-ins que son muy rápidas y eficientes, pero el problema es que escribir un plug-in no es una tarea trivial ni tampoco es algo que haya que hacer en el proceso de construcción de un Site. Luego los pulg-ins son herramientas válidas para programadores muy expertos que permiten incorporar características nuevas al navegador sin necesidad de que el vendedor conceda su permiso.

Scripts

Un lenguaje script permite embeber código fuente para la programación del lado cliente, directamente en la página HTML, y el plug-in que interpreta ese lenguaje se activará automáticamente cuando se cargue en el navegador. Estos lenguajes tienden a ser muy simples y sencillos, además se cargan muy rápidamente porque van incluidos en la página que envía el servidor. La pega es que el código del programador está expuesto a la vista de cualquiera, aunque tampoco se pueden hacer demasiadas filigranas con un lenguaje script.

Estos lenguajes se utilizan fundamentalmente para hacer más atractivos los interfaces gráficos de las páginas, porque disponen de elementos gráficos y pueden llegar a resolver el 80% de los problemas que se plantean en la programación de la parte cliente del sistema cliente-servidor; y, además, son lenguajes mucho más sencillos de aprender e implementar soluciones con ellos que recurrir a Java o ActiveX. Siempre que los problemas del caigan dentro de ese 80% que son capaces de resolver los lenguajes script, y el programador se encuentre cómodo con este tipo de lenguajes, serían la elección prioritaria, antes de adentrarse en las profundidades que representa siempre el estudio de un nuevo lenguaje de programación.

El lenguaje script más utilizado es JavaScript, que no tiene nada que ver con Java, me imagino que se llamará así para aprovechar el tirón de popularidad de Java, pero también se pueden realizar scripts en la parte cliente con Visual Basic o con Tcl/Tk.

Java

¿Y qué pasa con el 20% de los problemas que no pueden resolver los lenguajes script? La respuesta más común, si se hiciese una encuesta, sería Java, y no solamente porque sea un poderoso lenguaje de programación enfocado a la seguridad, multi-plataforma e internacional, sino porque Java está siendo continuamente extendido para proporcionarle nuevas características y librerías que resuelven elegantemente problemas que son muy difíciles en la programación tradicional como el acceso a bases de datos, el uso de multihilo, la programación de redes y la programación distribuida, y además porque Java, a través de los applets, permite la programación de la parte cliente.

Un applet es un miniprograma que corre solamente bajo un navegador y es descargado automáticamente como parte de una página Web, al igual que cualquier gráfico, y cuando se activa, ejecuta un programa. Este es el interés, proporciona una forma a través de la cual se puede distribuir software al cliente desde el servidor, en el momento en que el cliente necesite ese software, y no antes, con lo cual siempre tendrá el cliente la última versión de ese software, se actualice cuando se actualice. Además, tal como está diseñado Java, el programador necesita crear su programa una sola vez, y ya estará listo para ser ejecutado en todas las plataformas que dispongan de un navegador con soporte Java.

Con Java se podrá realizar tanto trabajo como sea posible en el cliente antes y después de hacer peticiones al servidor. Por ejemplo, se puede evitar el enviar una petición a través de Internet mientras el usuario no haya introducido los parámetros correctos de esa petición, que estará chequeando el cliente, sin necesidad de tener que consultar continuamente al servidor; con ello se gana en velocidad de respuesta ante el usuario, una reducción general en el tráfico de red y una gran descarga de trabajo para el servidor.

Una de las ventajas de los applets sobre los scripts es que están en forma compilada, con lo cual el código fuente no es visible; aunque se puede descompilar sin demasiadas complicaciones, pero vamos, no está del todo accesible. Además, un applet puede comprimir varios módulos, utilizando ficheros JAR, evitando múltiples conexiones con el servidor, ya que en una sola se descargan todos los componentes necesarios.

Y, finalmente, está la curva de aprendizaje, porque a pesar de lo que el lector haya podido escuchar o leer por ahí, Java no es un lenguaje trivial. Si el lector domina Visual Basic, por ejemplo, el que realice sus trabajos en VBscript le resultará más fácil y rápido y resolverá sus problemas de programación cliente-servidor sin embarcarse en la dura empresa de aprender Java.

ActiveX

La competencia directa de Java es ActiveX, de Microsoft, aunque su enfoque sea bastante diferente. ActiveX es originalmente una solución orientada a entornos Windows, aunque parece ser que ahora está siendo desarrollado para ser multiplataforma. Lo que hace ActiveX es decir "si tu programa se conecta a este entorno, se podrá descargar en una página Web y correr bajo un navegador que soporte controles ActiveX". Microsoft Internet Explorer soporta ActiveX directamente y Netscape lo soporta a través de plug-in. Por lo tanto, ActiveX no está constreñido a un solo lenguaje de programación, sino que se pueden desarrollar componentes ActiveX en el lenguaje que domine el programador, ya sea C++, Visual Basic o el Delphi de Borland.

Scriptlets

Microsoft ha subido una vez más la apuesta en su batalla contra Java con el lanzamiento de los scriplets, que son similares en naturaleza a los componentes JavaBeans, y aparecen como una campaña de vaporware por parte de Microsoft. Su aparente meta es posicionar esta tecnología como un potencial rival multiplatafroma de Java, que, según dice Microsoft, no cumple su compromiso de ser tan manejable como propugna su publicidad. Los scriptlets, a diferencia de Java, sólo se pueden utilizar sobre un navegador Web. Si bien es cierto que a los applets les ocurre lo mismo, Java deja abierta la posibilidad de crear aplicaciones, dependientes de una máquina virtual Java, pero no de un navegador; y en cuanto la máquina virtual Java se encuentra incluida en el propio sistema operativo, el usuario no advierte dependencia alguna. La verdad es que los scriptlets no aportan nada nuevo a las posibilidades de las herramientas actuales, sino que son otra forma de hacer lo mismo.

La descarga y ejecución automática de programas a través de Internet, en principio, suena como el sueño de cualquier creador de virus. Los componentes ActiveX son especialmente sensibles a este ataque, ya que se puede hacer lo que se quiera, sin control alguno, con lo cual, el usuario puede bajarse un componente ActiveX que haga estragos en su máquina. Esto no es nuevo, sino que es un problema largamente conocido desde los tiempos de las BBS, pero que aquí se ve amplificado por la velocidad de Internet.

Cuando se pide una página Web, se reciben ficheros gráficos, el código de la página (con o sin scripts), código Java precompilado y componentes ActiveX. De estos, algunos son casi inofensivos, como los ficheros gráficos y el código HTML de la página, porque es muy poco lo que se puede manipular sobre ellos. Java está diseñado para ejecutar los applets en una caja cerrada (sand box), envuelta en una capa de seguridad que impide cualquier acceso a disco o a memoria que se encuentre fuera de esa caja cerrada. Así que, la parte más propensa a introducir elementos no deseados en la máquina cliente son los componentes ActiveX.

Actualmente se está intentando paliar esta desagradable posibilidad a través de las firmas digitales, que permiten reconocer al autor. Esta idea parte de que los autores de virus normalmente son anónimos, y si se eliminan estos componentes anónimos, siempre se podrá forzar al programador a que sea responsable de sus acciones. Puede se una buena idea, porque permitirá a los programas ser más funcionales, aunque si un programa tiene un bug inadvertido que pueda resultar destructivo, todavía podrá causar problemas.

Con respecto a Java, hay diversas opiniones respecto a la draconiana restricción a que un applet no pueda escribir en el disco local del cliente; porque, que pasa si el usuario quiere crear una base de datos local, o quiere guardar cualquier tipo de información para cuando se encuentre desconectado de Internet. La asunción inicial de que todo el mundo estaría conectado es impracticable, aunque si se redujesen los precios del teléfono, pudiese llegar a ser el estado normal de muchos usuarios; así que la solución debe llegar por otra vía. Los applets firmados, que utilizan una clave pública para comprobar que el applet viene del lugar correcto y no ha sido manipulado puede ser una de esas soluciones. Desde Java 1.1 se dispone de un entorno para implementar firmas digitales, por lo que si fuese necesario se podría hacer que un applet se saliese de su caja cerrada.

Mas de Java  

Posted by Danny in

El uso principal que se hace de Internet e incluso de las redes internas (corporativas) es correo electrónico (e-mail), aunque actualmente hay un auge sorprendente de la navegación web. Los documentos web pueden contener variedad de texto, gráficos de todas clases y proporcionar enlaces hipertexto hacia cualquier lugar de la red. Los navegadores utilizan documentos escritos en lenguaje HTML. La combinación actual de navegadores HTML/WWW están limitados pues a texto y gráficos. Si se quiere reproducir un sonido o ejecutar un programa de demostración, primero hemos de bajarnos (download) el fichero en cuestión y luego utilizar un programa en nuestro ordenador capaz de entender el formato de ese fichero, o bien cargar un módulo (plug-in) en nuestro navegador para que pueda interpretar el fichero que hemos bajado.

Hasta ahora, la única forma de realizar una página web con contenido interactivo, era mediante la interfaz CGI (Common Gateway Interface), que permite pasar parámetros entre formularios definidos en lenguaje HTML y programas escritos en Perl o en C. Esta interfaz resulta muy incómoda de programar y es pobre en sus posibilidades.

El lenguaje Java y los navegadores con soporte Java, proporcionan una forma diferente de hacer que ese navegador sea capaz de ejecutar programas. Con Java se puede reproducir sonido directamente desde el navegador, se pueden visitar home pages con animaciones, se puede enseñar al navegador a manejar nuevos formatos de ficheros, e incluso, cuando se pueda transmitir video por las líneas telefónicas, nuestro navegador estará preparado para mostrar esas imágenes.

Utilizando Java, se pueden eliminar los inconvenientes de la interfaz CGI y también se pueden añadir aplicaciones que vayan desde experimentos científicos interactivos de propósito educativo, a juegos o aplicaciones especializadas para la televenta. Es posible implementar publicidad interactiva y periódicos personalizados. Por ejemplo, alguien podría escribir un programa Java que implementara una simulación química interactiva -una cadena de adn-. Utilizando un navegador con soporte Java, un usuario podría recibir fácilmente esa simulación e interaccionar con ella, en lugar de conseguir simplemente un dibujo estático y algo de texto. Lo recibido cobra vida. Además, con Java podemos estar seguros de que el código que hace funcionar el experimento químico no contiene ningún trozo de código malicioso que dañe al sistema. El código que intente actuar destructivamente o que contenga errores, no podrá traspasar los muros defensivos colocados por las características de seguridad y robustez de Java.

Además, Java proporciona una nueva forma de acceder a las aplicaciones. El software viaja transparentemente a través de la red. No hay necesidad de instalar las aplicaciones, ellas mismas vienen cuando se necesitan. Por ejemplo, la mayoría de los navegadores del Web pueden procesar un reducido número de formatos gráficos (típicamente GIF y JPEG). Si se encuentran con otro tipo de formato, el navegador estándar no tiene capacidad para procesarlo, tendría que ser actualizado para poder aprovechar las ventajas del nuevo formato. Sin embargo, un navegador con soporte Java puede enlazar con el servidor que contiene el algoritmo que procesa ese nuevo formato y mostrar la imagen. Por lo tanto, si alguien inventa un nuevo algoritmo de compresión para imágenes, el inventor sólo necesita estar seguro de que hay una copia en código Java de ese algoritmo instalada en el servidor que contiene las imágenes que quiere publicar. Es decir, los navegadores con soporte Java se actualizan a sí mismos sobre la marcha, cuando encuentran un nuevo tipo de fichero o algoritmo.

En esta filosofía es en la que se basan los NC (Network Computer), que serán ordenadores sin disco y con mucha memoria. Sus programas residen en un servidor que se los envía cuando los solicita. Es quizá un guiño al pasado y una versión futurista de lo que ha sido un Terminal-X en otros tiempos, salvando las diferencias, evidentemente (no sea que alguien me tilde de irreverente con las nuevas tecnologías).

Portabilidad de Java  

Posted by Danny in

Java es una palabra que actualmente está en boca de todos y ha creado una auténtica revolución. Nosotros nos enfocaremos al lenguaje Java, y la verdad es que no es para tanto el armar ese revuelo. Verdad es que Java es una gran idea, pero, no escandalosamente genial. Quizá todo se haya visto magnificado por Internet, pero Java se anuncia como un lenguaje completo de propósito general y, bueno, hay ciertas porciones del mismo que no están definidas o son discutibles, y algunas características son ciertamente oscuras. A lo largo del Tutorial iremos presentando todas esas cosas.

La creación de este Tutorial ha partido de la necesidad de aprendizaje del lenguaje Java para implantarlo en aplicaciones críticas. Se necesitaba una evaluación del lenguaje para comprobar si podría emplearse en el desarrollo de pequeñas aplicaciones (no necesariamente con Internet por medio, aunque también). Esto ha hecho que hayamos investigado en muchas fuentes, principalmente de Sun Microsystems, y obtenido las conclusiones a que queríamos llegar. Que resumiendo vienen a indicarnos que, tal como se encuentra definido Java actualmente y con las herramientas que hay, si no hay interés en Internet, lo mejor es olvidarse de Java. Aunque pronto pueda que esta afirmación sea falsa, dado el empeño que todo el mundo está poniendo en llevar a Java a buen puerto, pero la decisión del grupo que hemos formado fue descartar Java (momentáneamente).

En toda esta historia nos hemos dado cuenta de que falta literatura en castellano; como siempre, vamos a remolque. Por ello ha sido el desarrollar este Tutorial de Java, que esperamos (espero) humildemente, sea de provecho para alguien. Eso sería ya una gran satisfacción para mí. Quizá yo no sea la persona más indicada para estar escribiendo esto, porque todavía soy y siempre me consideraré un principiante en Java, pero sí que puedo transmitir los pocos conocimientos que he adquirido, y eso es lo que haré.

Todas las sugerencias que alguien pueda ofrecer, serán bienvenidas. Prometo contestar a todo el mundo, si no me sobrepasa el correo. Y me gustaría que pudiésemos ir haciendo crecer este Tutorial de Java entre mucha más gente. No obstante, la experiencia de muchos años de BBS me dice que hay mucho escuchador y poco participador, por lo que el Tutorial esta casi planteado en un noventa por ciento. Aunque, repito, todas las colaboraciones serán bienvenidas y si van con el estilo, incluidas en el Tutorial de Java que arranca aquí.

Y una recomendación final, antes de que alguien se decida a publicar un applet nada más terminar de leerse éste u otro Tutorial sobre Java. Hay que ser críticos con nuestro trabajo. Debemos valorar mucho nuestra estima y, por ende, el código que escribimos bajo nuestro nombre. Actualmente hay muchos applets que se pueden visualizar y, desgraciadamente, bastantes de ellos son de muy baja calidad, escritos por programadores que están dando sus primeros balbuceos en Java. Más que applets son crapplets (crap es una forma coloquial de mierda), algunos de ellos incluso se quedan colgados o no tienen un rendimiento mínimo aceptable. Debemos renunciar a una excesiva rapidez de desarrollo en beneficio de un código fiable y bien diseñado. Y parafraseando palabras de Alex Newman, director ejecutivo de Sun User Group/Java: "Hay un montón de buenos programadores que no se dedican a ir por ahí vendiendo código. Lo que hacen es buscar trabajo. Saber programar en Java será algo positivo para incluir en el currículum".

No obstante, y para que todos tengamos una idea general de lo que es Java, haremos una serie de aclaraciones o indicaciones, para que alguien que no esté muy decidido a aprender Java, pueda tener elementos de juicio y de comparación para tomar esa decisión. Por ello, haremos una introducción más extensa de lo que sería habitual en un Tutorial, lo que también me permitirá verter ciertas opiniones que en otro sitio no tendrían cabida.

Esta es la segunda versión del Tutorial de Java corregida, ampliada y readaptada para acomodarse a las nuevas características introducidas a Java por Sun desde la versión 1.1 del Java Development Kit (JDK) y adaptándose en todo lo posible a la versión 1.2. He revisado todo el código fuente, he añadido algunos ejemplos más en las partes en las que más consultas he tenido y también, en respuesta a demanda, he incorporado algunas secciones, que aunque no son tan básicas como pretendo yo con el Tutorial, sí parece que resultan muy interesantes a la mayoría de los lectores de la versión anterior del Tutorial (que todavía se puede encontrar en la dirección http://www.fie.us.es/info/internet/JAVA/).

ESTA NO ES UNA TRADUCCION DEL "JAVA TUTORIAL" DE SUN Microsystems, POR LO QUE LOS TEMAS QUE SE TRATAN SON LOS QUE A MI ME PARECEN MAS INTERESANTES. TAMPOCO ME UNE NINGUN TIPO DE RELACION CON SUN NI CON NINGUNA DE SUS FILIALES.

Quien vaya a desarrollar applets para su publicación en Internet y pretenda que llegue a la mayoría de navegantes que aterricen en su página, ha de saber que si desarrolla con el JDK 1.1.X, y más con el JDK 1.2, sus applets no podrán verse con una versión inferior a la 4.0 de los navegadores más extendidos, Netscape y Microsoft Explorer. E incluso estos navegadores no tienen soporte total del JDK 1.1.X, a fecha de hoy.

El JDK 1.1 fue un tremendo paso adelante en la evolución de Java y en el JDK 1.2 se han incorporado a la Plataforma Java muchas de las APIs que estaban en versiones individuales. El rendimiento y estabilidad de Java son mucho más sólidos, y los JavaBeans van a representar un modelo a seguir por muchas empresas. También el movimiento 100% Pure Java asegurará que los applets que hoy se están desarrollando, funcionarán en cualquier entorno del mañana, y no todo el mundo puede precisar algo semejante. Creo que nunca una tecnología nueva ha sido adoptada por tanta gente en tan poco tiempo.

Las críticas que se hacen a Java de que no está completamente definido y de que sus capacidades dejan bastante que desear, deben hacer reflexionar a quienes las predican, porque es menester recordar que el rendimiento es un camino no una meta, siempre estamos en condiciones de mejorar algo, sea lo que sea. Y tal como se está moviendo el mercado entorno a Java, pronto veremos que Java entra de verdad en el mundo de los negocios y su estabilidad se verá infinitamente más robustecida.

Conocimientos Previos

En el planteamiento inicial se supone que tú, que estás leyendo esto, tienes experiencia en algún lenguaje de programación, como puede ser C o un lenguaje similar, también que sabes utilizar un navegador de WWW como Netscape o Internet Explorer, también que eres capaz de desarrollar páginas WWW con HTML y comprendes la programación orientada a objetos. Intentaré que estos conocimientos sean suficientes para poder seguir el Tutorial. Haré referencias a C++ para la mejor comprensión de lo que hace diferente a Java, porque muchos de los lectores del anterior Tutorial tenían conocimientos de C++, y la mayoría de las consultas que se me hacen van en esa orientación.

El entorno de desarrollo habitual entre la gente que trabajamos con el JDK (los pobres sin poder para comprarse herramientas comerciales) consiste en tener abiertas sobre el escritorio de la pantalla, ya sea en Solaris, Windows '95/NT o Linux, varias ventanas, que usamos para lo siguiente:

  • En una de ellas tenemos abierto HotJava, apuntando al fichero packages.html de la documentación del API de Java, para poder tener al momento la información sobre los parámetros de llamada, valores de retorno y la información de cada una de las funciones que estemos utilizando.
  • Los que estén desarrollando sobre Windows '95 o NT, podrán disponer de la documentación del API también desde el sistema de ayuda de Windows si han descargado esta documentación en formato Winhelp desde Dippy.
  • En otra tendremos abierto un navegador con soporte Java, normalmente será Netscape, en una versión superior a la 4.0.3, para que tenga soporte al JDK 1.1.X en los applets que desarrollemos, o Microsoft Explorer, en versión 4.0 o superior. Aunque, lo mejor sin duda es utilizar, por ahora, el appletviewer para la verificación del correcto funcionamiento de los applets, antes de pelearnos con problemas que pueden originarse en el soporte a medias del JDK 1.1.X por parte de los navegadores comerciales.
  • Tendremos abierta otra ventana con un editor, donde iremos escribiendo el código de nuestro applet o aplicación Java. En Windows '95 son muy utilizados el editor Jpad y Diva. Aunque en estos momentos, quien tiene potencia suficiente en su ordenador, está programando Java desde el Java Workshop de Sun.
  • Y una ventana más donde tendremos acceso al prompt del sistema para poder invocar al compilador y a las demás herramientas del JDK.
  • Los que tengan algo de dinero podrán estar utilizando alguno de los entornos shareware que ya hay disponibles como RadJa, Kawa o JavaMaker.
  • Los que disponen de poder adquisitivo abundante habrán empezado con el Symantec Café de Symantec, ahora estarán trabajando con Borland Latte, o estarán entusiasmados con el Visual J++ de Microsoft. Y los enamorados de OS2, que en su versión 4.0 ya incluía una Máquina Virtual Java (JVM) en su kernel, se lo pasarán en grande con el IBM VisualAge for Java.
  • También somos afortunados los que podemos disfrutar de las ventajas que ofrece Linux, que con ser el sistema operativo más económico, resulta ser uno de los más potentes. Y esto también es válido cuando se trata de Java, porque el porting realizado del JDK es muy bueno.

Objetivos

Entre los objetivos que me he marcado están los que expongo a continuación. Estos objetivos esperan que tú, que estás leyendo esto, cuando llegues al final del Tutorial, saques el máximo aprovechamiento de lo que yo sé y seas capaz de:

  • Crear páginas HTML que llamen a applets Java
  • Crear contextos gráficos en Java
  • Utilizar los componentes del interfaz gráfico que proporciona Java
  • Crear aplicaciones autónomas en Java
  • Crear aplicaciones multi-threaded
  • Utilizar las librerías de E/S para manipular ficheros de texto y datos
  • Crear servidores y clientes TCP/IP que se comuniquen vía socket

Intentaré cumplir lo que acabo de prometer, aunque también pido paciencia, ya que Java en este momento es un lenguaje con una tremenda vitalidad, que todavía estoy yo aprendiendo. Y por otro lado, no es nada sencillo el hacerse entender, por lo que tengo que dar varias vueltas a cada una de las frases que escribo para cerciorarme de que tú, lector, comprendes exactamente lo que yo te quiero transmitir.

Eso sí, tampoco esperes que te proporcione ungüentos milagrosos, que por arte de magia traspasen el conocimiento. El estudio de Java, y sus applets, no será sino el examen de una particular forma de ver las cosas, con un poco de estructuración en la presentación y un cierto trasfondo de Internet; el resto es, como siempre, tarea del programador. Es decir, uno puede aprender a construir un applet, o dejar que alguna de las herramientas lo construyan automáticamente, igual que puede enseñarse a codificar un diálogo en un entorno gráfico, pero... la inteligencia de esa pieza siempre dependerá de la habilidad y experiencia del programador respecto del lenguaje usado y de sus recursos. En fin, un buen applet será únicamente resultado del trabajo de un buen programador Java.

Para concluir esta presentación, aquí está un enlace a páginas que mantienen relación con el Tutorial, bien en forma de enlaces o mirrors, y en donde puedes encontrar información que cumplimente todo lo que en este Tutorial se cuenta.

Cambiar los colores del Nimrod Look&Feel  

Posted by Danny in

El creador de Nimrod Look&Feel ha dado la posibilidad de cambiar los colores y la opacidad de este Look&Feel. Esto se realiza a través de un editor que incorpora el fichero .jar del propio "skin".

Cuando el fichero nimrodlf.jar (el mismo que usted importa al proyecto para obtener el Look&Feel) es ejecutado haciendo doble click sobre el mismo o escribiendo en la línea de comandos:

java -jar nimrodlf.jar

...se puede observar el editor que trae consigo este Look&Feel y que le permite, entre otras cosas cambiar los colores del Look&Feel y la opacidad.



Editor Nimrod Look&Feel
Aquí se pueden modificar, probar y guardar en un fichero llamado NimRODThemeFile.theme (este nombre se puede cambiar, por supuesto) las características antes mencionadas(color y opacidad). Esto se logra haciendo clicks en los recuadros "Selection", "Background", "Menu Opacity" e "Internal Frame Opacity" y escogiendo los colores y opacidad que usted desee.

Después de haber escogido los colores y la opacidad deseada se pulsa el botón "Save" y se guarda esta configuración en un fichero .theme con el nombre por defecto NimRODThemeFile.

Este fichero se coloca luego dentro de la carpeta de tabajo(../src) y cuando se compila la aplicación, habiendo importado previamente el .jar del Nimrod Look&Feel este detecta automáticamente el fichero .theme con la configuración requerida y....se puede observar al ejecutar acto seguido la aplicación como cambia el aspecto de este Look&Feel.



Aquí les dejo un video de como se lleva acabo todo el proceso...

Maximizar jFrame  

Posted by Danny in

Si queremos que al iniciar una aplicación Java nuestra ventana principal se encuentre maximizada no importa la resolución de pantalla con la cual se esté trabajando lo único que tenemos que hacer es escribir en el constructor de nuestro jFrame principal la siguiente línea de código:



this.setExtendedState(this.MAXIMIZED_BOTH);


De forma tal que nuestro constructor nos quedaría más o menos así:




public MyFrame(){
this.setExtendedState(this.MAXIMIZED_BOTH);
initComponents();
...
...
}



A la línea:
this.setExtendedState(this.MAXIMIZED_BOTH);

se le pueden pasar otros parámetros:

this.MAXIMIZED_HORIZ //Maximiza la aplicación horizontalmente

this.MAXIMIZED_VERT //Maximiza la aplicación verticalmente

Java en los Browser  

Posted by Danny in

JAVA EN LOS BROWSERS:------El primer lugar y el más frecuente, donde encontramos al lenguaje Java, es en los exploradores o navegadores de Internet. Veamos cómo llega hasta ahí.

La World Wide Web:------Llamada así por sus siglas WWW, es la aplicación que ha popularizado a Internet, y ha sido la causante de la explosión de la red de redes.

Hablando sencillamente, la WWW basa su existencia en dos aplicaciones: los servidores de Web y los clientes. Los primeros son programas dedicados, instalados en las máquinas nodos de la red, que atienden a todos los pedidos de los clientes. Estos solicitan archivos, recursos de la Web , en general, archivos HTML y gráficos. Los archivos HTML son archivos de texto, que contienen una descripción de lo que vemos como página en nuestro browser. La sigla HTML significa Hypertext Markup Languaje (lenguaje de marcación de hipertexto), y es el lenguaje que describe las páginas Web.

En esas páginas se colocan textos, gráficos y otros recursos. Es trabajo del cliente, nuestro browser, interpretar esa página, mostrarla en pantalla, y reclamar todo lo que se necesite para armarla, como los gráficos y archivos de sonido que la pueden acompañar.

Java en la Web:------Los programas Java son, al fin, otro recurso más, como pueden serlo una página HTML o un archivo gráfico. Al igual que estos últimos viajan desde el servidor a la máquina cliente, y se ejecutan en ésta.

Verá, cuando arme alguna applet, que existe una construcción, la marca HTML , que especifica un determinado lugar en una página Web, para que el browser posicione y ejecute una aplicación Java. Los archivos Java que viajan son de un tipo: se trata de archivos con extensión .class y contienen las instrucciones Java ya compiladas, no viajan en código fuente. Una applet se compone, como mínimo, de un archivo .class, pero puede requerir más archivos .class (con más código para ejecutar), que el browser recupera, o archivos gráficos, de sonido u otros, que la propia applet se encarga de recuperar.

Máquinas Virtuales:------Se ha mencionado que el lenguaje Java se compila, no pensando en una plataforma o procesador en particular, sino produciendo código (que se denomina bytecodes), destinado a ser interpretado por la llamada máquina virtual Java. Esta máquina no es una única, sino que hay una por cada plataforma y, en realidad, cada browser que implementa Java tiene la suya. Así, el Microsoft Explorer usará su máquina en Windows, mientras que el Netscape Navigator usará la suya, que variará de Windows a UNIX.

Pero todas tienen la misma funcionalidad (o debería esperarse eso). Tanto el usuario como los programadores no deberíamos preocuparnos por las distintas implementaciones. Sin embargo, se escuchan quejas de los desarrolladores, originadas en la pequeñas diferencias que se encuentran tanto entre una implementación y otra, como en el aspecto de la interface gráfica.

Además de la máquina virtual, cada browser instala una serie de clases, ya listas para usar, que Java espera tener disponibles en cualquier plataforma. Esas clases tienen una funcionalidad definida, que no debería sufrir modificaciones.

Netscape y Microsoft:------La empresa Netscape, creadora del Netscape Navigator, soporta Java desde la versión 2 de su browser. Microsoft no se ha quedado atrás y soporta Java desde la versión 2.0 de su browser. Microsoft no se ha quedado atrás (pues no le convenía, dado la mayoría de las páginas contiene - aunque sea - un poquito de Java) y soporta Java desde la versión 3.0 de su Internet Explorer. Ambos browsers instalan y usan su propia máquina virtual Java. No hay diferencias apreciables en las prestaciones de estos dos browsers, respecto de Java.

Hay que hacer algunas aclaraciones: en general, los browsers, de cualquier origen, soportan Java en ambientes que permiten la multitarea y los llamados múltiples hilos de ejecución (multihttrading).

Seguridad:------Debido a la naturaleza de Internet, traer programas desde un lugar lejano y no controlado a nuestra computadora, para ejecutarlo, puede ser riesgoso.

Con respecto a las applets Java debemos quedarnos tranquilos: Sun y los constructores de browsers han implementado una política de seguridad, que impide a una applet, por ejemplo, leer o escribir en nuestro disco, o interferir con otras aplicaciones en ejecución. Es tan grande la seguridad que, como programadores, nos puede llegar a molestar: en una applet nunca podremos grabar un archivo local, con datos transitorios o de configuración.

Nuevos browsers:
Entre Netscape (en múltiples plataformas) y Microsoft (en plataformas Windows) acaparan el mercado de los browsers.

Java sin browsers:

Pero no todo es Internet en Java. Este es un lenguaje de uso general, que sólo incidentalmente cobró popularidad en Internet. Podemos desarrollar aplicaciones Java que se ejecuten en nuestra máquina, sin necesidad de estar conectados a la red, y sin el auxilio de browsers. Mientras los programas Java para Internet y páginas HTML se llaman applets, los que pueden ejecutarse fuera de la red se llaman genéricamente aplicaciones.

Metro: Pila de webservices de Sun  

Posted by Danny in ,

Metro es la actualización del antiguo JWSDP (Java Web Services Developer Pack), y digo actualización porque la mayor parte del código se hereda de JWSDP (dicho por uno de sus desarrolladores, si el código es bueno y funciona bien, para que cambiarlo? ).

Esta incluido en Glassfish (Servidor de aplicaciones de Sun) a partir de su versión 2.

Metro realmente es un paquete de diferentes tecnologías, entre las que se encuentran JAX-WS, JAXB, y WSIT (implementación de webservices, implementación de XML-Bindings y Webservices intercomunication tecnology, que permite comunicar sin problemas webservices java y .net 3).

Según los desarrolladores de Metro,

Veamos que necesitamos para usarlo y un pequeño ejemplo.

AVISO: Este tutorial presupone el conocimiento por parte del lector de muchos de los términos e ideas que aquí se exponen, por tanto exige niveles de conocimiento altos en las tecnologías subyacentes. Los ejemplos se muestran como fragmentos que el lector debe completar.

Instalación

La instalación es muy sencilla. Hay que descargarse el jar (https://metro.dev.java.net/1.1/) y ejecutarlo (java -jar metro-installer.jar o doble clic sobre el archivo si estas en windows).

Lo que nos va a instalar es una serie de herramientas y los ficheros necesarios para su funcionamiento. Estas herramientas, al igual que en axis, son las que nos van a permitir la generación automática de código para poder crear nuestros webservices.

Tendremos por tanto 2 posibilidades de crear un webservice.

  • A partir de un fichero WSDL (WebServices Description Language).


      • útil cuando ya tenemos este tipo de fichero, o queremos reimplementar la funcionalidad de un webservice ya publicado en internet (y que nos da igual que este en .net, java o cualquier otra tecnología).
      • No es recomendable este método para generar un webservice desde 0, puesto que es trabajo de crear el fichero .wsdl puede llegar a ser muy tedioso.

      • En la versión usada, Metro 1.1, WSDL 2.0 no está soportado.



  • A partir de una clase java.
      • Perfecto para crear un webservice desde 0, o publicar ciertos métodos de una aplicación java que tenemos ya desarrollada.

      • No recomendable cuando tengamos el fichero wsdl (El webservice generado puede no ser totalmente compatible con el del wsdl que teníamos).

Veamos detalladamente cada uno de los pasos.


Crear un WebService


Para todos los ejemplos vamos a usar el webservice público definido en 'http://wscc.info/index.php?show=32031_SWE&&page_anchor=http://wscc.info/p32031/p32031_swe.php', y que devuelve información de geolocalización de una ip dada. Además el webservice está realizado en .net, y así comprobaremos si WSIT funciona.


Desde un fichero WSDL


Para generar el webservice desde este tipo de ficheros vamos a usar la herramienta que trae Metro, wsimport, y que nos va a crear todas las clases necesarias para poder poner en funcionamiento el webservice. Un ejemplo de uso del comandos sería:


wsimport.sh -s src/main/java -p com.autentia.service -Xnocompile http://ws.ip2location.com/ip2locationwebservice.asmx?wsdl

Donde:



  • -s: ruta donde se van a generar los fuentes.

  • -p : paquete en el que se generará el código.

  • -Xnocompile : indica a la herramienta que no compile el código generado.

y nos generará las siguientes clases:

IP2Location.java: Java bean de tipo de dato complejo.

Ip2LocationWebService.java: Proxy del webservice.

IP2LOCATION.java: Java bean de tipo de dato complejo.

Ip2LocationWebServiceSoap.java: Interfaz del servicio.

IP2LocationResponse.java: Java bean de la respuesta del servicio.

ObjectFactory.java: Factoría de objetos usados internamente por el servicio.

package-info.java: Archivo para javadoc.

Como lo que vamos a hacer es reescribir el servicio web (hacer un webservice compatible con el wsdl usado pero realizado en java), no nos quedaría nada más que crear la clase skeleton del webservice (la que implementa la lógica de negocio del webservice).

Creamos una nueva clase java que tendrá la siguiente estructura (en este ejemplo la llamaremos IP2LocationSkel.java):


@WebService(endpointInterface="com.autentia.service.Ip2LocationWebServiceSoap")  public class IP2LocationSkel implements Ip2LocationWebServiceSoap {          ...  }

Donde veis lo simple que es: creamos la clase y hacemos que implemente la interfaz generada anteriormente (no es obligatorio, pero si muy recomendable para saber cómo es el método a implementar en tiempo de compilación).


Lo que si es obligatorio es la anotación de la clase (y lo que le da potencia y sencillez a Metro): @WebService. La propiedad endpointInterface indica la clase (nombre cualificado) de la interfaz del webservice (y es por esto por lo que no es obligatorio implemetar la interfaz anterior).


Y ya está! Ya tendríamos nuestro webservice creado, en pocos pasos y de manera muy sencilla!


Desde java


Vamos a hacer ahora la operación inversa. Queremos realizar un webservice desde 0, no tenemos el fichero WSDL o ya tenemos una clase java de la que queremos hacer públicos alguno de sus métodos a través de webservice.


No tedríamos más que generar una clase java, que debe cumplir los siguientes requisitos:



  • La clase se debe anotar con @javax.jws.WebService.

  • Todos los métodos que se desean exponer como operación del webservice se pueden anotar con @javax.jws.WebMethod (si todos los métodos de la clase son operaciones del servicio web se puede omitir dicha anotación).

  • Todos los métodos que se desean exponer como operación del webservice pueden lanzar java.rmi.RemoteException, aparte de todas las excepciones específicas del servicio.

  • Todos los parámetros de los métodos del servicio y tipos de retorno deben ser compatibles con “JAXB 2.0 Java to XML Schema mapping definition".

  • Los parámetros de los métodos del servicio y tipos de retorno no pueden implementar directa o indirectamente la interfaz java.rmi.Remote.

Veamos una sección de la clase (una clase que implementa una pequeña calculadora):
@WebService  public class AddNumbersImpl {       @WebMethod   public int addNumbers(int number1, int number2) throws AddNumbersException {    ...   }  }


Fijaos en las anotaciones: hemos anotado la clase con @WebService, y el método addNumbers con @WebMethod (el único que expondremos como método del servicio web).

El siguiente paso: generar las clases de apoyo necesarias para poner en marcha el webservice, y para ello usaremos otra herramienta que nos provee Metro, y que se llama wsgen
wsgen.sh  -cp  -keep com.autentia.service.AddNumbersImpl
Donde:

  • -cp : indica el classpath a utilizar, es decir, la ruta o rutas de .jar o carpetas que contienen los .class necesarios para la compilación.

  • -keep : indica que no se borren los ficheros .java generados.

  • com.autentia.service.AddNumbersImpl: para el ejemplo, es la clase que implementa el webservice (denominado SEI: service endpoint implementation).

Que nos generará las siguientes clases:

AddNumbersExceptionBean.java : java bean para la excepción que puede lanzar el webservice.

AddNumbers.java : Skeleton del webservice.

AddNumbersResponse.java : clase de tratamiento de la respuesta SOAP.


Ya tenemos nuestro webservice! (sencillito, eh?)


Creando una aplicación web con nuestro webservice (war)

Una vez creado nuestro webservice veamos qué recursos y configuraciones debemos incluir para que el webservice funcione como una aplicación web y la podamos publicar (yo he usado tomcat y funciona sin problemas).

Ante todo debemos meter en la carpeta WEB-INF/lib de nuestro war los .jar (webservice*.jar) que vienen en la instalación de Metro.

Dentro de WEB-INF deben ir localizados web.xml y sun-jaxws.xml

El fichero de descripción de la aplicación web, web.xml, debe contener el siguiente fragmento (se define el servlet y filtros necesarios para que funcione Metro):

web.xml:
...  <listener>          <listener-class>                  com.sun.xml.ws.transport.http.servlet.WSServletContextListener          </listener-class>  </listener>  <servlet>          <description>JAX-WS endpoint - fromjava</description>          <display-name>metro ws engine servlet</display-name>          <servlet-name>metroServlet</servlet-name>          <servlet-class>                  com.sun.xml.ws.transport.http.servlet.WSServlet          </servlet-class>          <load-on-startup>1</load-on-startup>  </servlet>  <servlet-mapping>          <servlet-name>metroServlet</servlet-name>          <url-pattern>/ws/*</url-pattern>  </servlet-mapping>  ...

El fichero de descripción del webservice para Metro:


sun-jaxws.xml:


<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">


    <endpoint          name="addnumbers-example"          implementation="com.autentia.service.AddNumbersImpl"          url-pattern="/ws/addnumbers"/>  </endpoints>

Ojo! El url-mapping del servlet de webservice de metro y de la definición del webservice deben ser compatibles:








Una vez empaquetado el código convenientemente podemos instalar la aplicación en Tomcat, y acceder a http://localhost:8080/<war-name>/ws/addnumbers:








podemos ver el wsdl generado al pulsar sobre el link que nos propone la página.


Generar el cliente


Bien, ya he creado mi web service, ya lo he publicado... y ahora cómo lo uso? O cómo me conecto a un webservice externo?. Veamos cómo crear entonces un cliente apra webservice, y lamaera es muy sencilla, y es 99% igual que la forma en que generábamos un servicio web a partir de un wsdl.


Ejecutando el comando (la URI del wsdl tomaremos la del webservice del ejemplo comentado al inicio):


wsimport.sh -s src/main/java -p com.autentia.service -Xnocompile http://ws.ip2location.com/ip2locationwebservice.asmx?wsdl

con el que ya vimos anteriormente qué clases se generaban automáticamente.


La diferencia entre crear un webservice a aprtir de un WSDL y un cliente es la clase que tenemos que crear. Ahora codificaremos una clase como sigue, que será la que se conecte y haga la llamda al webservice:


public class IP2LocationStub implements Ip2LocationWebServiceSoap {     public IP2LOCATION ip2Location(String ip, String license) {      // Create Service    Ip2LocationWebService service = new Ip2LocationWebService();      // create proxy    Ip2LocationWebServiceSoap proxy = service.getIp2LocationWebServiceSoap();      // invoke    return proxy.ip2Location(ip, license);   }  }






Donde, como al crear el webservice, no es obligatorio que la clase implemente la interfaz Ip2LocationWebServiceSoap, pero si es muy recomendable.


Si llamáis al webservice del ejemplo necesitáis una clave de uso, con lo que la llamada volverá con los datos vacíos y con un mensaje de error, pero eso implica que el ejemplo funciona!!!


Conclusión


Ya habéis visto lo sencillo que es crear un servicio web y un cliente de webservice con Metro (y hemos probado además que WSIT funciona!).


En mi humilde opinión el desarrollo a base de anotaciones agiliza y simplifica mucho la tarea de generar web services, además nos permite reutilizar clases que ya teníamos.


En cuanto al rendimiento, existe en http://weblogs.java.net/blog/kohsuke/archive/2007/02/jaxws_ri_21_ben.html una comparativa de Metro vs Axis2, donde se muestra que para el envío de ciertos tipos de datos, Metro puede llegar a ser el doble de rápido que axis2 (por tanto más eficiente), aunque claro, la comparativa está realizada por uno de los propios desarrolladores de Metro... A final vuestra experiencia será la que diga la última palabra.


No os perdáis los próximos tutoriales sobre metro donde veremos cómo automatizar las tareas que realizábamos 'a mano' mediante maven2, y otro que nos enseñará a usar RESTFull con Metro.




Validación de documentos XML  

Posted by Danny in , ,

Veamos cómo se valida un documento XML.


import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;

public class Validate {

public Validate(String filename) {
StringBuffer buff = new StringBuffer();

try {
File f = new File(".", filename);
StringBuffer errorBuff = new StringBuffer();
InputSource input = new InputSource(new FileInputStream(f));

// Set systemID so parser can find the dtd with a relative URL in the source document.
input.setSystemId(f.toString());
SAXParserFactory spfact = SAXParserFactory.newInstance();

spfact.setValidating(true);
spfact.setNamespaceAware(true);

SAXParser parser = spfact.newSAXParser();
XMLReader reader = parser.getXMLReader();

//Instantiate inner-class error and lexical handler.
Handler handler = new Handler(filename, errorBuff);
reader.setProperty("
http://xml.org/sax/properties/lexical-handler ", handler);
parser.parse(input, handler);

if (handler.containsDTD && !handler.errorOrWarning) { // valid
buff.append("VALID " + filename +"\n");
}
else if (handler.containsDTD) { // not valid
buff.append ("NOT VALID " + filename + "\n");
buff.append(errorBuff.toString());
}
else buff.append("NO DOCTYPE DECLARATION " + filename + "\n");
}
catch (Exception e) {
buff.append("NOT WELL-FORMED " + filename + ". " + e.getMessage() + "\n");
}

System.out.print(buff.toString());
}

class Handler extends DefaultHandler implements LexicalHandler {
boolean errorOrWarning;
boolean containsDTD;
String sourceFile;
StringBuffer errorBuff;

Handler(String sourceFile, StringBuffer errorBuff) {
super();
this.sourceFile = sourceFile;
this.errorBuff = errorBuff;
errorOrWarning = false;
containsDTD = false;
}

public void error(SAXParseException exc) {
errorBuff.append(sourceFile + " Error: " + exc.getMessage()+ "\n");
errorOrWarning = true;
}

public void warning(SAXParseException exc) {
errorBuff.append(sourceFile + " Warning:" + exc.getMessage()+ "\n");
errorOrWarning = true;
}

public void startDTD (String name, String publicId, String systemId) throws SAXException {
containsDTD = true;
}

public void endDTD () throws SAXException {}
public void startEntity (String name) throws SAXException {}
public void endEntity (String name) throws SAXException {}
public void startCDATA () throws SAXException {}
public void endCDATA () throws SAXException {}
public void comment (char ch[], int start, int length) throws SAXException {}
}

public static void main(String[] args) {
Validate v = new Validate("birds.xml");
}
}

Glosario de Java  

Posted by Danny in

abstract: Abstracto.Aplicable a clases o métodos.

array: Variable que posee varias posiciones para almacenar un valor en cada posición. Las posiciones son accedidas mediante un índice numérico.

break: Palabra clave que finaliza la ejecución de un bucle o de una instrucción switch.

bucles: Tipo de estructura iterativa, que permite repetir un conjunto de instrucciones un número variable de veces.

clase: Estructura que define como son los objetos, indicando sus atributos y sus acciones.

clase base: Clase de la cuál se hereda para construir otra clase, denominada derivada.

CLASSPATH: Variable de entorno que permite a la máquina virtual java saber donde localizar sus clases.

constructor: Función especial empleada para inicializar a los objetos, cada clase posee sus propios constructores.

derivada: Clase que hereda de una clase base.

Excepcion: Objeto empleado para representar una situación de excepción (error) dentro de una aplicación java.

herencia: Característica que permite que una clase posea las características de otra, sin tener que reescribir el código.

herencia sencilla y múltiple: Dos tipos de herencia, con una sóla clase base, o con varias.

instancia: Un objeto creado a partir de una clase.

instanciación: Proceso de creación de un objeto a partir de una clase.

interfaz: Define un tipo de datos, pero sólo indica el prototipo de sus métodos, nunca la implementación.

JDK: Java Development Kit, es el conjunto de herramientas proporcionadas por sun, que permite compilar y ejecutar código java.

jerarquía de herencia: Árbol construido mediante las relaciones de herencia en las clases java.

máquina virtual: Es la encargada de ejecutar el código java.

multiplataforma: Posibilidad de existir en varias plataformas (sistemas operativos)

package: Paquete. Carpeta creada para contener clases java, y así poder organizarlas.

PATH: Variable de entorno, empleada por los sistemas operativos para saber donde localizar sus programas ejecutables.

Sobrescritura: Poseer el mismo método, pero con código distinto, en una clase base y en una clase que deriva de ella.

transformación de datos: Cómo cambiar el tipo de una información, por ejemplo cambiar el literal "23" al valor numérico 23.

try/catch/finally: Instrucciones empleadas para gestionar los posibles errores que se puedan provocar en un programa java.

Prácticas con excepciones  

Posted by Danny in ,

Crear el fichero Try1.java

Agregar el siguiente código:

public class Try1

{

public static void main(String arg[])

{

int [] array = new int[20];

array[-3] = 24;

}

}

Como podremos comprobar al ejecutar se generará el siguiente error:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException

at Try1.main(Try1.java:6)

Que indica que se ha generado una excepción del tipo java.lang.ArrayIndexOutOfBoundsException en la función Try1.main, dentro del fichero Try1.java y en la línea 6 del código. Esta excepción en particular, se lanza cuando intentamos acceder a una posición de un array y no existe dicha posición.


Vamos a gestionar esta interrupción mediante un bloque try/catch, el fichero crear es Try2.java, con el siguiente código:

public class Try2

{

public static void main(String arg[])

{

int [] array = new int[20];

try

{

array[-3] = 24;

}

catch(ArrayIndexOutOfBoundsException excepcion)

{

System.out.println(" Error de índice en un array");

}

}

}



Intentemos provocar también un error de tipo división por cero y pongamos un catch específico para dicho error (fichero Try3.java):

public class Try3

{

public static void main(String arg[])

{

int [] array = new int[20];

try

{

// array[-3] = 24;

int b = 0;

int a = 23/b;

}

catch(ArrayIndexOutOfBoundsException excepcion)

{

System.out.println(" Error de índice en un array");

}

catch(ArithmeticException excepcion)

{

System.out.println(" Error de índice en un array");

}

}

}

Podemos comprobar que se ejecuta el catch correspondiente al tipo de error generado. La línea que lanza el error de índice la hemos comentado para que no lo genere y podamos generar el error de división por cero.

Los tipos de error que se generan, son todos ellos clases, que heredan de la clase java.lang.Exception, que a su vez hereda de java.lang.Throwable, por lo tanto podríamos crear nuestros propios errores personalizados. Al igual que podríamos tener un solo catch que capture todos los errores, independientemente del tipo del error.


Excepciones  

Posted by Danny in

Excepcion es, o sencillamente problemas. En la programación siempre se producen errores, más o menos graves, pero que hay que gestionar y tratar correctamente. Por ello en java disponemos de un mecanismo consistente en el uso de bloques try/catch/finally . La técnica básica consiste en colocar las instrucciones que podrían provocar problemas dentro de un bloque try, y colocar a continuación uno o más bloques catch, de tal forma que si se provoca un error de un determinado tipo, lo que haremos será saltar al bloque catch capaz de gestionar ese tipo de error específico. El bloque catch contendrá el codigo necesario para gestionar ese tipo específico de error. Suponiendo que no se hubiesen provocado errores en el bloque try, nunca se ejecutarían los bloques catch.

Veamos ahora la estructura del bloque try/catch/finally:

try

{

//Código que puede provocar errores

}

catch(Tipo1 var1)

{

//Gestión del error var1, de tipo Tipo1

}

[ ...

catch(TipoN varN)

{

//Gestión del error varN, de tipo TipoN

} ]

[

finally

{

//Código de finally

}

]

Como podemos ver es obligatorio que exista la zona try, o zona de pruebas, donde pondremos las instrucciones problemáticas. Después vienen una o más zonas catch, cada una especializada en un tipo de error o excepción. Por último está la zona finally, encargada de tener un código que se ejecutará siempre, independientemente de si se produjeron o no errores.

Se puede apreciar que cada catch se parece a una función en la cuál sólo recibimos un objeto de un determinado tipo, precisamente el tipo del error. Es decir sólo se llamará al catch cuyo argumento sea coincidente en tipo con el tipo del error generado.



Práctica con interfaces  

Posted by Danny in ,

Vamos a definir el interfaz Cantante, un interfaz muy simple que sólo posee un método: cantar.

Crear el fichero Cantante.java

Agregar el siguiente código:

public interface Cantante

{

public void cantar();

}

Cojamos la clase Persona y hagamos que implemente el interfaz Cantante:

public class Persona implements Cantante

Además agreguemos el código para el método que define el interfaz cantante:

public void cantar()

{

System.out.println("La laa la raa laaa!");

}

Construyamos ahora una clase con función main (ArranqueInterfaz.java)para ejecutar:

public class ArranqueInterfaz

{

public static void main(String arg[])

{

Persona p = new Persona();

hacerCantar(p);

}

public static void hacerCantar(Cantante c)

{

c.cantar();

}

}




Interfaces III  

Posted by Danny in

Podemos ver que construimos un objeto (p) de tipo persona y se lo pasamos a la función hacerCantar. Esta función espera recibir un objeto Cantante, y una persona lo es, por tanto la recibe y llama al método cantar del objeto recibido.

Probemos a intentar pasar a la función hacerCantar en lugar del objeto Persona (p) un objeto String (texto), resultado: error de compilación.

Contruyamos ahora la clase Canario (Canario.java), pensando que también sabe cantar:

public class Canario implements Cantante

{

private int peso;

/* Aqui vendrían el resto de atributos y funciones propias de un canario */

public void cantar()

{

System.out.println("Pio Pio Pio");

}

}

Y ahora agreguemos en la clase ArranqueInterfaz el siguiente código, para crear un objeto canario y pasarselo a la función hacerCantar:

Canario c = new Canario();

hacerCantar(c);

Tras ejecutar comprobaremos que podemos pasar tanto una Persona como un Canario a la función hacerCantar, de tal manera que dentro de dicha función sólo accedamos a las funciones del interfaz y no habrá problemas. Por ejemplo, si pusiéramos:

c.SetNombre("Luis")

dentro de la función hacerPersona, podría funcionar si pasásemos un objeto Persona, pero no si pasamos uno de tipo Canario.




Interfaces II  

Posted by Danny in

Donde modif.visibilidad puede ser public o bien sin especificar, es decir visibilidad pública (desde cualquier clase se puede emplear el interfaz) o de paquete (sólo se puede emplear desde clases del mismo paquete).

nombreInterfaz por convenio, sigue las mismas reglas de nomenclatura que las clases, y en muchos casos acaba en able (que podíamos traducir como: 'ser capaz de').

La claúsula opcional extends, se emplea para conseguir que un interfaz herede las funciones de otro/s interfaces, simplemente listaInterfaces es una lista separada por coma de interfaces de los que se desea heredar.

En muchas ocasiones un interfaz es empleado para definir un comportamiento, que posteriormente será implementado por diversas clases, que podrán no tener nada que ver entre ellas, pero que todas se comportarán igual de cara al interfaz. Es decir, todas tendrán las funciones indicadas por el interfaz.

Cuando varios objetos de distintas clases pueden responder al mismo mensaje (función), aún realizando cosas distintas se denomina polimorfismo.

Interfaces I  

Posted by Danny in

Un interfaz es una lista de acciones que puede llevar a cabo un determinado objeto. Sorpresa, ¿eso no eran los métodos que se definen en una clase? Casi, en una clase además de aparecer los métodos aparecía el código para dichos métodos, en cambio en un interfaz sólo existe el prototipo de una función, no su código.

Veámoslo con un ejemplo: Pensemos en un interfaz en el que en su lista de métodos aparecen los métodos despegar, aterrizar, servirComida y volar. Todos pensamos en un avión, ¿verdad? El motivo es sencillamente que avión es el concepto que engloba las acciones que hemos detallado antes, a pesar que existan muchos objetos avión diferentes entre sí, por ejemplo Boeing 747, Boeing 737, MacDonell-Douglas.

Lo realmente interesante es que todos ellos, a pesar de pertenecer a clases distintas, poseen el interfaz avión, es decir poseen los métodos detallados en la lista del interfaz avión.

Esto significa también que a cualquier avión le podemos pedir que vuele, sin importarnos a que clase real pertenezca el avión, evidentemente cada clase especificará como volará el avión (porque proporciona el código de la función volar).

En java un interfaz define la lista de métodos, pero para que una clase posea un interfaz hay que indicar explícitamente que lo implementa mediante la claúsula implements. Pero veamos primero la estructura de un interfaz:

[modif.visibilidad] interface nombreInterfaz [extends listaInterfaces]

{

prototipo método1;

.....

prototipo método1;

}

Introducción a la transformación entre tipos de datos (II)  

Posted by Danny in

En ocasiones nos interesará transformar un tipo, por ejemplo entero, a otro tipo entero de menos precisión, es decir, transformar de long a int, para ello habrá que emplear el operador de moldeo:

(tipo)

para forzar la conversión de un tipo a otro:

long b =-234;

int a = (int)b;

Funcionará mientras que el valor almacenado en el long esté dentro del rango permitido al tipo int, si no, se truncará el valor. Lo mismo se puede indicar para los tipos float y double.

También se puede emplear el operador de moldeo para objetos. Veamos un ejemplo:

Coche c = new Coche();

Vector v = new Vector();

v.add(c);

Object o = v.get(0);

Coche recuperado = (Coche) o;

En este ejemplo creamos un objeto de la clase Coche, y un objeto de la clase Vector. Un Vector en java se emplea como un array dinámico.

En este caso agregamos al vector el coche mediante la función add. Para recuperar el objeto que está en la posición 0 usamos la función get, esta función devuelve un Object, cuando pensamos que debería devolver un objeto Coche. En realidad lo que devuelve es una referencia de la clase base Object, que apunta al objeto de la posición 0, es decir nuestro objeto coche. Pero necesitamos que nuestro objeto sea apuntado por una referencia de tipo Coche para poder llamar a las funciones de la clase Coche. Por ello hacemos una conversión de referencias en la última línea.



Introducción a la transformación entre tipos de datos (I)  

Posted by Danny in

En java será necesario transformar entre tipos de datos básicos, generalmente entre String hacia cualquier otro tipo tipo básico, o viceversa. Si es necesario transformar un tipo básico hacia String, la forma más rápida consiste en concatenar el valor a un objeto String, por ejemplo:

"" + 34

Con ello conseguiremos que se cree el literal "34".

Si en cambio queremos transformar el literal "2345" a un valor int para poder operar con el será necesario emplear:

int valor = Integer.parseInt("2345");

Integer es una clase empleada para representar al tipo básico int, y para transformar de String a int, pero puede lanzar excepciones, es por ello que siempre hay que usarla con try/catch:

int valor;

try{

valor = Integer.parseInt( "2345");

}catch(Exception e){ e.printStackTrace();}

System.out.println(valor*10);

Introducción a la entrada por teclado  

Posted by Danny in

En java para poder escribir se emplea el objeto System.out, pero para leer del teclado es necesario emplear System.in. Este objeto pertenece a la clase InputStream, esto significa que para leer tenemos que emplear sus métodos, el más básico es read, que permite leer un carácter:

char caracter = (char) System.in.read();

Pero como podemos comprobar es muy incómodo leer de letra en letra, por ello para poder leer una línea completa emplearemos el siguiente código:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String línea = br.readLine();

En el cuál creamos un InputStreamReader a partir de System.in y pasamos dicho InputStreamReader al constructor de BufferedReader, el resultado es que las lecturas que hagamos sobre br son en realidad realizadas sobre System.in, pero con la ventaja de que se permite leer una línea completa.

Es necesario realizar un import de java.io para poder emplear esta lectura de líneas.

Además la línea del readLine puede lanzar Excepciones, es por ello que hay que meterla entre instrucciones try/catch para poder gestionar el posible error:

String línea;

try{

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

línea = br.readLine();

}catch(Exception e){ e.printStackTrace();}

System.out.println(línea);

Tercera práctica con instrucciones iterativas (II)  

Posted by Danny in ,

Prácticas:

Crear el fichero BreakContinue.java y agregar el siguiente código:

public class BreakContinue1{

public static void main(String arg[]){

for (int contador = 0; contador<=15 ; contador ++)

{

System.out.println(contador);

// if(contador==10) break;

// if(contador==10) continue;

System.out.println("Despues del if");

}

}

}

Al ejecutar aparecerá:

0

Despues del if

pero variando de 0 a 14.

Ahora vamos a descomentar la línea del break y ejecutamos, el resultado será el mismo, pero ahora variará de 0 a 10 y además para el caso 10 no aparecerá el texto después de if.

Ahora comentamos la línea del break y descomentamos la línea del continue, ejecutamos. Podremos apreciar que aparecen los valores de 0 a 14, pero en el caso 10 no aparece el mensaje "Después de if".

Tercera práctica con instrucciones iterativas  

Posted by Danny in ,

En esta equivalencia veremos que inicialización es empleada para dar un valor inicial a la variable que utilizaremos para ser evaluada posteriormente en la condición. La condición, que será evaluada para comprobar si se detiene o no el bucle for, y la evaluación, empleada para indicar los incrementos que se realizarán sobre la variable.

Prácticas:

Crear una aplicación que muestre los primeros 256 caracteres por pantalla, en cada fila aparecerán 5 caracteres.

Crear el fichero For1.java

Agregar el siguiente código:

public class For1{

public static void main(String arg[]){

for (int nLetra = 0; nLetra<=255 ; nLetra ++)

{

System.out.print(" " + nLetra + ": " + (char)nLetra);

if (nLetra%4==0) System.out.println("");

}

}

}

Para los tres tipos de bucles existen dos palabras claves que se pueden emplear: break y continue.break consigue que se detenga el bucle y siga el flujo de ejecución después del bucle, mientras que continue provoca que se regrese al comienzo del bucle. Este regreso no provoca que se reinicialicen las variables empleadas.

Segunda práctica con Instrucciones iterativas  

Posted by Danny in ,

public static String leerLinea(){

try{

java.io.BufferedReader d = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));

return d.readLine();

}catch(Exception e) {}

return "";

}

}

for

La sintaxis del bucle for es:

for (inicialización;condición;evaluación){

//instrucciones a ejecutar

}

Antes de nada, veamos una equivalencia de un bucle while configurado como un bucle for:

inicialización;

while (condición)

{

//Instrucciones a ejecutar

evaluación;

}

Instrucciones iterativas (II)  

Posted by Danny in

Este bucle comienza ejecutando las instrucciones que hay en su interior, una vez ejecutadas comprueba el valor de condición, si es true vuelve de nuevo a repetir el proceso ejecutar/evaluar. Si la evaluación de condición es false, entonces finaliza la ejecución del bucle.

Un bucle while ejecutará sus instrucciones de 0 a n veces, dependiendo del valor de las condiciones. Mientras que un bucle do while ejecutará sus instrucciones de 1 a n veces dependiendo del valor de la condición.

Prácticas:

Crear una aplicación que solicite una contraseña al usuario, si es correcta mostrará que es correcta, si el usuario se equivoca tres veces finalizará el programa.

Crear el fichero DoWhile1.java

Agregar el siguiente código:

public class DoWhile1{

public static void main(String arg[]){

String clave = "Sin clave";

String candidata;

int nVeces = 0;

do

{

System.out.println("Introduzca la clave: ");

candidata = leerLinea();

nVeces++;

}while(!clave.equals(candidata) && nVeces<3);>

if(nVeces==3 && !clave.equals(candidata))

{

System.out.println("Lo siento no acertó.");

}

else

{

System.out.println("Clave correcta.");

}

}

/* Esta función permite leer una línea de texto, veremos su funcionamiento cuando lleguemos al capítulo de flujos de entrada y salida */

Práctica con instrucciones iterativas  

Posted by Danny in ,

Vamos a construir una aplicación que tome un número como argumento y muestre la tabla de multiplicar de dicho número.

Crear While1.java

Agregar el siguiente código:

public class While1{

public static void main(String arg[]){

if ( arg.length>0) {

int valor = Integer.parseInt(arg[0]);

int contador = 1;

while (contador<=9)

{

System.out.println("" + valor + " * " + contador + " = " + (valor*contador));

contador++;

}

}

else

{

System.out.println("No hay ningún parámetro");

}

}

}

do while :

La sintaxis es:

do

{

//Instrucciones a ejecutar

} while (condición);

Instrucciones iterativas (I)  

Posted by Danny in

También conocidas como bucles, las instrucciones iterativas tienen la misión de ejecutar las mismas instrucciones de código un número de veces, determinado por una condición.

En java tenemos tres bucles: while, do while y for.

while :

La sintaxis es:

while (condición)

{

//Instrucciones a ejecutar

}

Este bucle evalúa la condición, si es cierta ejecutará las instrucciones de su interior, una vez ejecutadas regresará al comienzo y se repetirá el proceso de evaluar/ejecutar. Este proceso sólo finalizará cuando en la evaluación la condición de como resultado false.

Mas de Instrucciones Condicionales II  

Posted by Danny in

El operador ternario tiene la misión de devolver un valor, dependiendo del valor de una condición booleana. La sintaxis es:

((condición)?valor1:valor2)

Se evalúa la condición y si es true se devuelve valor1, y si es false se devuelve valor2.

Practica:
Construir una aplicación que tome un valor entero como argumento y que muestre si es par o no por pantalla.
Crear el fichero Ternario1.java
Agregar el siguiente código:
public class Ternario1{
public static void main(String arg[]){
if ( arg.length>0) {
int valor = Integer.parseInt(arg[0]);
String resultado = ((valor%2==0)?"par":"impar");
System.out.println("El número es "+resultado);
}
else
{
System.out.println("No hay ningún parámetro");
}
}
}

Práctica completa con Instrucción Condicionales (II)  

Posted by Danny in ,

case 4:

nombreMes = "Abril";

break;

case 5:

nombreMes = "Mayo";

break;

case 6:

nombreMes = "Junio";

break;

case 7:

nombreMes = "Julio";

break;

case 8:

nombreMes = "Agosto";

break;

case 9:

nombreMes = "Septiembre";

break;

case 10:

nombreMes = "Octubre";

break;

case 11:

nombreMes = "Noviembre";

break;

case 12:

nombreMes = "Diciembre";

break;

default:

nombreMes = "desconocido";

}

System.out.println("El mes es " + nombreMes);

}

}

Ejecutar y comprobar su correcto funcionamiento.

Eliminar todas las instrucciones break del código, y comprobar que siempre se devuelve el mismo valor, independientemente del valor pasado como argumento.

Práctica completa con Instrucción Condicionales (I)  

Posted by Danny in ,

La instrucción switch toma la variable que le pasamos como argumento, y obtiene el valor de dicha variable. Después lo compara con los valores que hay junto a las etiquetas case, comenzando a ejecutar el código que hay debajo de la etiqueta case que coincida. Cuando se encuentre con la instrucción break finalizará la ejecución del switch.

En caso de no encontrar una etiqueta case coincidente, ejecutará el código que existe dentro de la etiqueta default. La etiqueta default es opcional, por tanto en caso de no tenerla simplemente no hace nada la instrucción.

Práctica:

Construir una aplicación que tome un valor entero como argumento, y que muestre el mes equivalente al entero introducido.

Crear el fichero Switch1.java

Agregar el siguiente código:

public class Switch1{

public static void main(String arg[])

{

if ( arg.length == 0 )

{

System.out.println("Uso: \n\tjava Switch1 entero");

return;

}

int mes = Integer.parseInt(arg[0]);

String nombreMes;

switch(mes){

case 1:

nombreMes = "Enero";

break;

case 2:

nombreMes = "Febrero";

break;

case 3:

nombreMes = "Marzo";

break;



Prácticas con instrucciones condicionales (I)  

Posted by Danny in ,

Vamos a construir una clase java que permita recibir un parámetro al ejecutar la clase y comprobemos que existe al menos un parámetro, y en caso de que exista que lo visualice.

Construyamos la clase if1.java

Agreguemos el siguiente código:

public class If1{

public static void main(String arg[]){

if ( arg.length>0) {

System.out.println(" Al menos hay un parámetro, y el primero es: " + arg[0] );

}

else

{

System.out.println("No hay ningún parámetro");

}

}

}

Ejecutar sin pasar nigún parámetro, o pasando al menos un parámetro y comprobemos lo que sucede. La instrucción switch permite ejecutar código, pero dependiente del valor de una variable:

switch (variable)

{

case val1:

------

------

break;

.

.

.

case valn:

------

------

break;

default:

------

------

}


BlogESfera Directorio de Blogs Hispanos - Agrega tu Blog