Title: JNIEasy
1JNIEasy
- Aspect Oriented Programming a la ayuda de Java
como ciudadano de primera clase en el desktop
Jose María Arranz Santamaría jmarranz_at_eresmas.com
jmarranz_at_dii.etsii.upm.es javaHispano nickname
jmarranz
2Índice
- El dominio de Windows en el desktop
- WORA realidad o utopía ?
- JNI amigo o enemigo ?
- AOP y Bytecode Enhancement
- JNIEasy, hacia una solución Java sin JNI
- Hacia un desktop muy Java?
3El dominio de Windows en el desktop
4Plataformas relevantes en desarrollo software
- Los tres tenores
- Java (J2SE y J2EE)
- .Net
- LAMP (LinuxApacheMySQLPerl/PHP)
- Y C/C para KDE/Qt, GNOME/GTK?
- Sí... pero en el coro
- Y la plataforma Mozilla (XUL,XBL...)?
- Uff...
5Web Java
- Java tiene especial relevancia en el lado del
servidor - Muy portable
- Importante peso de Unixes/Linux
- JDBC mucho más portable que ODBC/OleDB
- Web agnóstico en el servidor
- HTML generado consumido por MSIE casi siempre
(aprox. 90 navegadores)
6Web Java
- Familiaridad de Java con Internet
- Sockets, HTTP, RMI, EJBs, WebServices, CORBA,
applets ... - Frameworks, frameworks, frameworks...
- De Web JSP, JSF,Struts,Tapestry, Cocoon ...
- De Bases de Datos EJB, JDO, Hibernate ...
- Más profesional, más seguro, más escalable que
PHP o ASP
7Desktop ? Java
- 90 ordenadores con Windows (IDC)
- Gran mayoría de aplicaciones desktop
desarrolladas con Visual Basic/C - Acceso al hardware vía componentes estándar de
Windows - Presentando una API C (Win32) o COM
- Drivers propietarios en C
- JDIC, JMF... insuficiente
8WORA realidad o utopía ?
- WORA Write Once Run Anywhere
9WORA realidad en el servidor
- Las aplicaciones Java de gestión de bases de
datos por Web son muy portables - Los negocios de hardware de Sun e IBM sobreviven,
en gran medida, gracias a Java y al WORA
10WORA utopía en el desktop
- Java no cubre todo Windows
- Y quizás no deba ...
- Windows está en permanente evolución
- Nuevas APIs, componentes ...
- Drivers propietarios ... en C
ifndef TWAIN define TWAIN / SDH - 02/08/95 -
TWUNK / / Force 32-bit twain to use same
packing of twain structures as existing /
11Soluciones
- Cambiarse de bando
- .Net Windows
12Soluciones
- Permanecer...
- Alguien lo hizo antes?
- Esperar al WORA
- Tú mismo JNI
13JNI amigo o enemigo ?
- JNI Java Native Interface
14I JNI
- JNI Programar Java en C/C
- Relativamente complejo e inseguro (idem C/C)
- Doble modelado Java C/C
- Lucha entre si Java o C/C
- Conversiones de datos entre mundos
15I JNI
- Ciertos casos Imprescindible
- SourceForge general
- SourceForge Multimedia/Vídeo
16Aspect Oriented Programming y Bytecode Enhancement
17Bytecode Enhancement
- Modificación/introducción de código via bytecode
en un .class ya existente - Nuevo .class
- Como JDO consigue la persistencia transparente
18AOP
- Solución elegante de los crosscuting concerns
- A través de la introducción horizontal de
aspectos - nuevos atributos y métodos (advices),
- que son llamados en determinados puntos
(pointcuts) del código original, - de entre los posibles (joinpoints)
19Bytecode Enhancement / AOP
- B.E. es AOP ?
- No es un instrumento
- Sí el uso de dicho instrumento es AOP
- AspectJ y AspectWerkz se basan en B.E.
- B.E. AOP en el sentido más primitivo
- Y más flexible
- Y más controlable
20JNIEasy, hacia una solución Java sin JNI
21Qué es JNIEasy?
- Es un sustituto de JNI
- Es un nuevo Java Native Interface en Java!
- Evita la programación en C/C en el acceso a
métodos y estructuras de datos programados en
DLLs - Componentes del S.O.
- Drivers del hardware
- Librerías de todo tipo...
22No se había hecho algo así antes?
- SI, pero las soluciones clásicas han sido
- fuertemente intrusivas
- limitadas
- muy poco Java friendly
- Fuerzan la adaptación de Java al mundo nativo
- Resultado código Java poco Java
23Ejemplos producto clásico
- Instanciación de datos
- // C int value
- Int value new Int()
- // C int pValue value
- Pointer pValue new Pointer(value)
- Se identifica un objeto Java por cada dato nativo
en memoria, incluso datos primitivos
JNIWrapper http//www.jniwrapper.com
24Ejemplos producto clásico
- Llamada a funciones
- // C int sprintf(const char,)
- Function sprintf new Library("msvcrt")
- .getFunction("sprintf")
- AnsiString result new AnsiString()
- sprintf.invoke(null,result,
- new AnsiString("Hello, s!"),
- new AnsiString("World"))
- System.out.println(result.getValue())
- //Output Hello, World!
- Es necesario envolver las cadenas en una clase
específica (AnsiString)
25Ejemplos producto clásico
- Definición de estructuras
- // C struct TestStruct short a int b
- private static class TestStruct
- extends Structure
- public Int16 a new Int16()
- public Int32 b new Int32()
- public TestStruct()
- init(new Parameter _int16,_int32)
-
- Derivación intrusiva de Structure
- Atributos primitivos como objetos
26Ejemplos producto clásico
- Declaración de callbacks
- / C callback int callback(int) /
- private static class IncIntCallback
- extends Callback
- private Int _arg new Int()
- private Int _result new Int()
- public IncIntCallback()
- init(new Parameter _arg,_result)
- public void callback()
- _result.setValue(_arg.getValue()1)
-
- Intrusividad y artificialidad máximas
27Conclusiones
- Java que no parece Java
- Ni siquiera parece C
- Escasa simetría
- Código difícil de entender y programar
- Uso sistemático de clases del framework incluso
para datos primitivos
28Enfoque de JNIEasy
- Corresponder el modelo de datos y de trabajo
normal de Java con el modelo nativo - Conseguir la máxima
- Transparencia
- Naturalidad (a lo Java)
- Con la mínima intrusividad
- C const char s "texto"
- JNIEasy String s new String("Texto")
- Aceptable rendimiento
29Herramientas usadas
- Java of course
- AOP/Bytecode enhancement
- JNI en C y C
- Ensamblador embebido en C y C
- Generación dinámica de código máquina
30Bytecode Enhancement y JNIEasy
- Absolutamente necesario
- En JNIEasy NO es capricho ni una moda
- Inspiración JDO
- Objetivo transparencia
- Y AspectJ y AspectWerkz?
- AspectJ demasiado rígido (estático)
- AspectWerkz quizás ...
31Bytecode Enhancement y JNIEasy
- Conversión de una clase Java en una estructura C
Bytecode enhancement
Clase Java Estructura Nativa
Pointer (bridge)
Buffer (memoria nativa)
pointcuts
Aspecto
32Llamadas a Funciones
- Función API C Win32 (User32.DLL)
- HWND FindWindow(
- LPCTSTR lpClassName, // class name
- LPCTSTR lpWindowName ) //window name
- Preliminares en JNIEasy
- JNIEasy.getInstance().load()
- DynamicLibrary user32DLL
JNIEasy.getInstance().getDLLManager().get("User32.
dll")
33Llamadas a Funciones
- Obtención de handler y llamada
- CMethod method
- user32DLL.addCMethod("FindWindowA",
- int.class, // tipo de retorno
- new Class
- String.class, // nombre clase
- String.class , // nombre ventana
- CallConv.STD_CALL )
- // method representa al método C en la DLL
- int hwnd method.callInt(new Object
- null,"DDE Server Window" )
34Llamadas a Funciones
- Llamada alternativa
- Integer hwndObj
- (Integer)method.call(
- new Object
- null,"DDE Server Window" )
- call es agnóstico en el tipo de retorno (Object)
- Recordar que se declaró como tipo de retorno
int.class
35Llamadas a Funciones
- Mejor empaquetado en una clase
- public class User32
- public static DynamicLibrary dll
JNIEasy.getInstance() - .getDLLManager().get("User32.dll")
- public static GenericMethod methodList
- new GenericMethod
- static
- methodList0 dll.addCMethod("FindWindowA",.
.. ) ... - public static int findWindow(
- String className,String windowName)
- CMethod method (CMethod)methodList0
- return method.callInt(new Object
- className,windowName )
- . . .
36Llamadas a Funciones
- Mejor aún si lo genera JNIEasy
- ltmethod returnType"int" name"findWindow"
- nativeName"FindWindowA" type"C"
- conv"STD_CALL" gt
- ltparam type"String" name"className" /gt
- ltparam type"String" name"windowName" /gt
- lt/methodgt
37Polimorfismo en Funciones
- El lenguaje C admite un cierto polimorfismo
- FindWindow puede llamarse como si fuera
- HWND FindWindow(int lpClassName,
- int lpWindowName)
- En JNIEasy también signatura tipo Java/C
- CMethod method user32DLL.addCMethod(
- "FindWindowA",int.class,
- new Class
- int.class, // class name
- int.class , // window name
- CallConv.STD_CALL )
38Polimorfismo en Funciones
- Búsqueda de métodos por nombre
- List methods user32DLL.findMethods("FindWindow
A") - // lista de 2 métodos
- Búsqueda de método por signatura
- CMethodSignature sig SignatureUtil.newCMethodSig
nature(int.class, - new ClassString.class,String.class)
- method user32DLL.findCMethod(
- "FindWindowA",sig)
39Unicode
- Ha venido para quedarse
- C/C
- Tipo wchar_t de 16 bits
- L"mi cadena" cadena Unicode
- Win32 C
- funciones Unicode xxxW (xxxAANSI)
- Java desde el principio
40Unicode
- JNIEasy por defecto ANSI, pero
- CMethod method jniEasyDLL.addCMethod(
- "FindWindowW",int.class,
- new Class
- StringUnicode.class,
- StringUnicode.class ,
- CallConv.STD_CALL)
- int hwnd method.callInt(new Object
- null,"DDE Server Window")
41Callbacks
- Sea EnumWindows de la API Win32 C
- BOOL EnumWindows(
- WNDENUMPROC lpEnumFunc, / callback /
- LPARAM lParam) / app-defined value /
- Se define a su vez WNDENUMPROC como
- BOOL CALLBACK EnumWindowsProc(
- HWND hwnd, // handle to parent window
- LPARAM lParam ) // app-defined value
42Callbacks
- Definición de la callback con JNIEasy
- public class EnumWindowsProc extends
CCallbackImpl - private static final CMethodSignature
- SIGNATURE SignatureUtil.newCMethodSignature(
- int.class,new Class
- int.class,int.class,CallConv.STD_CALL )
- public EnumWindowsProc()
- super(SIGNATURE)
- public Object onCall(Object params)
- int hwnd ((Integer)params0).intValue()
- int lParam ((Integer)params1).intValue()
- System.out.println("handle" hwnd "
param" lParam) - return new Integer(1)
-
43Callbacks
- Invocaríamos EnumWindows por ejemplo
- method user32DLL.addCMethod("EnumWindows",
int.class,new Class EnumWindowsProc.class,
int.class , CallConv.STD_CALL ) - method.callInt(new Object
- new EnumWindowsProc(),new Integer(10))
- Salida por pantalla
- handle65784 param10
- handle328538 param10 ...
44Callbacks
- Pero no iba a ser todo muy transparente?
- public class EnumWindowsProc2
- public static int showData(int hwnd,int lParam)
- System.out.println("handle" hwnd
- " param" lParam)
- return 1
-
- java.lang.reflect.Method reflMethod
- EnumWindowsProc2.class.getDeclaredMethod(
- "showData",new Classint.class,int.class
) - CCallback cb CallbackUtil.newCCallback(reflMetho
d) - method.callInt(new Objectcb,new Integer(10))
45Estructuras
- Sea la estructura Win32 C
- typedef struct tagPAINTSTRUCT
- HDC hdc // HDC int en Win32
- BOOL fErase // BOOL int en Win32
- RECT rcPaint
- BOOL fRestore
- BOOL fIncUpdate
- BYTE rgbReserved32
- PAINTSTRUCT, PPAINTSTRUCT
46Estructuras
- En Java con JNIEasy
- public class PaintStruct
- int hdc
- int fErase
- Rect rcPaint new Rect() // Es embebido
- int fRestore
- int fIncUpdate
- byte rgbReserved
- new byte32 // Es embebido
-
- En XML se indica que rcPaint y rgbReserved son
embebidos (no RECT o BYTE)
47Estructuras
- Ciclo de vida impuesto por el garbage collector
- PaintStruct ps new PaintStruct()
- Cuando se pierde el objeto se destruye su memoria
nativa asociada - El g.c. es el delete de JNIEasy
- No memory leaks
48Exportación de Funciones
- Podemos exportar un método Java
- tal que sea accesible desde código nativo
dinámicamente - a través del nombre, sin conocer la dirección
previamente - como si fuera un método exportado en una DLL
49Exportación de Funciones
- Sea el código Java
- public class CallbackTest
- public static long suma(int a,int b)
- return a b
- reflMethod
- CallbackTest.class.getDeclaredMethod(
- "suma",new Classint.class,int.class)
- JNIEasyLibrary dll
- JNIEasy.getInstance().getJNIEasyLib()
- dll.exportMethod(reflMethod,
- CallConv.STD_CALL)
50Exportación de Funciones
- Sea el código C
- HMODULE dllHandleLoadLibrary("JNIEasy.dll")
- void (__stdcall findCBAddress)(const char)
- findCBAddress (void (__stdcall )(
- const char))GetProcAddress(dllHandle,
- "_findExportedMethodAddress_at_4" )
- const char sig "CallbackTest.suma(int,int)"
- // signatura de la callback Java
- __int64 (__stdcall suma)(int,int)
- suma (__int64 (__stdcall )(int,int))
- findCBAddress(sig)
- __int64 res suma(1,2)
51C
- Acceso a métodos C exportados en DLLs
- Clases Java que emulan a clases C
- Métodos no estáticos de clases Java accesibles
desde código nativo por signatura - Etc.
52Hacia un desktop muy Java?
53Y ESO ES TODO!
- GRACIAS
- info www.jnieasy.com