!Ya estoy en youtube! suscribete a mi canal https://www.youtube.com/channel/UC6-tLGUyvfrb9ibuCipFQKg
Este es el mejor Blog en español dedicado a la tecnología Java, noticias, API's, Frameworks y toda mi experiencia.
miércoles, 29 de diciembre de 2021
Usando el dialogo de configuración de impresión
martes, 28 de diciembre de 2021
Un programa básico de impresión en Java
Esta sección explica como crear un programa básico de impresión que muestra un dialogo de impresión e imprime el texto "Hola Mundo" en la impresora seleccionada.
Imprimir un documento consiste en dos partes:
- La clase Job para controlar la impresión - Crear una petición de impresión, asociar la petición con una impresora, especificar el número de copias, e interacción del usuario con el dialogo de impresión
- Dibujando la página - Dibujar contenido en una página y administrar contenido que abarca páginas (paginación).
Primero crea una instancia de la clase Job. La clase que representa una petición de impresión y la mayoría de las otras clases relacionadas se encuentran en el paquete java.awt.print
A continuación proporciono el código que imprime en contenido en la pagina, esto se logra implementando la interfaz Printable.
Una aplicación por lo general mostrará un dialogo de impresión para que el usuario pueda ajustar varias opciones como son el numero de copias, la orientación de la pagina o seleccionar la impresora cuando tengo varias.
Este dialogo se muestra visible hasta que el usuario aprueba o cancela la impresión. La variable doPrint será true si el usuario confirmo que quiere continuar con la impresión.
Si la variable doPrint es falso, el usuario ha cancelado la impresión. Dado que mostrar el cuadro de dialogo es opcional, el valor devuelto es puramente informativo.
Si la variable doPrint es verdadero, entonces la aplicación solicitará que la impresión se realice, esto se concreta llamando al metodo print de clase PrinterJob.
La excepción PrinterException se lanzará si ocurre un problema al envíar nuestro trabajo a la impresora. Sin embargo, dado que el metodo PrinterJob.print retorna tan pronto como el trabajo ha sido enviado a la impresora, el usuario de la aplicación no puede identificar si no hay papel o si este se ha atascado. El control que proporciona la clase PrinterJob es suficiente para usos básicos de impresión.
La interfaz Printable tiene un solo metodo:
La clase PageFormat describe la orientación de la pagina (portrait o landscape), el tamaño del papel y el area donde se puede dibujar en unidades de 1/72 de una pulgada.
El área imprimible representa los límites de margen de la mayoría de las impresoras (margen del hardware). El area imprimible es el espacio dentro de estos margenes, y en la práctica, a menudo se limita aún más para dejar espacio para encabezados o pies de página.
El parámetro page en base zero representa el numero de pagina que será impreso.
El siguiente código representa una implementación completa de la clase Printable
Recuerda que la impresora tiene un margen definido y lo debes de considerar, por ello llamamos al método translate de la clase Graphics. Para conocer el tamaño del margen llamamos a los métodos getImageableX y getImageableY
Enviar una instancia de la clase Graphics a la impresora es esencialmente lo mismo que renderizarla en la pantalla. En ambos casos, debe realizar los siguientes pasos:
- Dibujar una cadena de texto de prueba es tan fácil como las otras operaciones que se describieron para dibujar usando la clase Graphics2D.
- Los gráficos de la impresora tienen una resolución más alta, que debería ser transparente para la mayoría de los programas.
- El método Printable.print() es llamado por el sistema de impresión al igual que se llama al método Component.paint() para pintar un componente en la pantalla. El sistema de impresión llamará al método Printable.print() para la pagina 0, 1, .. etc.
- Hasta que el método print() devuelva NO_SUCH_PAGE.
- Se puede llamar al método print() con el mismo índice de pagina varías veces hasta que se complete el documento. Esta función es aplicada cuando el usuario especifica atributos como múltiples copias con la opción collate.
- El área imprimible de PageFormat determina el área del clip. El área imprimible también es importante para calcular la paginación o cómo distribuir el contenido en las páginas impresas, ya que los saltos de página están determinados por cuánto cabe en cada página.
Nota: Se puede omitir una llamada al método print () para ciertos índices de página si el usuario ha especificado un rango de página diferente que no involucra un índice de página en particular.
domingo, 19 de diciembre de 2021
Impresión en Java
La API Java 2D te permite dibujar en cualquier superficie, una extensión natural de eso es la habilidad de imprimir los gráficos Java 2D. Una impresora puede ser considerada un dispositivo grafico al igual que la pantalla.
La API de impresión Java 2D no está limitada a solo imprimir gráficos. Ya que también es posible imprimir el contenido de la interface de usuario de una aplicación. El contenido puede ser impreso enviando dato sin formato a la impresora delegando el formateo a la API de impresión Java 2D, o usando la API Graphics de Java 2D.
En esta lección vas a explorar las funciones de las clases printer y job que pertenecen a la API de impresión Java 2D y que son complementos de los elementos del renderizado. Aprenderás como buscar las impresoras configuradas en el sistema operativo o en la red y consultar información relevante sobre estas impresoras tales como el tamaño del papel soportado, seleccionar los parámetros de impresión y diálogos de usuarios.
Las principales clases e interfaces incluidas en la API de impresión se encuentran en los paquetes java.awt.print y javax.print (este último paquete te permite acceder a los servicios de impresión).
Las operaciones básicas de impresión son representados en las siguientes secciones:
- Un programa básico de impresión - Esta sección describe la interface Printable y presenta un programa básico de impresión.
- Usando el dialogo de parametros de impresión - Estás secciones explica como mostrar el dialogo Configuración de Impresión
- Imprimiendo un documento con varías paginas - Esta sección explica como usar paginación para imprimir un documento con varias paginas.
- Trabajando con servicios de impresión y atributos - Esta sección te enseña acerca de los servicios de impresión, como especificar el formato de impresión de los datos, y como crear una peticion de impresión usando el paquete javax.print.
- Imprimiendo el contenido de una interfaz de usuario - Esta sección explica como imprimir el contenido de una ventana.
- Soporte de impresión en componentes Swing - Esta sección proporciona una breve descripción de la funcionalidad de impresión en Swing y se refiere a clases e interfaces especificas de Swing
miércoles, 8 de diciembre de 2021
Genericos en Java
En cualquier proyecto de software no trivial, los errores son simplemente una realidad. Una planificación, programación y pruebas cuidadosas pueden ayudar a reducir su omnipresencia, pero de alguna manera, en algún lugar, siempre encontrarán una manera de introducirse en su código. Esto se vuelve especialmente evidente a medida que se introducen nuevas funciones y su código base crece en tamaño y complejidad.
Afortunadamente, algunos errores son más fáciles de detectar que otros. Los errores en tiempo de compilación, por ejemplo, se pueden detectar desde el principio; puede utilizar los mensajes de error del compilador para averiguar cuál es el problema y solucionarlo, en ese mismo momento. Los errores en tiempo de ejecución, sin embargo, pueden ser mucho más problemáticos; no siempre aparecen de inmediato, y cuando lo hacen, puede ser en un punto del programa que está muy alejado de la causa real del problema.
Los genéricos (o Generics) agregan estabilidad a su código al hacer que más errores sean detectables en el momento de la compilación.
¿Por qué utilizar genéricos?
En pocas palabras, los genéricos permiten que los tipos (clases e interfaces) sean parámetros al definir clases, interfaces y métodos. Al igual que los parámetros formales más familiares utilizados en las declaraciones de métodos, los parámetros de tipo proporcionan una forma de reutilizar el mismo código con diferentes entradas. La diferencia es que las entradas a los parámetros formales son valores, mientras que las entradas a los parámetros de tipo son tipos.
El código que usa genéricos tiene muchas ventajas sobre el código no genérico:
Comprobaciones de tipo más estrictas en tiempo de compilación.
Un compilador de Java aplica una fuerte verificación de tipos al código genérico y emite errores si el código viola la seguridad de los tipos. Arreglar errores en tiempo de compilación es más fácil que arreglar errores en tiempo de ejecución, que pueden ser difíciles de encontrar.
Eliminación de conversión de tipo (Cast).
El siguiente fragmento de código sin genéricos requiere conversión:
Cuando se reescribe para usar genéricos, el código no requiere conversión:
Permitir a los programadores implementar algoritmos genéricos.
Mediante el uso de genéricos, los programadores pueden implementar algoritmos genéricos que funcionan en colecciones de diferentes tipos, se pueden personalizar y son seguros para los tipos y más fáciles de leer.
Tipos genéricos
Un tipo genérico es una clase o interfaz genérica que se parametriza sobre tipos. La siguiente clase Box se modificará para demostrar el concepto.
Box, una clase simple
Comience examinando la clase Box no genérica que opera sobre objetos de cualquier tipo. Solo necesita proporcionar dos métodos: set, que agrega un objeto al cuadro, y get, que lo recupera:
Una versión Generic de la clase Box
Convenciones de nomenclatura de parámetros de tipo
- E - Elemento (utilizado ampliamente por Java Collections Framework)
- K - Clave
- N - Número
- T - Tipo
- V - Valor
- S, U, V, etc. - 2. °, 3. °, 4. ° tipos
Invocación y creación de instancias de un tipo genérico
El diamante
Parámetros de tipo múltiple
lunes, 29 de noviembre de 2021
Log4j ofrece control sobre el logging
La API log4j de código abierto para Java ofrece servicios de logs rápidos y eficientes
¡Advertencia! Log4j 1.x ha sido deprecada y reemplazada por Log4j 2.x. Sin embargo es buena practica iniciarnos con la versión predecesora.
Casi todas las aplicaciones grandes incluyen su propia API de logging. La experiencia indica que el logging representa un componente importante del ciclo de desarrollo. Como tal, el logging ofrece varias ventajas. Primero, puede proporcionar un contexto preciso sobre una ejecución de la aplicación. Una vez insertado en el código, la generación de la salida del log no requiere intervención humana. En segundo lugar, la salida del log se puede guardar en un medio persistente para estudiarla más adelante. Finalmente, además de su uso en el ciclo de desarrollo, también se puede emplear un paquete de logs suficientemente rico como herramienta de auditoría.
De conformidad con esa regla, a principios de 1996, el proyecto EU SEMPER (Mercado electrónico seguro para Europa) decidió escribir su propia API de logging. Después de innumerables mejoras, varias encarnaciones y mucho trabajo, esa API se ha convertido en log4j, un paquete de logging popular para Java. El paquete se distribuye bajo la Licencia Pública de IBM, certificada por la iniciativa de código abierto.
El logging tiene sus inconvenientes. Puede ralentizar una aplicación. Si es demasiado detallado, puede causar ceguera de desplazamiento. Para aliviar esas preocupaciones, log4j está diseñado para ser rápido y flexible. Dado que el log rara vez es el enfoque principal de una aplicación, la API de log4j se esfuerza por ser simple de entender y usar.
Este artículo comienza describiendo los componentes principales de la arquitectura log4j. Continúa con un ejemplo simple que describe el uso y la configuración básica. Concluye tocando los problemas de rendimiento y la próxima API de logging de Sun.
Categorías, Appenders y Layouts
Log4j tiene tres componentes principales:
- Categorías
- Appenders
- Layouts
Los tres componentes trabajan juntos para permitir que los desarrolladores registren los eventos según el tipo de evento y la prioridad, y para controlar en tiempo de ejecución cómo se formatean estos mensajes y dónde se informan. Echemos un vistazo a cada uno de ellos.
Jerarquía de categorías
La primera y principal ventaja de cualquier API de logs sobre System.out.println simple reside en su capacidad para deshabilitar ciertas declaraciones de registro mientras permite que otras impriman sin obstáculos. Esa capacidad asume que el espacio del log, es decir, el espacio de todas las declaraciones de logs posibles, se categoriza de acuerdo con algunos criterios elegidos por el desarrollador.
De conformidad con esa observación, la clase org.log4j.Category figura en el núcleo del paquete. Las categorías son entidades con nombre. En un esquema de nomenclatura familiar para los desarrolladores de Java, se dice que una categoría es padre de otra categoría si su nombre, seguido de un punto, es un prefijo del nombre de la categoría secundaria. Por ejemplo, la categoría denominada com.foo es un padre de la categoría denominada com.foo.Bar. De manera similar, java es un padre de java.util y un antepasado de java.util.Vector.
La categoría raíz, que reside en la parte superior de la jerarquía de categorías, es excepcional de dos maneras:
- Siempre existe
- No se puede recuperar por nombre
En la clase Category, al invocar el método getRoot () estático se recupera la categoría raíz. El método estático getInstance () crea una instancia de todas las demás categorías. getInstance () toma el nombre de la categoría deseada como parámetro. Algunos de los métodos básicos de la clase Categoría se enumeran a continuación:
A las categorías se les pueden asignar prioridades del conjunto definido por la clase org.log4j.Priority. Aunque el conjunto de prioridades coincide con el del sistema Unix Syslog, log4j fomenta el uso de solo cuatro prioridades: ERROR, WARN, INFO y DEBUG, enumeradas en orden decreciente de prioridad. La lógica detrás de ese conjunto aparentemente restringido es promover una jerarquía de categorías más flexible en lugar de un conjunto de prioridades estático (aunque sea grande). Sin embargo, puede definir sus propias prioridades subclasificando la clase Prioridad. Si una categoría determinada no tiene una prioridad asignada, hereda una de su antepasado más cercano con una prioridad asignada. Como tal, para garantizar que todas las categorías puedan eventualmente heredar una prioridad, la categoría raíz siempre tiene una prioridad asignada.
Si una categoría no tiene una prioridad asignada va a heredar la prioridad de su padre.
Para registrar un evento de la aplicación, invoque uno de los métodos de impresión de una instancia de categoría. Esos métodos de impresión son:
error()
warn()
info()
debug()
log()
Por definición, el método de impresión determina la prioridad del registro del evento. Por ejemplo, si c es una instancia de categoría, entonces la instrucción c.info ("..") es una solicitud de logging de prioridad INFO.
Se dice que una solicitud de registro está habilitada si su prioridad es mayor o igual que la prioridad de su categoría. De lo contrario, se dice que la solicitud está deshabilitada. Una categoría sin una prioridad asignada heredará una de la jerarquía.
A continuación, encontrará un ejemplo de esa regla:
Llamar al método getInstance () con el mismo nombre siempre devolverá una referencia al mismo objeto de categoría. Por lo tanto, es posible configurar una categoría y luego recuperar la misma instancia en algún otro lugar del código sin pasar referencias. Las categorías se pueden crear y configurar en cualquier orden. En particular, una categoría padre buscará y vinculará a sus hijos incluso si se crea una instancia después de ellos. El entorno log4j generalmente se configura en la inicialización de la aplicación, preferiblemente leyendo un archivo de configuración, un enfoque que discutiremos en breve.
Log4j facilita la tarea de nombrar categorías por componente de software. Eso se puede lograr instanciando estáticamente una categoría en cada clase, con el nombre de la categoría igual al nombre completo de la clase, un método útil y sencillo para definir categorías. Como la salida del registro lleva el nombre de la categoría generadora, dicha estrategia de denominación facilita la identificación del origen de un mensaje del registro. Sin embargo, esa es solo una estrategia posible, aunque común, para nombrar categorías. Log4j no restringe el posible conjunto de categorías. De hecho, el desarrollador es libre de nombrar las categorías como desee.
Appenders y Layouts
La capacidad de habilitar o deshabilitar selectivamente las solicitudes de registro según su categoría es solo una parte de la imagen. Log4j también permite que las solicitudes de registro se impriman en múltiples destinos de salida llamados appenders en log4j. Actualmente, existen appenders para la consola, archivos, componentes GUI, servidores de socket remotos, NT Event Loggers y demonios remotos de UNIX Syslog.
Una categoría puede referirse a múltiples appenders. Cada solicitud de registro habilitada para una categoría determinada se reenviará a todos los appenders de esa categoría, así como a los que se agregan más arriba en la jerarquía. En otras palabras, los appenders se heredan de forma aditiva de la jerarquía de categorías. Por ejemplo, si agrega un appender de consola a la categoría raíz, todas las solicitudes de registro habilitadas se imprimirán al menos en la consola. Si, además, se agrega un appender de archivos a una categoría, digamos C, las solicitudes de registro habilitadas para C y los hijos de C se imprimirán en un archivo y en la consola. Tenga en cuenta que puede anular ese comportamiento predeterminado para que la acumulación de appenders ya no sea aditiva.
Las reglas que gobiernan la aditividad del appender se resumen a continuación.
Aditividad del appender
La salida de una declaración de registro del registrador C irá a todos los appenders en C y sus ancestros. Este es el significado del término "aditividad del appender".
Sin embargo, si un ancestro del registrador C, digamos P, tiene el indicador de aditividad establecido en falso, entonces la salida de C se dirigirá a todos los anexos en C y sus ancestros hasta e incluyendo P, pero no a los agregadores en ninguno de los ancestros de P .
Los registradores tienen su indicador de aditividad establecido en verdadero de forma predeterminada.
La siguiente tabla muestra un ejemplo:
Logger Name | Added Appenders | Additivity Flag | Output Targets | Comment |
---|---|---|---|---|
root | A1 | not applicable | A1 | The root logger is anonymous but can be accessed with the Logger.getRootLogger() method. There is no default appender attached to root. |
x | A-x1, A-x2 | true | A1, A-x1, A-x2 | Appenders of "x" and root. |
x.y | none | true | A1, A-x1, A-x2 | Appenders of "x" and root. |
x.y.z | A-xyz1 | true | A1, A-x1, A-x2, A-xyz1 | Appenders in "x.y.z", "x" and root. |
security | A-sec | false | A-sec | No appender accumulation since the additivity flag is set to false. |
security.access | none | true | A-sec | Only appenders of "security" because the additivity flag in "security" is set to false. |
Para configurar el flag agregar la siguiente linea al archivo de configuración.
log4j.additivity.nombre.logger=false
La mayoría de las veces, los usuarios desean personalizar no solo el destino de salida, sino también el formato de salida, una hazaña que se logra al asociar un layout con un appender. El layout formatea el mensaje del registro de acuerdo con los deseos del usuario, mientras que un appender se encarga de enviar la salida formateada a su destino. PatternLayout, parte de la distribución estándar de log4j, permite al usuario especificar el formato de salida de acuerdo con patrones de conversión similares a la función printf del lenguaje C.
Por ejemplo, PatternLayout con el patrón de conversión % r [% t]% - 5p% c -% m% n generará algo similar a:
En la salida de arriba:
- El primer campo es igual al número de milisegundos transcurridos desde el inicio del programa.
- El segundo campo indica el hilo que realiza la solicitud de registro
- El tercer campo representa la prioridad de la declaración de registro.
- El cuarto campo es igual al nombre de la categoría asociada con la solicitud de registro.
- El texto después de - indica el mensaje de la declaración.
Configuración
Insertar solicitudes de registro en el código de la aplicación requiere una gran cantidad de planificación y esfuerzo. La observación muestra que el código dedicado al registro representa aproximadamente el cuatro por ciento del total de la aplicación. En consecuencia, incluso las aplicaciones de tamaño moderado tendrán miles de declaraciones de registro incrustadas en su código. Dado su número, es imperativo administrar esas declaraciones de registro sin la necesidad de modificarlas manualmente.
El entorno log4j se puede configurar completamente mediante programación. Sin embargo, es mucho más flexible configurar log4j utilizando archivos de configuración. Actualmente, los archivos de configuración se pueden escribir en XML o en formato de propiedades Java (clave = valor).
Démosle una idea de cómo se hace con la ayuda de una aplicación imaginaria, MyApp, que usa log4j:
Como se ve en el código anterior, MyApp comienza importando clases relacionadas con log4j. Luego define una variable de categoría estática con el nombre MyApp, que resulta ser el nombre completo de la clase.
MyApp usa la clase Bar definida en el paquete com.foo:
En MyApp, la invocación del método BasicConfigurator.configure () crea una configuración log4j bastante simple. Ese método está programado para agregar a la categoría raíz una impresión FileAppender en la consola. La salida se formateará utilizando un PatternLayout establecido en el patrón% -4r [% t]% -5p% c% x -% m% n.
Tenga en cuenta que, de forma predeterminada, la categoría raíz se asigna a Priority.DEBUG.
La salida de MyApp es:
La Figura 1 muestra el diagrama de objetos de MyApp inmediatamente después de que llama al método BasicConfigurator.configure ().
//agregar figura
La Figura 1 muestra el diagrama de objetos de MyApp inmediatamente después de que llama al método BasicConfigurator.configure ().
La clase MyApp configura log4j invocando el método BasicConfigurator.configure (). Otras clases solo necesitan importar la clase org.log4j.Category, recuperar las categorías que desean usar y cerrar sesión.
El ejemplo anterior siempre genera la misma información de registro. Afortunadamente, es fácil modificar MyApp para que la salida del registro se pueda controlar en tiempo de ejecución. A continuación, verá una versión ligeramente modificada:
Esta versión de MyApp indica a PropertyConfigurator que analice un archivo de configuración y configure el registro en consecuencia.
Veamos un archivo de configuración de muestra que da como resultado exactamente el mismo resultado que el ejemplo anterior basado en BasicConfigurator:
Suponga que ya no deseamos ver la salida de ningún componente que pertenezca al paquete com.foo. El siguiente archivo de configuración muestra una posible forma de lograrlo:
La salida de MyApp configurada con este archivo se muestra a continuación:
Como la categoría com.foo.Bar no tiene una prioridad asignada, hereda su prioridad de com.foo, que se estableció en WARN en el archivo de configuración. La declaración de registro del método Bar.doIt () tiene la prioridad DEBUG, menor que la prioridad de categoría WARN. En consecuencia, se suprime la solicitud de registro de doIt ().
A continuación, vemos otro archivo de configuración que usa múltiples appenders:
Llamar a la MyApp mejorada con ese archivo de configuración generará lo siguiente en la consola:
Además, como a la categoría raíz se le ha asignado un segundo appender, la salida también se dirigirá al archivo example.log. Ese archivo se renovará cuando alcance los 100 KB. Cuando se produce una renovación, la versión anterior de example.log se mueve automáticamente a example.log.1.
Tenga en cuenta que para obtener esos diferentes comportamientos de registro, no es necesario volver a compilar el código. Con la misma facilidad podríamos haber iniciado sesión en un demonio de Unix Syslog y redirigir toda la salida de com.foo a un registrador de eventos de NT. De manera similar, podríamos haber reenviado los eventos de registro a un servidor log4j remoto, que registraría de acuerdo con la política del servidor local, por ejemplo, iniciando sesión en un archivo local y reenviando el evento de registro a un segundo servidor log4j.
Contextos de diagnóstico anidados
La mayoría de los sistemas del mundo real deben tratar con varios clientes simultáneamente. En una implementación multiproceso típica de un sistema de este tipo, diferentes subprocesos manejarán diferentes clientes. Teniendo en cuenta eso, el registro es especialmente adecuado para rastrear y depurar aplicaciones distribuidas complejas. Un enfoque común para diferenciar la salida de registro de un cliente de otro es crear una instancia de una nueva categoría separada para cada cliente. Sin embargo, ese enfoque promueve la proliferación de categorías y aumenta la sobrecarga administrativa del registro.
En una técnica más ligera, puede sellar de forma única cada solicitud de registro iniciada desde la misma interacción con el cliente, un enfoque descrito por Neil Harrison (ver Recursos). Para sellar de forma única cada solicitud, el usuario inserta información contextual en el contexto de diagnóstico anidado (NDC). La clase NDC se muestra a continuación:
El NDC se gestiona por hilo como una pila de información contextual. Tenga en cuenta que todos los métodos de org.log4j.NDC son estáticos. Suponiendo que la impresión NDC está activada, cada vez que se realiza una solicitud de registro, el componente log4j apropiado incluirá la pila NDC completa para el hilo actual en la salida del registro. Eso se hace sin la intervención del usuario, que es responsable únicamente de colocar la información correcta en el NDC mediante el uso de los métodos push () y pop () en algunos puntos bien definidos del código. En contraste, el enfoque de categoría por cliente exige cambios extensos en el código.
Para ilustrar ese punto, tomemos el ejemplo de un servlet que entrega contenido a numerosos clientes. El servlet puede construir el NDC al comienzo de la solicitud antes de ejecutar otro código. La información contextual puede ser el nombre de host del cliente y otra información inherente a la solicitud, generalmente información contenida en cookies. Por lo tanto, incluso si el servlet está sirviendo a varios clientes simultáneamente, los registros iniciados por el mismo código (es decir, pertenecientes a la misma categoría) aún se pueden distinguir porque cada solicitud de cliente tendrá una pila de NDC diferente. Compare eso con la complejidad de pasar una categoría recién instanciada a todo el código ejercido durante la solicitud del cliente.
No obstante, algunas aplicaciones sofisticadas, como los servidores web de alojamiento virtual, deben registrarse de manera diferente, según el contexto del host virtual y el componente de software que emite la solicitud. La versión más reciente de log4j admite múltiples árboles de jerarquía, una mejora que permite que cada host virtual posea su propia copia de la jerarquía de categorías.
Rendimiento
Uno de los argumentos más citados en contra del logging proviene de su costo computacional. Esa es una preocupación legítima, ya que incluso las aplicaciones de tamaño moderado pueden generar miles de solicitudes de registro. Se dedicó mucho esfuerzo a medir y ajustar el rendimiento del registro. Log4j afirma ser rápido y flexible: primero la velocidad, luego la flexibilidad.
No obstante, el usuario debe conocer los siguientes problemas de rendimiento:
1.- Rendimiento del registro cuando el registro está desactivado. Cuando el registro está desactivado por completo o para un conjunto de prioridades, el costo de una solicitud de registro es una invocación de método más una comparación de enteros. La invocación del método implica el costo oculto de la construcción de parámetros. Para algunas categorías cat, escribir
incurre en el costo de construir el parámetro de mensaje que convierte tanto el entero i como la entrada [i] en una cadena y concatena cadenas intermedias, independientemente de si el mensaje se registrará o no. Si a uno le preocupa la velocidad, escriba:
Eso no incurrirá en el costo de la construcción de parámetros si la depuración está deshabilitada. Por otro lado, si la categoría está habilitada para la depuración, incurrirá dos veces en el costo de evaluar si la categoría está habilitada o no: una vez en debugEnabled () y una vez en debug (). Eso representa una sobrecarga insignificante porque la evaluación de una categoría lleva aproximadamente el 1 por ciento del tiempo que lleva registrar realmente. En log4j, las solicitudes de registro se realizan a instancias de la clase Categoría. Debido a que Categoría es una clase y no una interfaz, el costo de la invocación del método es posiblemente menor, pero a costa de cierta flexibilidad. En una máquina Pentium II de 233 MHz, el costo típico de registro cuando el registro está desactivado está en el rango de 5 a 50 nanosegundos.
2.- El rendimiento de decidir si registrar o no registrar un registro cuando el logging está activado. En ese escenario, la pregunta se centra en el costo de rendimiento de recorrer la jerarquía de categorías. Cuando el registro está activado, log4j aún necesita comparar la prioridad de la solicitud de registro con la prioridad de la categoría de solicitud. Sin embargo, es posible que las categorías no tengan una prioridad asignada; pueden heredarlos de la jerarquía de categorías. Por lo tanto, para descubrir su prioridad, la categoría puede necesitar buscar a sus antepasados. Se ha hecho un esfuerzo serio para que esa jerarquía camine lo más rápido posible. Por ejemplo, las categorías secundarias se vinculan solo a sus antepasados existentes. En el ejemplo de BasicConfigurator mostrado anteriormente, la categoría denominada com.foo.Bar enlaza directamente con la categoría raíz, evitando así las categorías com o com.foo inexistentes, mejorando significativamente la velocidad de la caminata, especialmente en jerarquías dispersas. caminar por la jerarquía está en el rango de 5 a 15 microsegundos, nuevamente en una máquina Pentium II de 233 MHz.
3.- El rendimiento real del Loggin. Otro problema de rendimiento se deriva del costo de formatear la salida del registro y enviarla a su destino. Aquí nuevamente, se hizo un gran esfuerzo para que los Layouts (formateadores) funcionen lo más rápido posible. Lo mismo ocurre con los Appenders. El costo típico de registrar realmente varía entre 100 y 300 microsegundos.
Aunque log4j tiene muchas características, su primer objetivo de diseño fue la velocidad. Algunos componentes de log4j se han reescrito muchas veces para mejorar el rendimiento. Sin embargo, los contribuyentes suelen presentar nuevas optimizaciones.
La empresa SUN está construyendo su API de Logging
**Actualización: La API ya se encuentra disponible, se le conoce como JUL Java Util Logging**
Sun ha iniciado la petición JSR47 en Java Community Process (JCP) para definir una API de Logging para Java. La API resultante requerirá la versión 1.4 de JDK y pronto estará lista para su revisión pública.
La API JSR47 y Log4j son bastante similares a nivel arquitectónico. La API JSR47 admitirá un espacio de nombres jerárquico, una de las características centrales de log4j. Por otro lado, log4j posee muchas características útiles que faltan en JSR47. Dado el impulso detrás de log4j, en mi opinión partidista, es probable que JSR47 esté obsoleto para cuando se lance. Log4j está escrito por las personas que lo utilizan, no por un comité cerrado.
Por cierto, log4j ya proporciona soporte para la conexión en la API JSR47 cuando esta última esté disponible.
Permítanme también mencionar JLog, otra API de registro disponible en alphaWorks de IBM. JLog se llamaba anteriormente RAS Toolkit hasta que IBM lo renombró. En el sitio alphaWorks, JLog tiene la etiqueta "Logging Toolkit for Java", casi la misma etiqueta que tenía log4j en alphaWorks antes de migrar a http://log4j.org. JLog, aunque es un buen paquete de registro, no debe confundirse con log4j.
Conclusión
Log4j es un paquete de registro popular escrito en Java. Uno de sus rasgos distintivos incluye la noción de herencia en categorías. Usando una jerarquía de categorías, es posible controlar qué declaraciones de registro se generan con granularidad arbitraria, reduciendo así el volumen de salida registrada y minimizando el costo de registro.
Una de las ventajas de la API de log4j es su capacidad de administración. Una vez que las declaraciones de registro se han insertado en el código, se pueden controlar con archivos de configuración. Además, pueden habilitarse o deshabilitarse selectivamente y enviarse a diferentes y múltiples destinos de salida en formatos elegidos por el usuario. Además, el paquete log4j está diseñado para que las declaraciones de registro puedan permanecer en el código enviado sin incurrir en un alto costo de rendimiento.
Log4j es el resultado de un esfuerzo colectivo. Mi especial agradecimiento a todos los autores que han contribuido al proyecto. Sin excepción, las mejores características del paquete se han originado en la comunidad de usuarios.
Referencia: https://logging.apache.org/log4j/1.2/manual.html
Más información sobre este tema
"Patterns for Logging Diagnostic Messages," Neil Harrison in Pattern Languages of Program Design 3, edited by R. Martin, D. Riehle, and F. Buschmann (Addison-Wesley, 1997)
http://www.amazon.com/exec/obidos/ASIN/0201310112/qid%3D973215403/002-8420944-7444837/javaworld
Log4j project homepage
http://jakarta.apache.org/log4j/docs/
Sun's Java Logging API Specification
http://java.sun.com/aboutJava/communityprocess/jsr/jsr_047_log.html
Igor Poteryaev, an independent author, has ported log4j to the Python language, called log4p
http://log4p.sourceforge.net
IBM's JLog API
http://www.alphaworks.ibm.com/tech/loggingtoolkit4j
The EU's Secure Electronic Marketplace for Europe (SEMPER) project homepage
http://www.semper.org
OpenSource.org
http://www.opensource.org
Level
https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Level.html
Category
https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Category.html
PatternLayout
https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html
miércoles, 24 de noviembre de 2021
Logging de una aplicación en Java
El logging de una aplicación consiste en registrar (logs) información relevante del comportamiento de la ejecución de nuestra aplicación. Contiene datos de variables, entidades, cambios de estado, componentes de software involucradas en dicha ejecución y la llamada de los métodos. Su principal funcionalidad es facilitar el seguimiento o análisis de la ejecución de la aplicación:
- Analizar el comportamiento de la aplicación durante la fase de desarrollo y depuración (pruebas de caja blanca)
- Analizar los bugs o errores de ejecución detectados, sus causas y consecuencias
- Servir de registro de auditoría cuando la información contenida y el modo en que se ha procesado cumpla los criterios requeridos
- Medir el rendimiento o carga de los sistemas o aplicaciones
- Revertir el estado del aplicativo siguiendo en orden inverso el log
Aunque depende de las circunstancias en las que nos encontremos, el segundo de los usos suele ser el más relevante. Un buen log desarrollado correctamente en el código y mantenido o configurado en explotación es una garantía de respuesta rápida para análisis de errores; que incluso podrían hacerse sin necesidad de parar el aplicativo, reconfigurarlo o aplicarle ningún cambio.
El log o registro de la aplicación suele formarse por un conjunto de eventos que se almacenan secuencialmente, por lo general en el orden en que suceden, de manera persistente o recuperable. Se pueden almacenar en ficheros, en BBDD, en componentes distribuidos a tal efecto. Se pueden habilitar mecanismos de rotación o históricos de estos logs, se pueden utilizar por monitores para lanzar alertas, se pueden integrar y fusionar para hacer análisis más exhaustivos. Lo relevante es que la información registrada y la forma en que se gestiona sea útil.
Existen numerosas soluciones y propuestas de software, tanto libres como propietarias, más o menos estandarizadas, más sencillas o más completas, de mil tipos y formas. Lo importante es buscar aquella se ajusta a nuestras necesidades y entornos, para olvidarnos de la implementación del mecanismo por completo; y ceñirnos a los dos aspectos más importantes:
- El contenido de cada registro o evento, principal preocupación del desarrollador
- El modo en que se procesa, persiste y gestiona, principal preocupación de la explotación del sistema o aplicativo
El coste de implementación del logging se encuentra en el ir, mientras se desarrolla, dejando registros (logs) en los diferentes puntos del código. Esta actividad debe hacerse durante el desarrollo, siguiendo patrones, criterios y procedimientos preestablecidos. De esta manera los desarrolladores tendrán criterios comunes y los logs serán coherentes entre las diferentes partes del código.
La información registrada en el log debe ser relevante y completa. Se pueden considerar los siguientes aspectos a la hora de decidir qué información incluir:
Qué:
Qué evento o acción ha ocurrido.
Qué entidades han estado involucradas.
Si hay un cambio de estado, ¿Cuál era el anterior? ¿Cuál es el nuevo estado?.
Dónde:
En qué punto del código ha ocurrido: componente, clase, fichero de código, método o bloque de ejecución, línea de código… Cuanto más detallada sea esta información mejor para localizar el lugar del posible error o por donde ha pasado la ejecución, por un lado; pero más puede afectar el logging al rendimiento.
Cuándo:
Registrando el momento temporal, bien absoluto o bien relativo al comienzo de ejecución o cualquier otro evento.
Generando los logs secuencial o causal, en la que los eventos que ocurren antes en el tiempo o que ocasionan otros, aparezcan antes.
En qué contexto:
Registrando estados o variables: propios de la ejecución (parámetros), de personalización o específicos de usuario, referentes a la sesión o transacción en ejecución…
Indicando hilos, transacciones o peticiones relacionadas cuando estemos en entornos concurrentes.
Para que la información de los logs sea más detallada en momento de análisis y más manejable durante la explotación de la misma, se establecen niveles de filtrado. De tal manera que solo se muestra o almacenan aquellos eventos con un nivel mayor o igual al del nivel de log establecido. Las librerías de logging permiten filtrar los eventos por otros criterios como son la clase o contexto del evento, también.
Los niveles más comunes son DEBUG, INFO, WARNING y ERROR. La clasificación de los diferentes eventos en cada nivel es parte del ejercicio de análisis, y deben orientarse a que la traza sea legible y útil en los diferentes contextos del aplicativo, desde el desarrollo hasta la explotación.
Este puede ser un ejemplo de semántica de niveles de logging:
DEBUG: para información de muy bajo nivel solo útil para el debug de la aplicación, tanto en el desarrollo como en el análisis de incidencias
Llamadas a funciones y procedimientos y otros componentes, con parámetros y respuestas
Flujos de ejecución
Desarrollo de algoritmos y procedimientos que permitan identificar y seguir su ejecución en desarrollo
INFO: información de más alto nivel que permita hacer un seguimiento de la ejecución normal
Paradas y arranques de servicios y sistemas
Parámetros críticos o relevantes de configuración
Comienzo y fin de transacciones y operaciones completas
Cambios de estado de operaciones
WARN: información de situaciones, que aún sin ser de error, si son anómalas o no previstas, aunque el aplicativo tiene alternativas para solventarlas
Parámetros no definidos, y cuyo valor se toma por defecto
Situaciones anómalas, pero que son resueltas por el aplicativo, dejando la operación en un estado correcto
Funcionalidades no primordiales o imprescindibles, que no pueden resolverse, pero que dejan la operación en un estado correcto
ERROR: información de situaciones que son de error y que impiden la ejecución correcta de una operación o transacción, pero sin afectar a otras operaciones o transacciones (error aislado o contenido)
No se pudo realizar una operación o transacción, pero no afecta a otras
Peticiones o consultas erróneas (almacenando los parámetros de entrada)
Funcionalidades generales del aplicativo, que aún afectando al funcionamiento general del aplicativo, no se consideran primordiales o imprescindibles
FATAL: información de situaciones de error que afectan al funcionamiento general del aplicativo (errores no aislados o contenidos en alcance)
Parámetros no definidos o configuraciones erróneas
Falta de conexión o comunicación con otros componentes
Errores de ejecución que pueden afectar a operaciones o transacciones independientes, o que afectan al funcionamiento general de la aplicación
Tanto el contenido y forma de cada evento de log, como la semántica de los niveles son parte del diseño del aplicativo. Estos criterios deben definirse y ser comunicados al equipo de desarrollo para que se apliquen de manera homogénea y coherente en todo el desarrollo. Si estos criterios son consensuados con el equipo se puede sacar mucho provecho de la experiencia de los desarrolladores.
Otras recomendaciones a tener en cuenta son:
Registrar los eventos de manera atómica, que toda la información referente a un evento se almacene en un registro o línea.
Orientar el formato de la información mostrada a poder ser usado de manera informatizada o automática con herramientas específicas.
En lo referente a excepciones:
Mostrar siempre la traza (trace o llamada secuencial de los métodos) completa de la excepción con su mensaje y todo el stacktrace.
Si la excepción es capturada, tratada y luego lanzada de nuevo (bien la misma u otra) no dejar traza de la excepción hasta que se capture y se trate en última instancia. De esta manera cada excepción solo se mostrará una vez. Si no lo hacemos así y registramos cada captura y relanzamiento aparecerá en la traza varias veces y no sabremos si es la misma o son varias. (Antipatrón catch-log-throw).
Hacer uso de la propiedad de excepción causante o interna cuando capturemos y relancemos la excepción. En Java es el método getCause(), en .NET la propiedad InnerException.
Implementar el método toString() de todas las clases de negocio o POJOs para facilitar su traceado.
Hay que tener en cuenta las diferencias y zonas horarias a la hora de trabajar con logs de varias máquinas o componentes.
El logging no puede tener efectos laterales, no puede modificar el estado de ningún parámetro, variable o procedimiento. Solo muestra información. Debe ser ligero, el propio logging no puede requerir de procesamientos largos o costosos.
Las llamadas a métodos, componentes y componentes distribuidos externos, deberían registrarse tras la llamada incluyendo los parámetros de entrada y la respuesta, así como clase/componente y método, a nivel de DEBUG. Y a nivel de ERROR y FATAL cuando ocurra un error en la llamada (si fuese una excepción se debe tracear parámetros de entrada y excepción)
En Java tenemos varias API's o librerías para llevar a cabo el logging de nuestra aplicación, siendo las mas comunes:
- Log4j2 antes Log4j
- Loogback
- JUL (Java Util Logging)
- Commons Logging
- SLF4J
martes, 26 de octubre de 2021
Aprendiendo el lenguaje Java
Ruta: Aprendiendo el lenguaje Java
Este ruta cubre los fundamentos de la programación en el lenguaje de programación Java.
Conceptos de la programación Orientada a Objetos
Conceptos básicos del lenguaje
Clases y Objetos
Anotaciones
Interfaces y Herencias
Números y Cadenas de caracteres (Strings)
Tipos Genéricos son una característica poderosa del lenguaje de programación Java. Mejoran la seguridad de tipos de su código, haciendo que más errores sean detectables en tiempo de compilación.
Paquetes (Packages)
Referencia: https://docs.oracle.com/javase/tutorial/java/index.html
domingo, 19 de septiembre de 2021
6 Herramientas para mejorar la productividad del desarrollador Java
Los desarrolladores de Java tienen perspectivas laborales muy altas en la industria del desarrollo de software. Con razón, Java impulsa muchas de las aplicaciones y servidores de escritorio, web y móviles del mundo. La mayoría de las empresas que reclutan desarrolladores de Java pertenecen a las industrias más maduras, como la atención médica y el Retail.
En consecuencia, es importante que los desarrolladores de Java sean eficaces y eficientes en sus trabajos.
A continuación se muestran seis de las herramientas más útiles que los desarrolladores de Java deberían considerar usar.
Netbeans
Son pocos los desarrolladores de Java que no conocen Netbeans. Es un entorno de desarrollo integrado (IDE) de código abierto en varios idiomas.
Lejos de ser un simple editor de texto, proporciona algunas características interesantes que ayudan a los desarrolladores a ser productivos.
Las características clave incluyen su resaltado de sintaxis que facilita la refactorización del código, ya que no solo le brinda información de sintaxis sino también de semántica. También proporciona excelentes plantillas y asistentes para una amplia gama de lenguajes de programación.
También es una plataforma de aprendizaje: tiene un tutorial completo de Java (y también PHP). Otra cosa que se destaca de Netbeans es que facilita a los desarrolladores la gestión de sus proyectos mediante el uso de favoritos y el control de versiones. También se sincroniza bien con Github.
La comunidad crea continuamente una gran cantidad de herramientas poderosas para hacer que el uso de Netbeans sea más placentero.
¿Cuál es tu nivel de conocimiento en NetBeans?, ¿Básico, medio o experto?.
Rookout
Como desarrollador de Java, al igual que con todos los desarrolladores, encontrar y solucionar errores son dos de las actividades que requieren más tiempo. Estos no solo consumen mucho tiempo, sino que causan mucha angustia innecesaria cada vez que parece que un error da origen a otros errores en el futuro.
El problema se agrava cuando el error se experimenta en producción y el equipo de operaciones querría que corrigiera los errores en el código de producción.
Si bien es importante contar con una buena estrategia de depuración, es aún más esencial contar con las herramientas adecuadas para ayudarlo a hacerlo. Después de todo, nuestros ojos humanos están limitados en lo que pueden sentir.
Aquí es donde una herramienta de depuración como Rookout puede ayudar. Te permite depurar en cualquier entorno. El equipo de operaciones quiere que vayas y averigües qué está mal con el código enviado a producción. Puede realizar una depuración remota en vivo allí. También puede implementar la depuración de producción, lo que permite una experiencia perfecta.
También mejora la colaboración al proporcionar excelentes datos e información sobre los errores encontrados y también comparte métricas comerciales a pedido.
Y tu, ¿ya has usado Rookout? ¿Te atreverías a probarlo?
JUnit
Corregir errores es una gran cosa. Pero, a menudo, el código que no presenta errores no se comporta como se esperaba durante la ejecución. Por ejemplo, declarar una calculo matemático incorrecto, tu programa puede no presentar errores de compilación, pero como garantizas que el resultado es el correcto?. O cuando realizas modificación en una clase, ¿Cómo garantizas que el cambio no impacta en toda la funcionalidad?
Este error se puede detectar mediante pruebas automatizadas.
JUnit es una herramienta de prueba elegida por los desarrolladores de Java. Es un Framework de código abierto. Por lo general, usa anotaciones para que las pruebas tengan accesorios antes de ejecutarlas. Algunas de sus ventajas incluyen la simplicidad de uso, proporciona informes de inmediato, no solo te permite escribir pruebas sino también todo un conjunto de pruebas.
La mayoría de los IDE son compatibles con JUnit, por lo que se ha convertido en uno de los Framework de prueba más populares, si no el más popular, para Java.
Y tu, ¿Haces pruebas unitarias de tus funcionalidades?
Apache Maven
Apache Maven es simplemente un software de gestión de proyectos de software. Si bien probablemente pueda usar cualquier otra herramienta para este propósito, Maven también administra compilaciones para sus proyectos Java.
Su principio de funcionamiento se basa en el concepto de modelo de objetos de proyecto (POM). La creación de un proyecto con Maven le facilitará automáticamente la creación de los siguientes. Una de las cosas que ayuda a aumentar la productividad de los desarrolladores de Java es su actualización automática de dependencias.
Dado que es de código abierto, la comunidad siempre agrega nuevas herramientas a su ya enorme biblioteca. No necesitará muchas configuraciones cuando lleguen nuevas herramientas útiles o se necesiten actualizaciones.
En este blog puedes encontrar muchos artículos útiles sobre Maven.
Git
Git es un software de control de versiones diseñado por Linus Torvalds, pensando en la eficiencia, la confiabilidad y compatibilidad del mantenimiento de versiones de aplicaciones cuando estas tienen un gran número de archivos de código fuente. Contar con un sistema de versionamiento te permitirá gestionar tu proyecto de forma flexible, revertir cambios, comparar versiones, aprobar cambios y restaurar cambios.
En este blog puedes encontrar una guía básica pero muy útil de GitHub
Apache Spark
Apache Spark permite a los desarrolladores de Java crear aplicaciones de procesamiento de datos intensivo. Permite procesar grandes cantidades de datos de forma rápida y escalable.
Es un marco basado en el modelo de programación MapReduce de Hadoop. Incluso amplía este modelo para incluir cálculos en una amplia gama de tipos de datos y tipos de consultas (incluida la transmisión).
A los desarrolladores de Java interesados en la ciencia de datos les encantará.
Conclusión
La productividad es más que usar herramientas. Es importante que un desarrollador también sepa jugar bien con todo el equipo. Sin embargo, estas herramientas, ya sea que se utilicen individualmente o juntas, de hecho pueden aumentar la cantidad de trabajo de calidad realizado por los desarrolladores.
jueves, 22 de julio de 2021
La Aplicacion Hola Mundo en Java
lunes, 5 de julio de 2021
Instalación de Java JDK y Netbeans
El JDK de Java
Open JDK y Oracle JDK
Las versiones de Java
Pasos para instalar Open JDK en Windows
El IDE NetBeans
Pasos para instalar Netbeans
Para poder continuar con nuestra ruta de aprendizaje de la tecnología Java necesitamos instalar el JDK (Java Development Kit) de Java. El JDK de Java es un entorno o ambiente de desarrollo para construir aplicaciones y componentes usando el lenguaje de programación Java.
El JDK de Java incluye herramientas útiles para desarrollar, probar, y monitorear programas escritos en el lenguaje de programación Java y que se ejecutan en la plataforma Java. Algunas de estás herramientas son los comandos javac, jar y programas como el jdkconsole
La tecnología de Java ha evolucionado con el tiempo, siempre buscando incorporar nuevas funcionalidades, simplificar el proceso de desarrollo para responder a los cambios de los requerimientos de una forma más ágil. La ultima versión de Java es la versión 16.
Oracle en los últimos años ha liberado las siguientes versiones
Java SE 8 (LTSL) Marzo 2014.
Java SE 9 Septiembre de 2017
Java SE 10 Marzo de 2018.
Java SE 11 (LTS) Septiembre de 2018.
Java SE 12 Marzo de 2019
Note que las versiones 9 y 10 no tienen ya soporte, Desde Java 10 Oracle estará liberando releases cada 6 meses, sin embargo no todos los releases serán LTS (Long Term Support, Soporte extendido), para este tipo de productos será tener un release LTS cada 3 años.
Existen dos implementaciones principales del JDK de Java, Open JDK y Oracle JDK, a mediados del 2019 Oracle realizó algunos cambios importantes en la licencia de uso de Java, es por esta razón que preferimos trabajar con Open JDK y es la implementación que vamos a instalar. La diferencia principal radica en el soporte y actualizaciones, siendo Oracle JDK la primera en obtener actualizaciones y soporte.
Crea tu directorio de desarrollo
Soy un pro de los estándares, para este curso te recomiendo crear un directorio de desarrollo, puedes crearlo donde más gustes, incluso en Mis Documentos. En mi caso he decido crearlo en una partición D.
D:\devel\java
+ src
+ tools
+ dist
Si decides crear tu directorio de desarrollo en Mis Documentos, entonces quedaría algo así:
C:\Users\RLopez\Documents\devel\java
+ src
+ tools
+ dist
Pasos para instalar OpenJDK en Windows
2.- Descomprimir en un directorio, en mi caso C:\devel\java\tools
3.- Crear la variable de entorno JAVA_HOME con la ruta C:\devel\java\tools\ Muchas aplicaciones Java requieren esta variable.
4.- Agregar a la variable de entorno Path la ruta %JAVA_HOME%\bin Si no lo haces tendrás que pasar la ruta completa cada que quieras ejecutar un programa Java.
5.- Comprobar
Te aconsejo reiniciar tu equipo, Windows debe dejar disponibles las variables de entorno a las aplicaciones.
Estructura de los directorios de Open JDK
Como conocimiento general daremos un repaso breve de los directorios dentro de Open JDK
/jdk-16.0.1/bin Los ejecutables y herramientas de linea de comandos.
/jdk-16.0.1/conf Las configuraciones .properties, .policy y otras configuraciones que pueden ser editados por los desarrolladores, y usuarios finales.
/jdk-16.0.1/lib Librerías necesarias para soportar la ejecución de nuestra maquina virtual.
/jdk-16.0.1/jmods La definición de los módulos incluidos en la versión
/jdk-16.0.1/legal Los archivos de las licencias para cada uno de los modulos.
/jdk-16.0.1/lib/src.zip Este directorio contiene el código fuente de la Plataforma Java.
/jdk-16.0.1/include Los archivos Header del lenguaje C, necesarios para soportar programación nativa mediante JNI (java native interface) y las interfaces para el Debugger de la JVM (Java Virtual Machine).
El IDE Netbeans
Un IDE es una herramienta de Desarrollo Integrado, tiene integrado las siguientes herramientas: editor de código, herramientas built como Ant o Maven, herramientas de versionamiento como SVN o Git.
Netbeans es más que un editor de código, tiene un potente asistente de código que te permite auto acompletar el código fuente y destacar la sintaxis y semántica del código fuente.
Escribí una serie de entradas sobre NetBeans que puedes encontrar en este blog con la etiqueta Netbeans.
Pasos para instalar Netbeans
1.- Descargar NetBeans, existen dos versiones para Windows, el binario y el instalador. Si descargas el instalador este viene con un asistente paso a paso. Para está guía he decidido descargar el binario de la versión 12.4 de NetBeans. Descargar NetBeans 12.4
2.- Descomprimir en un directorio, en mi caso C:\devel\java\tools
3.- Crear el acceso directo, entras al directorio de bin NetBeans y creas el acceso directo del ejecutable.
4.- Agregar al ejecutable la opción --jdkhome %JAVA_HOME%
5.- Ejecuta el acceso directo para asegurarte que funciona correctamente
Te dejo el video para que te sea más fácil. No olvides de suscribirte al canal y darle me gusta.
Referencias
https://blogs.oracle.com/java-platform-group/oracle-java-se-releases-faq
https://docs.oracle.com/en/java/javase/16/install/
https://www.oracle.com/cl/java/technologies/javase-subscription/documentation.html