lunes, 4 de octubre de 2021

Java 8 Update 301 (8u301)

 

ava 8 Update 301 (8u301)

Características principales de la versión
  • IANA TZ Data 2021a.
    JDK 8u301 contiene datos de zona horaria IANA, versión 2021a. Para obtener más información, consulte Versiones de datos de zona horaria en el software de JRE.
  • Nueva función: Personalización de generación de almacén de claves PKCS12
    Se han agregado nuevas propiedades de sistema y seguridad para que el usuario pueda personalizar la generación de almacenes de claves de PKCS #12. Incluye algoritmos y parámetros para la protección de claves y certificados y datos de MAC. Puede encontrar una explicación detallada y valores posibles para estas propiedades en la sección "Propiedades de almacén de claves PKCS12" del archivo java.security.
    Consulte JDK-8076190
  • Funciones y opciones eliminadas: eliminación de certificados raíz con claves de 1024 bits
    Se han eliminado los certificados raíz con claves públicas RSA de 1042 bits débiles del almacén de claves de CAcert.
    Consulte JDK-8243559
  • Funciones y opciones eliminadas: eliminación del certificado CA Sonera Class2 de la compañía Telia
    Se ha eliminado el siguiente certificado raíz del almacén de confianza de CAcert:
    + Telia Company
    + soneraclass2ca
    DN: CN=Sonera Class2 CA, O=Sonera, C=FI

    Consulte JDK-8225081
  • Otras notas: actualización de los algoritmos de cifrado por defecto PKCS12
    Se han actualizado los algoritmos de cifrado por defecto utilizados en un almacén de claves PKCS #12. Los nuevos algoritmos basados en AES-256 y SHA-256 son más seguros que los algoritmos anteriores basados en RC2, DESede, y SHA-1. Consulte las propiedades de seguridad que empiezan por keystore.pkcs12 en el archivo java.security para obtener información detallada.
    Para garantizar la compatibilidad, se ha definido una nueva propiedad de sistema que revertirá los algoritmos para poder utilizar los algoritmos antiguos, más débiles, llamada keystore.pkcs12.legacy. No se ha definido ningún valor para esta propiedad.
    Consulte JDK-8153005
Actualización de JDK

Oracle recomienda que se actualice el JDK con cada actualización de parche crítico. Para determinar si una versión es la más reciente, la página de Security Baseline se puede utilizar para determinar cuál es la versión más reciente de cada familia de versiones.

Las actualizaciones de parches críticos, que contienen correcciones de vulnerabilidades de seguridad, se anuncian con un año de antelación en la sección Critical Patch Updates, Security Alerts and Bulletins. No se recomienda que este JDK (versión 8u301) se utilice después de la próxima actualización de parche crítico programada para el 19 de octubre de 2021.

Los clientes con suscripción a Java SE que gestionen actualizaciones/instalaciones de JRE para un gran número de escritorios deben considerar utilizar Java Advanced Management Console (AMC).

Para los sistemas que no se pueden ejecutar en servidores Oracle, un mecanismo secundario se encargará de hacer que caduque esta versión de JRE (versión 8u301) el 19 de noviembre de 2021. Una vez se haya cumplido cualquiera de las condiciones (que la nueva versión esté disponible o que se haya alcanzado la fecha de caducidad), el JRE enviará mensajes de advertencia y recordatorios sobre la nueva versión. Para más información, consulte 23.1.2 Fecha de caducidad de JRE en la Guía de despliegue de Java Platform, Standard Edition.

Correcciones de bugs

Esta versión contiene correcciones para las vulnerabilidades de seguridad descritas en el Aviso de actualización de parche crítico de Oracle. Para acceder a una lista más completa de las correcciones de bugs que incluye esta versión, consulte la página Correcciones de bugs de JDK 8u301.

» Notas técnicas sobre la versión 8u301

miércoles, 11 de marzo de 2020

Java string literal vs string object

Java string literal vs string object

Java string literal vs string object . ¿Qué diferencia existe entre las dos opciones? . Normalmente cuando trabajamos en Java solemos crear un String de forma rápida asignando una literal . Pero al tratarse de una clase tenemos la posibilidad de crearlo también como un objeto . El hecho disponer de varias posibilidades suele generar dudas sobre cual es la mejor. Vamos a entrar un poco más a detalle sobre este tema y aclarar las cosas que son un poco peculiares. Supongamos que partimos del siguiente bloque de código.
  1. package com.arquitecturajava;
  2. public class Principal {
  3. public static void main(String[] args) {
  4. String mensaje1="hola";
  5. String mensaje2="hola2";
  6. System.out.println(mensaje1);
  7. System.out.println(mensaje2);
  8. }
  9. }
