overview jdk español documentacion java java-api

java - jdk - ¿Qué tan peligroso es el uso de sun.misc.Unsafe en realidad?



java 8 overview (2)

Durante una sesión de JavaOne 2013, Mark Reinhold (el arquitecto de JDK) tuvo una pregunta: "¿Qué tan seguro es usar la clase Insegura?". Respondió con una especie de respuesta sorprendente: "Creo que debería convertirse en una API estable. Por supuesto, debidamente protegida con controles de seguridad, etc."

Así que parece que puede haber algo como java.util.Unsafe para JDK9. Mientras tanto, usar la clase existente es relativamente seguro (tan seguro como hacer algo inseguro puede ser).

Me pregunto qué tan peligroso es el uso de sun.misc.Unsafe realidad. Quiero crear un proxy de un objeto donde intercepto cada llamada de método (pero la de Object.finalize para consideraciones de rendimiento). Para este propósito, busqué un poco en Google y encontré el siguiente fragmento de código:

class MyClass { private final String value; MyClass() { this.value = "called"; } public void print() { System.out.println(value); } } @org.junit.Test public void testConstructorTrespassing() throws Exception { @SuppressWarnings("unchecked") Constructor<MyClass> constructor = ReflectionFactory.getReflectionFactory() .newConstructorForSerialization(MyClass.class, Object.class.getConstructor()); constructor.setAccessible(true); assertNull(constructor.newInstance().print()); }

Mi consideración es:

  • A pesar de que Java se anuncia como Escribir una vez, ejecutar en todas partes mi realidad como desarrollador se parece a Escribir una vez, ejecutar una vez en un entorno de tiempo de ejecución de un cliente controlable
  • Se considera que sun.misc.Unsafe se convierte en parte de la API pública en Java 9
  • Muchas máquinas virtuales que no son de Oracle también ofrecen sun.misc.Unsafe ya que, supongo, ya hay bastantes bibliotecas que lo utilizan . Esto también hace que la clase no desaparezca.
  • Nunca voy a ejecutar la aplicación en Android, así que esto no me importa.
  • ¿Cuántas personas en realidad están usando máquinas virtuales que no sean de Oracle?

Todavía me pregunto: ¿Hay otras razones por las que no debería usar sun.misc.Unsafe No pensé? Si busca en Google estas preguntas, la gente prefiere responder a una pregunta no especificada porque no es segura, pero realmente no creo que sea una posibilidad (muy poco probable) de que el método desaparezca algún día de la máquina virtual de Oracle.

Realmente necesito crear un objeto sin llamar a un constructor para superar el sistema de tipos de Java. No estoy considerando sun.misc.Unsafe por razones de rendimiento .

Información adicional : estoy usando ReflectionFactory en el ejemplo para conveniencia que delega a Unsafe eventualmente. Conozco bibliotecas como objenesis pero observando el código descubrí que básicamente hacen algo similar, pero comprueban otras formas al usar versiones de Java que de todos modos no me funcionarían, así que creo que escribir cuatro líneas vale la pena guardar una dependencia.


Hay tres problemas importantes (OMI):

  • Los métodos en la clase Unsafe tienen la capacidad de violar la seguridad del tipo de tiempo de ejecución, y hacer otras cosas que pueden hacer que su JVM se "estrelle".

  • Virtualmente, cualquier cosa que haga usando Inseguro podría, en teoría, depender de los detalles internos de la JVM; Es decir, detalles de cómo la JVM hace las cosas y las representa. Estos pueden ser dependientes de la plataforma y pueden cambiar de una versión de Java a la siguiente.

  • Los métodos que está utilizando ... o incluso el nombre de la clase en sí ... pueden no ser los mismos en diferentes versiones, plataformas y proveedores.

En mi opinión, estas son razones sólidas para no hacerlo ... pero eso es una cuestión de opinión.

Ahora, si Unsafe convierte en parte estandarizada de la API de Java estándar (por ejemplo, en Java 9), entonces algunos de los problemas anteriores serían discutibles. Pero creo que el riesgo de choques fuertes si cometes un error siempre se mantendrá.