Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lesson 4 Advanced RMI JNI. Some Misc real-world issues.

Similar presentations


Presentation on theme: "Lesson 4 Advanced RMI JNI. Some Misc real-world issues."— Presentation transcript:

1 Lesson 4 Advanced RMI JNI

2 Some Misc real-world issues

3 Posting many objects  What if many people logon to play tic-tac- toe? How do we give each pair their own game?  What if we have many objects in general to post?  There are two ways to deal with this –give each their own name in registry (not good) –bootstrap off a singe factory method (good)

4 Bootstrapping  For tic-tac-toe example, we could have a method: TicTacToeImpl getGame() throws RemoteException;  As long as both getGame and TicTacToeImpl are setup up as remote, only one remote object need get posted to the registry.  Can create a pool of tic-tac-toe games and assign as they come in.  Will be required for hw2, recommended for hw1.  This is a great simplification vs. binding multiple objects!

5 Contacting rmi registry  In our simplified application, to get a remote reference we called: Naming.lookup(“tic-tac-toe”);  This assumes the default rmi port (1099) on localhost.  To change ports, run rmiregistery  The more general rmi URL is Naming.lookup(“rmi://host:port/name”); e.g. Naming.lookup(“rmi://yourserver.com:99/tic-tac-toe”);

6 Listing objects in the registery  Note that the Naming class has a method list which returns a listing of all objects bound to the registry.  It is called from the client as: –String[] bindings = Naming.list(“<rmi url goes here”);

7 Security issues  Recall that client needs auto-generated up-to-date stub functions.  If these are available locally on the client, there is no security issue.  However, keeping a local installation can be cumbersome. Often stubs are downloaded via other servers (we’ll see how to do this).  In this case, a SecurityManager needs to be installed to ensure that the stubs are not hostile (unless applet is used, which has its own SecurityManager).

8 RMISecurityManager  Easiest way to do this is to use java.rmi.RMISecurityManager as: System.setSecurityManager(new RMISecurityManager());  This by default restricts all code from making socket connections.  Obviously this is too strict. Need a policy file to allow client to make network connection to rmi port. It would look something like: grant{ permission java.net.SocketPermission “*:1024-65535”, “connect”} java Client –Djava.security.policy=client.policy

9 Server-side security/firewalls  For this class we assume you have control over the server security configuration.

10 Deployment

11 RMI application deployment  Very simple if client/server both have up- to-date copies of all class files  However, this is unrealistic and impractical.  Better if client can load dynamically load classes remotely.  RMI provides such a mechanism built on top of standard servers.

12 Deployment, cont.  For server, following classes must be available to its classloader: –Remote service interface definitions –Remote service implementations –Stubs –All other server classes  For client –Remote service interface definitions –Stubs –Server classes for objects used by the client (e.g. return values) –All other client classes

13 RMIClassLoader  RMI support remote class loading by specfying the java.rmi.server.codebase property with an apprpriate URL  This is done as: java WhateverImp -Djava.rmi.server.codebase=http://whateverhttp://whatever ftp, file, etc. can also be used  Proper remote deployment will be required on the next assignment.

14 Remote Objects and Collections

15 Using Remote Objects in Sets  Recall that equals() and hashcode must be overridden to use Sets.  For remote objects, this would require a network call to the server, which could fail.  Since equals does not throw RemoteException, it cannot be overridden and used remotely.  Thus, must use equals and hashCode methods in RemoteObject class.  These unfortunately only compare stubs, not contents.  Probably not a great idea to do this unless necessary

16 clone() method  Can not call at all directly for stubs  If you want to clone, simply define a new remote method (e.g. remoteClone), have it call clone locally, and return copy as parameter.

17 Remote Objects and Inheritance

18 Synchronized RMI calls

19 Using synchronized methods in rmi  Recall that remote objects are passed by reference (stub).  Thus, when many users request the same object, they are manipulating a single copy.  If the object is immutable, there is no need to synchronize.  Otherwise, proper synchronization should be done in the regular way – using synchronized methods where appropriate, and synchronized blocks if necessary.

20 RMI calling semantics

21 Native Data Types  Native data types –pass by value – parameter copied before remote transmission –exactly like single jvm behavior –machine-independent format used

22 Objects  Calling sequence for object parameters –pass by value also! –this differs from single-jvm behavior –All objects are completely serialized (deep copy) and sent to remote location. –This can be hugely inefficient. Be very careful when performance is at a premium!

23 Remote Objects  Java defines a third type of parameter – a remote object.  Remote objects must be setup as rmi distributed objects in the regular way (extend UnicastRemoteObject and implement Remote interface)  Remote objects are pass-by-reference. proxies rather than serialized objects are returned.

24 Distributed Garbage Collection

25 Distributed garbage collection  Server keeps track of clients that have requested object.  When client disconnects, they are removed from the list.  Also a timeout mechanism controld by java.rmi.dgc.leaveValue.  Remote object can implement java.rmi.server.Unfererenced to get notification when clients no longer hold live reference.  Bottom line: not much to worry about here.

26 Client-side callbacks

27 RMI callbacks  Frequently, a server will need to inform a client asynchronously when an event occurs. e.g. –a player moved in a board game –a certain amount of time passed (ticker)  In such a case, the client has to behave like an rmi server.  There is nothing special about such situations. The client can export a remote object and make it available for the server to use for callback.  See class TimeMonitor example

28 Activation

29 Creating objects remotely  What we have learned about RMI requires the server to instantiate one or more objects and post them to the registry  What if objects do not exists. Is it possible for the client to remotely create an object on the server?  This can be useful occasionally and is now possible with java Activation framework.  We will not discuss Activation in this class.

30 RMI inter-language calls indirectly using JNI

31 JNI  Recall that CORBA allows inter-language remote object calls; RMI does not!  However, JNI allows one to call “native code” directly from java.  Thus, the two together give more CORBA- like capabilities. –rmi calls java remote method, which locally calls C code, which returns java parameter(s), and rmi sends back to client.

32 What exactly does JNI do?  Provides the glue between java – C/C++ (but no other languages)  Provides the machinery for mapping datatypes.  Can be used to call C/C++ from Java (typical), or Java from C (invocation API)  Does NOT provide network transparency!

33 Reasons for using JNI  Feature not available in java language.  Code already written in another language, don’t want to rewrite.  Java is slow.  Other language has no additional features per se, but has much better syntax for handling certain operations (Fortran for math).

34 Problems with JNI  Only provides C/C++ bindings. Going to Fortran, COBOL, Ada, etc. requires extra step.  Not portable  Mapping is not trivial  No built-in security

35 Basic steps to calling native code 1. Write java class with a method declared with native keyword. Provide no implementation –public native void sayHello(); –Example above is most simple, but method may pass any parameters or have any return type. 2. Add a call to System.loadLibrary(“libname”) in the class that declares the native method: –static{ System.loadLibrary(“hello”);}//static means called only once.

36 Steps, cont. 3. Compile the class –javac Hello.java 4. Produce the C/C++ header files using the javah utility: –javah Hello –This produces the header file Hello.h 5. Write your implementation file by first copying the function signature produced in the include file. Also, #include the header file. #include “Hello.h”

37 Steps, cont. 6. Write the implementation in C/C++. This will require using JNI methods to access the data or possibly casts to convert to basic C/C++ types 7. Best technique: Break into two steps. Think of your C/C++ function as a wrapper which accesses the Java data and maps it to C data using JNI methods, then shoves the converted data into a prewritten standalone C program.

38 Steps, cont. 8. Compile your native method(s) as a shared object (or DLL on Windows). –WARNING: Be sure to point your linker to the include files in /jdk1.3/include and jdk1.3/include/linux (for example). –WARNING: Mixing languages is much easier using a straight C wrapper rather than C++. 9. Set the environment variable LD_LIBRARY_PATH to the shared object directory  Run main Java class.

39 Mapping of datatypes  C datatypes are platform-dependent. Those in java aren’t.  Thus, JNI defines its own portable C datatypes.  See next slide for mapping of native types.

40 Native java/c data mappings JavaCBytes booleanjboolean1 bytejbyte1 charjchar2 shortjshort2 intjint4 longjlong8 floatjfloat4 doublejdouble8

41 String mappings  Java and C strings are very different (Unicode vs. 8-bit null terminated).  Thus, JNI cannot simply pass memory from java to C.  Some mapping must occur.  This is handled via C utility functions provided with JNI.  jstring is opaque type, and methods operate directly on/create jstring types.

42 What does Java pass to my C function?  How are these utility functions provided?  JNIEnv* : A pointer to the the JNI environment. This pointer is a handle to the current thread in the JVM, and contains mapping functions and other housekeeping information.  jobject : A reference to the object that called the native code (this) for non-static methods –or jclass: A descriptor of the class which contains the method for static methods  Any arguments specified by the method.

43 String functions  The string functions look like this: –jstring NewStringUTF(JNIEnv*, const char[]); –jsize GetStringUTFLength(JNIEnv*, jstring); –void REleaseStringUTFChars(JNIEnv*, jstring, const jbyte[]); –void ReleaseStringChars(JNIEnv*, jstring, const jchar[]); etc.

44 Object fields  What if we want to go beyond number and string parameters?  It is cumbersome but but not conceptually difficult to call methods that manipulate object state.  The designers of JNI made it difficult in order not to hide the inner layout of java data structures.  Thus, many method calls are required, outlined on the next page.

45 Test case – Employee class  Imagine the following simple Employee class: public class Employee{ public void raiseSalary(double percent){ this.salary *= 1 + percent / 100; } private double salary; }  We want to write this as a native method

46 Making raiseSalary native  To make raiseSalary native, we hit the signature with javah and get the following: JNIEXPORT void JNICALL Java_Employee_raiseSalary (JNIEnv*, jobject, jdouble);  Note that second argument is of type jobject since method is non-static. It is like this.  We need to access, change, and set the salary field of the implicit parameter.  This is a several step process.

47 How to access the fields of implicit parameter  General syntax is: x = (*env)->GetXxxField(env, class, fieldID);  To get the object class, do: jclass class_Employee = (*env)->GetObjectClass(env, obj_this);  To get the fieldID, do: jfieldID id_salary = (*env)->GetFieldID(env,class_Employee, “salary”, “D”); (string D denotes the type – double)  Finally, call SetXxxField to affect change.

48 Source code for example JNIEXPORT void JNICALL Java_Employee_raiseSalary( JNIEnv* env, jobject obj_this, jdouble byPercent){ jclass class_Employee = (*env)->GetObjectClass(env, obj_this); jfieldID id_salary = (*env)->GetFieldID(env, class_Employee, “salary”, “D”); jdouble salary = (*env)->GetDoubleField(env, obj_this, id_salary); salary *= 1 + byPercent / 100; (*env)->SetDoubleField(env, obj_this, id_salary, salary); }

49 Accessing static fields  Similar to object fields, but must get class using a different method, e.g.: jclass class_System = (*env)->FindClass(env, “java/lang/System”);  To get the fieldID jfieldID id_out = (*env)->GetStaticFieldID(env, class_System, “out”, “Ljava/io/PrintStream;”  To get static object field jobject obj_out = (*env)->GetStaticObjectField(env, class_System, id_out);

50 Calling java methods  This is possible and quite straightforward as well.  Simple use (*env)->CallXxxMethod(env, implicit parameter, methodID, explicit parameters).  Xxx can be Void, Int, Object, etc. depending on return type of method.  MethodID is like fieldID – use GetMethodID function to access.  Note that GetMethodID requires class name, method name, AND signature. How to specify signature is detailed in Horstmann ch 11.

51 Encoding scheme for method signatures in JNI Bbyte Cchar Ddouble Ffloat Iint Jlong Lclassname;a class type Sshort Vvoid Zboolean

52 More on signatures  Example: –Employee(java.lang.String; double; java.util.Date) has signature encoding: “(Ljava/lang/String;DLjava/util/Date;)V”  Note that String is wrapped in parentheses, there is no separator between types (other than ‘;’ for class types), and return type is appended).  What does (II)I describe?  What does (Ljava/lang/String;)V describe?  Note: Arrays of any type simply begin with ‘[‘  What does ([I[I)I describe?

53 javap tool  Java contains a tool called javap that can be run on a class file to produce the field signatures. e.g. javap –s –private Classname  This is fun and useful to play with to learn/save time.

54 Static Methods  Calling static methods is similar to object methods.  There are two differences: –Use GetStaticMethodID and CallStaticXxxMethod –Supply class object rather than implicit parameter object.

55 Arrays  Arrays in java are mapped as opaque C types: Here are a few; others obvious Java typeC type boolean[]jbooleanArray int[]jintArray double[]jdoubleArray Object[]jobjectArray

56 Some Array methods jsize GetArrayLength(JNIEnv, jarray) jobject GetObjectArrayElement(JNIEnv, jobjectArray, jsize); void SetObjectArrayElement(JNIEnv, jobjectArray, jsize, jobject) Xxx* GetXxxArrayElements(JNIEnv, jarray, jboolean* isCopy); void ReleaseXxxArrayElements(JNIEnv, jarray, Xxx elems[], jint mode) etc.

57 Examples on union  HelloWorld Example: No data passed –Hello.javaHello.java –Hello.ccHello.cc  Max example : Only native dataypes –Utils.javaUtils.java –utils.ccutils.cc  Advanced Max example: Arrays –Utils.javaUtils.java –utils.ccutils.cc  Max Java-C-Fortran: max.fmax.f

58 A simple alternative – spawning a system executable  Advantages –Infinitely simpler –Portable –Can use any native language  Disadvantages –Can only pass data to and from vi stdout –Must reload executable for each invocation

59 Spawning Executable -- technique  Process p = Runtime.exec(“some_exec”);  Use p to manage process: –p.getInputStream(); –p.getOutputStream(); –p.kill(); –p.halt();

60 Other topics/coming attractions  Invocation API (C calls java directly).  Calling constructors from native code  throwing java exceptions


Download ppt "Lesson 4 Advanced RMI JNI. Some Misc real-world issues."

Similar presentations


Ads by Google