El objetivo es escribir código java que detecte la versión JVM basándose en cambios de compatibilidad, efectos secundarios, errores y / o comportamiento indefinido que funcione de una manera en una versión y otra en otra. Además, el código debe ser al menos un poco legible, sin sacrificar espacios en blanco y nombres de variables legibles.
Para garantizar ese objetivo, las reglas formales exactas son:
El código debe estar escrito en Java y debe mostrar la versión JRE en la que se está ejecutando.
El código no debe usar ninguna API JDK o JRE proporcionada específicamente para detectar la versión de Java o que proporciona la versión JDK o JRE de forma gratuita.
El código no debe usar la reflexión.
El código solo es necesario para trabajar en Hotspot Java SE 5, 6 y 7, pero puede funcionar en otras JVM.
El código no debe usar ninguna biblioteca de terceros en el classpath.
El código no debe iniciar ningún otro proceso, java o no.
El código no debe usar variables de entorno.
El código no debe buscar en el sistema de archivos en busca de archivos o carpetas preexistentes.
El código debe estar contenido en un solo archivo y debe invocarse mediante
public static void main(String[] args)
opublic static void main(String... args)
.El código no debe usar ninguna API no pública presente en el JRE.
El código no debe generar ningún NoClassDefFoundError, NoSuchMethodError, ClassNotFoundException o NoSuchMethodException durante su ejecución.
El código debe ejecutarse en un sistema desconectado de Internet o de cualquier red local.
Debe proporcionar una explicación de por qué se comporta de una manera en una versión y de otra en otra.
Puntuación
El método utilizado para medir la mejor solución es max (n / s), donde n es el número de diferentes versiones de Java detectadas sin violar ninguna de estas reglas (al menos las versiones 5, 6 y 7) y s es el número de tokens léxicos En la solución.
fuente
Respuestas:
6/102 = 0.0588
Detecta 6 versiones. Cuenta con 102 fichas léxicas (frente a 103, después de que he eliminado
public
enpublic class
).Java 1.1 introdujo codificaciones de caracteres y algoritmos criptográficos en Java. Las versiones posteriores agregaron más codificaciones y algoritmos. Este programa intenta usar codificaciones y algoritmos hasta que detecta una excepción. Espero una codificación faltante para lanzar
java.io.UnsupportedEncodingException
y un algoritmo faltante para lanzarjava.security.NoSuchAlgorithmException
.Tenía un viejo PowerPC Macintosh con cuatro versiones antiguas de Java. Mi máquina OpenBSD tiene dos versiones más, así que probé estas seis versiones:
Este programa también puede ejecutarse en JamVM 1.5.4 y gcj 4.8.2 para OpenBSD, pero no los identifica como implementaciones diferentes. Solo imprime "Java 5".
Mac OS Runtime para Java
Gracias a "¡Escribe una vez, ejecuta en todas partes!", Puedo escribir este programa una vez, compilarlo una vez y ejecutar una clase GuessVersion.class en las ocho máquinas virtuales. Necesito un compilador para Java 1.1, la versión más antigua de mi colección.
Mi compilador es la
javac
herramienta de MRJ SDK 2.2. Debido a que el Mac OS clásico no tenía línea de comando,javac
es una herramienta bastante gráfica donde selecciono archivos y opciones y hago clic en "Do Javac". Después de editar mi código, solo hago clic en "Do Javac" nuevamente.La forma más fácil de ejecutar GuessVersion.class es abrirlo en JBindery, otra herramienta de MRJ SDK 2.2. El tiempo de ejecución es MRJ 2.2.6, una implementación de Java 1.1.8.
fuente
No estoy seguro de cuál es mi puntaje, porque depende de lo que consideres exactamente un token léxico, pero estoy tratando de abusar de ese sistema de conteo tanto como sea posible con una cadena larga ...
También depende de si cuenta esto como la identificación de 7 versiones diferentes o 16 ... (podría trivialmente extenderse hasta 190).
Funciona al intentar definir una interfaz en un cargador de clases personalizado con números de versión principales descendentes del formato de clase. El primero que no arroja un
java.lang.UnsupportedClassVersionError
corresponde a la versión de la VM.fuente
String... args
.protected Class loadClass(String name, boolean resolve) { return Object.class; }
. Los documentos API actuales no mencionan cómo se trataba de un método abstracto antes de Java 1.2. Devuelvo Object.class porque el método recibe una llamada para "java.lang.Object".El algoritmo interno cambió entre Java 6 y 7. Consulte /programming//a/7224864/540552
XMLGregorianCalendar.equals (null) solía lanzar NullPointerException en java 5, pero esto se solucionó en java 6. Consulte http://bugs.sun.com/view_bug.do?bug_id=6285370
10096928785 fichas aquí. Gracias a Peter Taylor por reducir 7 tokens.fuente
DatatypeConfigurationException
no se lanzará.int a
pero inicialícelo de inmediato, para que elif
bloque se vacíe. Niegue la condición, elimine el else y use en--
lugar de la asignación directa aa
.