Java7 Lenguajesdinamicos
Java7 Lenguajesdinamicos
Java7 Lenguajesdinamicos
Tabla de contenido
1. Introduccin ............................................................................................................................. 2 1.1. Introduccin a los lenguajes dinmicos........................................................................... 2 2. Lenguajes dinmicos ejecutados sobre la mquina virtual Java ........................................... 4 3. Especificacin JSR-292 y Java 7............................................................................................ 5 4. El paquete java.lang.invoke .................................................................................................... 6 4.1. Primeras prcticas con el paquete java.lang.invoke ....................................................... 8 Prctica 1: Un ejemplo simple con invocador dinmico ......................................................... 9 Prctica 2: Diferencia entre lookup y publicLookup.............................................................. 11 Prctica 3: Diferencia entre invoke() e invokeExact() en el retorno de parmetros. ........... 12 Prctica 4: Diferencia entre MutableCallSite y ConstantCallSite. ........................................ 14 Prctica 5: Invocando a mtodos con parmetros de entrada y salida ............................... 16 Prctica 6: El mtodo filterReturnValue a fondo................................................................... 18 Prctica 7: Invocar a constructores....................................................................................... 19 Prctica 8: Acceder a las campos de la clase ...................................................................... 20 Prctica 9: Mtodos estticos ............................................................................................... 21 Prctica 10: Trabajando con interfaces ................................................................................ 22 5. Conclusiones ......................................................................................................................... 23 6. Anexo: Referencias ............................................................................................................... 24
www.javahispano.org
1. Introduccin
Una de las novedades ms destacadas que incorpora Java 7 es el soporte mejorado a los lenguajes dinmicos. Esta nueva caracterstica es de gran transcendencia, debido a dos factores totalmente distintos, por un lado la clara apuesta de Oracle por abrir camino y apoyar a otros lenguajes de programacin capaces de ejecutarse sobre la mquina virtual de Java y que actualmente se encuentran en pleno auge. Por otro lado, esta nueva peculiaridad del lenguaje Java, ha implicado importantes cambios a nivel de la propia mquina virtual, incorporando nuevas instrucciones bytecode. Recordar que la filosofa de estos lenguajes dinmicos rompe un poco con la de Java que se identifica por su sintaxis principalmente esttica.
www.javahispano.org
En el listado 1.1, para los acostumbrados a los lenguajes estticos, lo primero que nos puede llamar la atencin es la asignacin de un valor a la variable a sin haber definido antes el tipo de dato que recibir. A continuacin, como en cualquier otro lenguaje, realizamos una operacin aritmtica de suma, para posteriormente mostrar en un mensaje, el nuevo valor adquirido, que como podremos comprobar, an es un tipo numrico. En el siguiente paso concatenamos una cadena de texto a la misma variable, y aqu viene la magia de los lenguajes dinmicos, la variable ha pasado a ser un tipo de dato alfanumrico como comprobaremos al mostrar el mensaje por pantalla. Podemos convertir el listado anterior en una nica funcin, mientras que si lo comparamos con un lenguaje de programacin esttico, necesitaremos al menos dos funciones:
<html> <script> function doTest(salida){ alert(salida); } a = 1; a = a + 3; doTest(a);//Llamamos a la funcin pasndole un dato numrico a = a + "hola mundo"; doTest(a); //Llamamos a la funcin pasndole un dato tipo texto </script> </html>
Listado 1.2 Lenguaje dinmico JavaScript II
package org.javahispano; public class TestEstatico { public static void main(String[] args) { int a = 1; a = a + 3; doTest(a); String strB = a + "hola mundo"; doTest(strB);
www.javahispano.org
En la siguiente tabla podemos encontrar algunos de los lenguajes clasificados como dinmicos: ActionScript ColdFusion E programming language Matlab Perl Ruby BASIC Common Lisp and some other Lisps JavaScript Lua PHP Smalltalk BeanShell Groovy VBScript Objective-C Python Tcl
Java 7: Soporte a lenguajes dinmicos Python REXX Ruby Tcl Jython NetRexx[4] JRuby Jacl
Otra caracterstica de algunos de estos lenguajes es que a la hora de ejecutarlos tenemos dos opciones: Ejecutar directamente el cdigo fuente sobre la mquina virtual a travs de ciertas clases Java que lo interpretarn. Compilar el cdigo fuente generando bytecode compatible con el de la JVM.
Existen al menos dos especificaciones que estandarizan este tipo de lenguajes: JSR-223: Fija los mecanismos para los lenguajes scripting basados en Java. JSR-292: Fija los mecanismos para proporcionar un mejor soporte a los lenguajes dinmicos ejecutados sobre la JVM.
En este artculo nos centraremos principalmente en la especificacin JSR292, siendo esta la que ha fijado los estndares para este nuevo soporte a los lenguajes dinmicos en Java 7, aunque no podemos olvidar que ambas especificaciones son compatibles, es decir, un lenguaje scripting puede ser tambin dinmico. Un claro ejemplo de ello es Groovy, que puede ser un lenguaje de scripting a la vez que dinmico.
Java 7: Soporte a lenguajes dinmicos uso intensivo de la misma, es decir es bastante ms lento invocar a un mtodo de una clase a travs de este API que hacerlo directamente, quedando linkada en tiempo de compilacin. Como mencionamos anteriormente la adopcin de la especificacin JSR-292 en Java 7, sobre todo trasciende a nivel de bytecode, aunque tambin ha dado lugar a la inclusin de un nuevo paquete java.lang.invoke. Para un desarrollador Java, esta nueva especificacin solo le ofrece una forma ms eficiente de hacer reflection, pero donde realmente se explotar todo su potencial es en este tipo de lenguajes dinmicos, que sern capaces de generar bytecode optimizado para un mayor rendimiento sobre la JVM.
4. El paquete java.lang.invoke
En esta seccin repasaremos brevemente la definicin del paquete java.lang.invoke. Se trata de presentar de una forma muy simplificada las clases que componen dicho paquete, as como algunos de sus mtodos. Debe tener en cuenta que el API es algo ms complejo de lo que se representa en el presente documento. Aun as, no se preocupe si no termina entender las definiciones ilustradas tericamente, los ejemplos plasmados posteriormente le sern de gran ayuda para lograr una base de conocimientos bsicos de esta nueva funcionalidad: CallSite ser la clase que tomaremos de partida a la hora de implementar invocaciones dinmicas. Envolver a la clase MethodHandle utilizada para hacer referencia al objeto que se desea invocar (target). Se trata de una clase abstracta, y por lo tanto no se puede instanciar directamente, para ello utilizaremos alguna de sus tres implementaciones: ConstantCallSite: Usaremos esta clase para invocar a los mtodos, campos o constructores de un objeto. La peculiaridad es que la instancia del objeto no podr ser variada. MutableCallSite: Al contrario que la clase anterior, podremos modificar el target, cambiando la instancia del objeto con la que estamos trabajando. VolatileCallSite: Acta igual que las variables voltiles. Algunos de los mtodos que podemos encontrar en esta clase abstracta son: <MethodHandle> dynamicInvoker(): Linkar al objeto a instanciar (target) a travs de la nueva instruccin bytecode invokedynamic. A travs de este mtodo conseguiremos un mayor rendimiento en la invocacin de los mtodos y campos del objeto. <MethodHandle> getTarget(): Retorna una instancia de MethodHandle con la referencia al objeto target con el que estamos trabajando. <void> setTarget(MethodHandle newTarget): Configura un nuevo objeto sobre el que operar a travs de la clase MethodHandle. <MethodType> type(): Retorna una instancia MethodType donde se encuentran algunas de las caractersticas del target.
www.javahispano.org
Java 7: Soporte a lenguajes dinmicos MethodHandle: Utilizada para apuntar y ejecutar mtodos del target (instancia del objeto referenciada desde alguna de las implementaciones de la clase CallSite). Al tratarse de una clase abstracta, no podr instanciarse directamente, para obtener una referencia a la misma utilizaremos la clase MethodHandles. Entre los diferentes mtodos ofrecidos por esta clase, haremos espacial hincapi en los dos siguientes: <Object> invoke(Object... args): Invoca al mtodo manejado por la clase MethodHandle. Retornar el valor devuelto por el mismo. <Object > invokeExact(Object... args): Al igual que el caso anterior invoca al mtodo manejado por la clase MethodHandle, con la salvedad que ser necesarin realizar un cast al objeto exacto retornado por dicho mtodo. MethodHandles: A travs de ella ser posible obtener referencia a una instancia de MethodHandle que es capaz de ejecutar uno o varios mtodos del target referenciado. Por ejemplo es posible buscar un mtodo dentro de una clase dado un patrn o tratar el resultado de la ejecucin de uno de estos mtodos aplicndolo como parmetro a otro. Esta clase se compone exclusivamente de mtodos estticos. Entre ellos podemos destacar: <static MethodHandles.Lookup> lookup(): Retorna una instancia de MethodHandles.Lookup a travs de la cual podremos buscar campos, mtodos o constructores del target. La restricciones de acceso a los miembros del target sern las mismas que si tratsemos de acceder al objeto directamente en tiempo de compilacin (sin usar reflection ni el paquete java.lang.invoke). <static MethodHandles.Lookup> publicLookup(): Funcionalidad idntica a la anterior, con la salvedad de que en este caso solo ser posible acceder a los miembros pblicos del objeto con el que deseamos trabajar. <static MethodHandle> filterReturnValue(MethodHandle target, MethodHandle filter): Utilidad para procesar el resultado de la ejecucin de un mtodo a travs de otro mtodo manejado. MethodHandles.Lookup: Factora para crear las instancias de la clase MethodHandle. Entre todos sus mtodos podemos destacar: <MethodHandle> findConstructor(Class<?> refc, MethodType type): Utilidad para invocar a los constructores de una clase. <MethodHandle> findGetter(Class<?> refc, String name, Class<?> type): Utilidad para acceder en modo lectura al valor de un campo de la clase.. <MethodHandle> findSetter(Class<?> refc, String name, Class<?> type): Utilidad para acceder en modo escritura a un campo de la clase. <MethodHandle> findStatic(Class<?> refc, String name, MethodType type): Utilidad para invocar a los mtodos estticos de una clase. <MethodHandle> findStaticGetter(Class<?> refc, String name, Class<?> type): Utilidad para acceder en modo lectura a un campo esttico de una clase. <MethodHandle> findStaticSetter(Class<?> refc, String name, Class<?> type): Utilidad para acceder en modo escritura a un campo esttico de una clase. <MethodHandle> findVirtual(Class<?> refc, String name, MethodType type): Utilidad para invocar a cualquier mtodo de una clase.
www.javahispano.org
Java 7: Soporte a lenguajes dinmicos MethodHandleProxies: Clase compuesta por mtodos estticos que crean instancias de MethodHandle capaces de trabajar con otros tipos de elementos, como por ejemplo interfaces. Algunos de sus mtodos son: <<T> T> asInterfaceInstance(Class<T> intfc, MethodHandle target): Convierte la instancia de un objeto en la implementacin de un interface que originalmente no implementaba. Esta utilidad solo funcionar para interfaces de un nico mtodo. <boolean> isWrapperInstance(Object x): Determina si el objeto recibido como parmetro ha sido convertido a travs de la utilidad asInterfaceInstance. MethodType: Clase final a travs de la cual se definir la firma del mtodo a invocar, es decir, se establecern los tipos de datos de entrada y salida del mtodo. SwitchPoint: Clase para controlar el estado de ciertas ejecuciones dinmicas. WrongMethodTypeException: Envolver algunas de las excepciones producidas en el paquete.
package org.javahispano; public class TestClass { public String strCampoPublico = "HOLA MUNDO"; private String strCampoPrivado = "Hey"; public TestClass() { System.out.println("Ejecutando constructor sin parmetros"); } public TestClass(String saludo) { System.out.println("Ejecutando constructor " + saludo); this.strCampoPrivado = saludo; } protected void metodoSinRetornoNiParametros() { System.out.println("TestObj::Metodo sin retorno ni parametros"); } public void metodoParaThread() {
www.javahispano.org
3. Definimos los parmetros de entrada y salida del mtodo. En este caso, como el mtodo no recibe parmetros, solo nos vemos obligados a declarar el retorno.
//Parmetros de salida MethodType MT_void = MethodType.methodType(void.class);
5. Invocamos al mtodo.
MH_metodoSinRetornoNiParametros = MethodHandles.filterReturnValue(MH_name, MH_metodoSinRetornoNiParametros); MH_metodoSinRetornoNiParametros.invokeExact( );
package org.javahispano; import java.lang.invoke.CallSite; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.invoke.MutableCallSite; public class Ejemplo { public static void main(String[] args) throws Throwable{ new Ejemplo().test1(); } public void test1() throws Throwable{ //CallSite que nos permitir variar el target CallSite name = new MutableCallSite(MethodType.methodType(TestClass.class); name.setTarget(MethodHandles.constant(TestClass.class, new TestClass())); //invocador dinmico MethodHandle MH_name = name.dynamicInvoker(); //Parmetros de salida MethodType MT_void = MethodType.methodType(void.class);
www.javahispano.org
10
El resultado que obtendremos al ejecutar la clase anterior ser similar a la salida representada en la siguiente imagen:
Incluyendo la lnea anterior en el listado 1.5, ahora obtendremos la siguiente excepcin en tiempo de ejecucin:
www.javahispano.org
11
public void test3() throws Throwable{ //CallSite que nos permitir variar el target CallSite name = new MutableCallSite(MethodType.methodType(TestClass.class)); name.setTarget(MethodHandles.constant(TestClass.class, new TestClass(Adios))); //invocador dinmico MethodHandle MH_name = name.dynamicInvoker(); //Parmetro de retorno MethodType MT_string = MethodType.methodType(String.class); Lookup lookup = MethodHandles.lookup(); String nomMetodo = "metodoConRetornoStringSinParametros"; MethodHandle MH_metConRetSinParam = lookup.findVirtual(TestClass.class, nomMetodo , MT_string); MH_metConRetSinParam = MethodHandles.filterReturnValue(MH_name, MH_metConRetSinParam); System.out.println("Retorno del mtodo " + (String)MH_metConRetSinParam.invokeExact( )); }
Listado 1.7 Prctica 3: Mtodo con retorno
Podemos ver que el cdigo expuesto en esta prctica guarda bastantes similitudes con el listado 1.5, con la salvedad que en esta ocasin el mtodo a invocar retorna un dato de tipo www.javahispano.org
12
Java 7: Soporte a lenguajes dinmicos String mostrado por consola a travs de un System.out. Por lo tanto el resultado de la ejecucin de este listado debera ser igual al de la figura 1.3:
En la ltima lnea del listado 1.7 se realiza un cast al tipo de retorno correcto del mtodo invocado. Este cast es totalmente necesario, ya que si tratamos de omitirlo obtendremos un error:
En cambio, es posible sustituir el mtodo invokeExact() por invoke(), evitando este tipo de errores: www.javahispano.org
13
System.out.println("Retorno del mtodo " + MH_metConRetSinParam.invoke()); System.out.println("Retorno del mtodo " + (Object) MH_metConRetSinParam.invoke());
Listado 1.8 Prctica 3: Mtodo invoke()
public void test4() throws Throwable { // CallSite que nos permitir variar el target CallSite name = new MutableCallSite( MethodType.methodType(TestClass.class)); name.setTarget(MethodHandles.constant(TestClass.class, new TestClass( "Adios"))); // invocador dinmico MethodHandle MH_name = name.dynamicInvoker(); // Parametro de retorno MethodType MT_string = MethodType.methodType(String.class); Lookup lookup = MethodHandles.lookup(); String nomMetodo = "metodoConRetornoStringSinParametros"; MethodHandle MH_metConRetSinParam = lookup.findVirtual(TestClass.class, nomMetodo, MT_string); MH_metConRetSinParam = MethodHandles.filterReturnValue(MH_name, MH_metConRetSinParam); System.out.println("Retorno del mtodo " + MH_metConRetSinParam.invoke()); // Variamos el target name.setTarget(MethodHandles.constant(TestClass.class, new TestClass( "Aupa!"))); System.out.println("Retorno del mtodo " + MH_metConRetSinParam.invoke()); }
Listado 1.9 Prctica 4: MutableCallSite
www.javahispano.org
14
Java 7: Soporte a lenguajes dinmicos Si ejecutamos el listado anterior vemos como variamos la instancia del objeto con la que estamos trabajando, al llamar dos veces al constructor de la clase y reescribir el target mediante el mtodo setTarget:
A continuacin trataremos de realizar lo mismo que en el listado 1.9, pero usando un target de tipo ConstantCallSite:
public void test4() throws Throwable { // CallSite que NO nos permitir variar el target // El constructor es algo distinto al del MutableCallSite CallSite name = new ConstantCallSite(MethodHandles.constant( TestClass.class, new TestClass("Adios"))); // invocador dinmico MethodHandle MH_name = name.dynamicInvoker(); // Parmetro de retorno MethodType MT_string = MethodType.methodType(String.class); Lookup lookup = MethodHandles.lookup(); String nomMetodo = "metodoConRetornoStringSinParametros"; MethodHandle MH_metConRetSinParam = lookup.findVirtual(TestClass.class, nomMetodo, MT_string); MH_metConRetSinParam = MethodHandles.filterReturnValue(MH_name, MH_metConRetSinParam); System.out.println("Retorno del mtodo " + MH_metConRetSinParam.invoke()); // Variamos el target name.setTarget(MethodHandles.constant(TestClass.class, new TestClass( "Aupa!"))); System.out.println("Retorno del mtodo " + MH_metConRetSinParam.invoke()); }
Listado 1.10 Prctica 4: ConstantCallSite
www.javahispano.org
15
Java 7: Soporte a lenguajes dinmicos Si ejecutamos el listado anterior, aparecer un error al tratar de variar el target:
www.javahispano.org
16
El ejemplo anterior solo difiere de los vistos hasta ahora en dos aspectos: Cuando se declara el MethodType primero se define el parmetro de retorno y a continuacin los tipos de datos que recibir como parmetro. Nueva instruccin insertArguments para dar valor a los parmetros de entrada. La salida de ejemplo anterior ser similar a la siguiente:
Otra opcin para invocar a este mtodo con menos lneas de cdigo, consiste en olvidarnos del invocador dinmico y pasarle los parmetros al mtodo desde el invokeExact(), tal y como podemos ver en el siguiente listado:
public void test5_2() throws Throwable { Lookup lookup = MethodHandles.lookup(); String nomMetodo = "metodoConRetornoYTresParametros"; MethodHandle cat = lookup.findVirtual(TestClass.class, nomMetodo, MethodType.methodType(String.class, int.class, short.class, String.class)); System.out.println("=>" + (String) cat .invokeExact(new TestClass(), 2, (short) 3, "Iep")); }
Listado 1.12 Prctica 5: Paso de parmetros con invokeExact
www.javahispano.org
17
public void test6() throws Throwable { // Mtodo concat - MethodType String,String MethodHandle cat = MethodHandles.lookup().findVirtual(String.class, "concat", MethodType.methodType(String.class, String.class)); // Mtodo toUpper - MethodType String MethodHandle toUpper = MethodHandles.lookup().findVirtual(String.class, "toUpperCase", MethodType.methodType(String.class)); // Concatenamos y luego convertimos MethodHandle f0 = MethodHandles.filterReturnValue(cat, toUpper); System.out.println((String) f0.invokeExact("hola ", "mundo")); }
Listado 1.13 Prctica 6
En el listado anterior es importante fijarse en la definicin de los parmetros de los mtodos (MethodType), que se corresponden segn el API:
String
concat(String str)
Concatenates the specified string to the end of this string.
MethodType.methodType(String.class, String.class)
www.javahispano.org
18
MethodType.methodType(String.class) Si ejecutamos el listado 1.13 obtendremos los String pasados como parmetro al mtodo invokeExact(), concatenados y capitalizados:
public void test7() throws Throwable { MutableCallSite name_constructor = null; name_constructor = new MutableCallSite( MethodType.methodType(TestClass.class)); MethodType MT_parametros = MethodType.methodType(void.class); Lookup lookup = MethodHandles.lookup(); MethodHandle MH_contructor = lookup.findConstructor(TestClass.class, MT_parametros); MH_contructor.invoke(); }
Listado 1.14 Prctica 7: Invocar a constructores
www.javahispano.org
19
Java 7: Soporte a lenguajes dinmicos El listado anterior difiere del resto de los ejemplos hasta ahora presentados, en el mtodo findConstructor. Si ejecutamos el listado anterior, obtendremos una salida similar a la siguiente:
public void test8() throws Throwable { MutableCallSite name = new MutableCallSite( MethodType.methodType(TestClass.class)); name.setTarget(MethodHandles.constant(TestClass.class, new TestClass())); // invocador dinmico MethodHandle MH_name = name.dynamicInvoker(); MethodHandle MH_fieldSet = MethodHandles.lookup().findSetter( TestClass.class, "strCampoPublico", String.class); MH_fieldSet = MethodHandles.filterReturnValue(MH_name, MH_fieldSet); // Asignamos valor al campo MH_fieldSet.invokeExact("Ke pasa!"); // Recogemos el valor del campo MethodHandle MH_field = MethodHandles.lookup().findGetter( TestClass.class, "strCampoPublico", String.class); MH_field = MethodHandles.filterReturnValue(MH_name, MH_field); System.out.println("El valor del campo " + (String) MH_field.invokeExact()); }
Listado 1.15 Prctica 8: Acceder a los campos de la clase
Como se puede observar en el listado anterior utilizamos los mtodos findGetter y findSetter para hacer Get y Set del campo de la clase. Si ejecutamos el listado anterior tendremos el siguiente resultado: www.javahispano.org
20
public void test9() throws Throwable { Lookup lookup = MethodHandles.lookup(); String nomMetodo = "metodoEstaticoSinRetornoNiParams"; MethodType MT_void = MethodType.methodType(void.class); MethodHandle MH_metodoEstatico = lookup.findStatic(TestClass.class, nomMetodo, MT_void); MH_metodoEstatico.invokeExact(); }
Listado 1.16 Prctica 9: Mtodos estticos
En este caso al tratarse de un mtodo esttico nos olvidamos del CallSite, haciendo lookup directamente sobre la definicin de la clase.
www.javahispano.org
21
public void test10() throws Throwable { MutableCallSite name = new MutableCallSite( MethodType.methodType(TestClass.class)); name.setTarget(MethodHandles.constant(TestClass.class, new TestClass())); Lookup lookup = MethodHandles.lookup(); // invocador dinmico MethodHandle MH_name = name.dynamicInvoker(); MethodType MT_void = MethodType.methodType(void.class); MethodHandle MH_thread = lookup.findVirtual(TestClass.class, "metodoParaThread", MT_void); MH_thread = MethodHandles.filterReturnValue(MH_name, MH_thread); // Transformamos la instancia en una implementacin de Runnable Runnable runnable = MethodHandleProxies.asInterfaceInstance( Runnable.class, MH_thread); System.out.println("El thread del main " + Thread.currentThread().getId()); // Ejecutamos el thread Thread t = new Thread(runnable); System.out.println("El nuevo thread " + t.getId()); t.start(); System.out.println("FIN de test "); }
Listado 1.17 Prctica 10
Si se fija en el mtodo metodoParaThread definido en la clase TestClass (Listado 1.4), puede ver cmo hacemos un Thread.sleep() durante 10 segundos, para que a la hora de ejecutar podamos verificar que realmente estamos ejecutndolo sobre un nuevo hilo diferente al principal. Por lo tanto en la ejecucin del listado anterior, podemos ver en la consola la salida FIN de test antes de que se termine de ejecutar el mtodo metodoParaThread:
www.javahispano.org
22
5. Conclusiones
Como hemos visto a lo largo de este tutorial, en Java 7 disponemos de un nuevo API que puede sustituir en parte a los antiguos mecanismos de hacer Reflection. Este API nos proporciona utilidades para trabajar con los diferentes miembros de una clase teniendo en cuenta los modificadores de acceso. Adems nos regala una interesante utilidad para manipular interfaces. En este documento, tan solo hemos realizado algunas de las operaciones ms bsicas que nos brinda este API, pero puede ser un buen punto de partida para profundizar en ella y descubrir muchas de las otras caractersticas en las que no nos hemos detenido. Tal vez la mayor transcendencia de este nuevo API, se oculte en las nuevas instrucciones bytecode que genera, que indudablemente sern llevadas a su mximo exponente por la nueva generacin de lenguajes dinmicos ejecutados sobre la mquina virtual Java.
www.javahispano.org
23
6. Anexo: Referencias
Dynamic Programing Language: http://en.wikipedia.org/wiki/Dynamic_programming_language List of JVM languages: http://en.wikipedia.org/wiki/List_of_JVM_languages JSR-223: http://www.jcp.org/en/jsr/detail?id=223 JSR-292: http://jcp.org/en/jsr/detail?id=292 Oracle - Java Virtual Machine Support for Non-Java Languages: http://docs.oracle.com/javase/7/docs/technotes/guides/vm/multiple-languagesupport.html Oracle - Dynamic Language Support on the Java Virtual Machine: http://www.oracle.com/technetwork/issue-archive/2010/10-may/o30java-099612.html The Da Vinci Machine Project: http://openjdk.java.net/projects/mlvm/ A rough guide to JVM languages: http://radar.oreilly.com/2011/07/jvm-languages.html Book - Whats New in Java 7: http://my.safaribooksonline.com/book/-/9781449318581 Book - The Well-Grounded Java Developer: http://www.manning.com/evans/
www.javahispano.org
24