El resultado saldrá por la consola y simplemente muestra la información.
código inicial
Hasta aquí no hay ningún problema se trata de dos objetos Java y cada uno emite su propia información . Podemos construir una segunda versión del programa que generará algunas dudas razonables.
  1. package com.arquitecturajava;
  2. public class Principal {
  3. public static void main(String[] args) {
  4. String mensaje1="hola";
  5. String mensaje2="hola";
  6. System.out.println(mensaje1==mensaje2);
  7. System.out.println(mensaje1.equals(mensaje2));
  8. }
  9. }
java objetos diferentes
En este caso nos encontramos comprobando si los dos mensajes contienen el mismo contenido y si al ser dos objetos en memoria diferentes el comprobar la igualdad con == nos devuelve true o false. Todo parece bastante claro ya que son dos objetos diferentes en memoria con contenidos diferentes. Es normal que el resultado devuelva false y false.

Java string literal vs string object e igualdad

El problema real comienza cuando nosotros modificamos el código por el siguiente.
  1. package com.arquitecturajava;
  2. public class Principal {
  3. public static void main(String[] args) {
  4. String mensaje1="hola";
  5. String mensaje2="hola2";
  6. System.out.println(mensaje1==mensaje2);
  7. System.out.println(mensaje1.equals(mensaje2));
  8. }
  9. }
java igualdad
Es aquí donde las cosas nos sorprenden un poco , es fácilmente entendible que el segundo System.out devuelva true ya que los dos objetos en memoria contienen el mismo texto . Ahora bien lo que sorprende mucho es que el primer método devuelva true. ¿Cómo es esto posible? se trata de dos objetos diferentes y antes devolvía false como es que ahora simplemente cambiando el contenido de los textos el resultado es true. Para entender esto tenemos que abordar el concepto de Java String pool.

Java Pools y Strings

Cuando nosotros usamos literales a la hora de definir cadenas ocurre una cosa curiosa que Java interpreta que es una de las cadenas más típicas con las que vamos a trabajar y las ubica dentro de un pool especial de Strings para no tener que volver a construir ese objeto jamas .
java string pool
Por ejemplo es util en concatenaciones que muchas veces usan caracteres tipo “,” esa coma irá directamente al pool de strings. Por lo tanto no se genera un objeto cada vez que definimos una cadena como literal sino que se busca primero en el pool a ver si ese objeto existe.

Java string object

No sucederá lo mismo cuando nosotros construyamos un String con el operador new . En este caso siempre se creará un objeto nuevo , por lo tanto si la nueva versión del código fuera :
java string sin pool
Esto es mucho más común y es el comportamiento clásico cuando trabajamos con dos objetos diferentes.

Java String y curiosidades

La clase String soporta algunas curiosidades respecto a este tipo de funcionamiento ya que nos permite añadir al pool de Strings las cadenas que deseemos simplemente invocando a String.intern() . De esta manera si un objeto se creo como literal y por temas de rendimiento lo queremos añadir al pool Java lo hará por nosotros.
  1. package com.arquitecturajava;
  2. public class Principal {
  3. public static void main(String[] args) {
  4. String mensaje1=new String("hola");
  5. String mensaje1A=mensaje1.intern();
  6. String mensaje2="hola";
  7. System.out.println(mensaje1A==mensaje2);
  8. System.out.println(mensaje1.equals(mensaje2));
  9. }
  10. }
En este código podemos observar como obligamos con el método intern a añadir una cadena al pool y la volvemos a referenciar. Acto seguido creamos un string literal con el mismo nombre que el anterior. el resultado por la consola será que ambos apuntan al mismo objeto.
java string literal

Fuente

Java ArrayList for y sus opciones

Java ArrayList for y sus opciones

Java ArrayList for y las opciones para recorrerlos siempre vuelven locos a los principiantes y a algunos que no lo son tanto ya que cuando tenemos muchas opciones pues siempre se generan dudas a la hora de elegir. Vamos a ver cómo recorrer una lista de elementos de forma sencilla y abordar las diferentes posibilidades.

Java ArrayList for y size()

La forma más sencilla de recorrer una lista es a través de un bucle for y accediendo a la propiedad size.
java arraylist for clasico
Veámoslo en código:
  1. package com.arquitecturajava;
  2. import java.util.ArrayList;
  3. public class JavaFor {
  4. public static void main(String[] args) {
  5. ArrayList<String> lista = new ArrayList<String>();
  6. lista.add("hola");
  7. lista.add("que");
  8. lista.add("tal");
  9. lista.add("estas");
  10. lista.add("hoy");
  11. for (int i=0;i<lista.size();i++) {
  12. System.out.println(lista.get(i));
  13. }
  14. }
  15. }
El resultado se muestra en la consola:
java resultado
Cuando uno empieza esta forma parece la más clara y no parece tener mucha problemática . Sin embargo algunas veces sucede que los desarrolladores al recorrer la lista no asignan correctamente el lista.size() o ponen otro valor sobre todo cuando se es muy novato. Por lo tanto puede generarse un NullPointerException. No solo eso sino que es una forma de recorrer elementos que solo nos vale para los ArrayList.

Java for e Iteradores

Una alternativa a esta situación es usar un Iterador .Un Iterador es un interface que dispone de los métodos hasNext() y next() y nos permite recorrer una colección de elementos.
java arraylist for
Da lo mismo que sea un ArrayList que otra estructura. Por lo tanto aporta homogeneidad en las APIs.
  1. package com.arquitecturajava;
  2. import java.util.ArrayList;
  3. import java.util.Iterator;
  4. public class JavaFor2 {
  5. public static void main(String[] args) {
  6. ArrayList<String> lista = new ArrayList<String>();
  7. lista.add("hola");
  8. lista.add("que");
  9. lista.add("tal");
  10. lista.add("estas");
  11. lista.add("hoy");
  12. Iterator<String> it= lista.iterator();
  13. while(it.hasNext()) {
  14. System.out.println(it.next());
  15. }
  16. }
  17. }

Java 5 ArrayList for

A partir de Java 5 aparece el concepto de bucle forEach y permite simplificar la forma en la que trabajamos con los Iteradores.
  1. package com.arquitecturajava;
  2. import java.util.ArrayList;
  3. public class JavaFor3 {
  4. public static void main(String[] args) {
  5. ArrayList<String> lista = new ArrayList<String>();
  6. lista.add("hola");
  7. lista.add("que");
  8. lista.add("tal");
  9. lista.add("estas");
  10. lista.add("hoy");
  11. for (String cadena: lista) {
  12. System.out.println(cadena);
  13. }
  14. }
  15. }
Como se puede observar la forma de recorrer una lista se simplifica sobremanera comparado con el Iterador que aunque genera homogeneidad siempre era complicado de usar. Esta es una de las opciones más recomendadas hasta la llegada de Java 8.

Java 8 y Streams.

En Java 8 tenemos un salto importante a niveles de programación ya que entran todas las capacidades funcionales y con ello se pueden simplificar el manejo de listas a través de streams .
  1. package com.arquitecturajava;
  2. import java.util.ArrayList;
  3. public class JavaFor3 {
  4. public static void main(String[] args) {
  5. ArrayList<String> lista = new ArrayList<String>();
  6. lista.add("hola");
  7. lista.add("que");
  8. lista.add("tal");
  9. lista.add("estas");
  10. lista.add("hoy");
  11. lista.forEach(System.out::println);
  12. }
  13. }
La simplificación es clara aun así nos quedan situaciones clásicas en las que un bucle de forEach de Java 5 nos aporta más ya que por ejemplo deseamos cambiar el contenido de los elementos del Array y luego imprimirlo.
  1. package com.arquitecturajava;
  2. import java.util.ArrayList;
  3. public class JavaFor6 {
  4. public static void main(String[] args) {
  5. ArrayList<String> lista = new ArrayList<String>();
  6. lista.add("hola");
  7. lista.add("que");
  8. lista.add("tal");
  9. lista.add("estas");
  10. lista.add("hoy");
  11. for (int i = 0; i < lista.size(); i++) {
  12. lista.set(i, lista.get(i).toUpperCase());
  13. }
  14. for (String cadena : lista) {
  15. System.out.println(cadena);
  16. }
  17. }
  18. }
Este bloque nos recorrera el array y volverá a recorrerlo de una forma clásica para mostrar la información en pantalla actualizada.
mayusculas
¿Existe una forma de realizar esta operación de una forma más compacta en Java 8 ? . La realidad es que sí . Podemos usar el método replaceAll del ArrayList que recibe un interface funcional y permite actualizar todos los elementos de golpe a continuación usaremos el método forEach.
  1. package com.arquitecturajava;
  2. import java.util.ArrayList;
  3. public class JavaFor5 {
  4. public static void main(String[] args) {
  5. ArrayList<String> lista = new ArrayList<String>();
  6. lista.add("hola");
  7. lista.add("que");
  8. lista.add("tal");
  9. lista.add("estas");
  10. lista.add("hoy");
  11. lista.replaceAll(String::toUpperCase);
  12. lista.forEach(System.out::println);
  13. }
  14. }
De esta forma el resultado será idéntico pero con mucho menos código.

Fuente: Arquitectura Java