This Guide is a tutorial of ZRO. We will tell you almost all contents of ZRO. With this guide,you will be familiar with ZRO and can start programming with ZRO.
ZRO is a set of api for developing distributed systems.
The architecture is simple. ZRO can also be names "Remote Reflection API".Information about Reflection API can be found is JDK's documentation. The reflection API represents, or reflects, the classes, interfaces, and objects in the current Java Virtual Machine. With the reflection API you can:
The server-side object is called Remote Object in ZRO.
The api is client-server mode. The is a server that open a ServerSocket to allow clients to connect. The client connect to server and send request and then fetch response.
I'm sure that you know the reference concept in Java. A reference can be seen as a pointer that points to a object in the jvm.Then I can tell you that a Remote Object in one jvm is a reference or pointer that points to a server-side object in a different jvm. You can invoke methos on this remote object and get or set the field of the remote object just as the object is local.
This guard is by examples mainly.
ZRO is so-called zero server-side programing. So the program runs in the serverside is very simple.
package com.zms.zro.test; import com.zms.zro.ZROServer; public class OneServer { public static void main(String[] args) throws Exception { ZROServer server=new ZROServer(1234); System.in.read(); server.close(); } }
This program almost can handle all client side programs.
This program has a main method.First it create a ZROServer instance. The constructor parameter is a int that tells on which port to open a ServerSocket.The lines else means a enter on the console will end the program.
Below is the classical Hello world program:
package com.zms.zro.test;
public class ClassicHelloWorld { public static void main(String[] args) { System.out.println("Hello world!"); } }
package com.zms.zro.test;System is a class. The System class has a static field "out" with the type PrintStream.We get the static field and invoke the println method on the object. Than the ZRO client program is just the same:
import java.io.PrintStream;
public class ClassicHelloWorld { public static void main(String[] args) { PrintStream out=System.out; out.println("Hello world!"); } }
package com.zms.zro.test;
import com.zms.zro.RemoteObject; import com.zms.zro.ZROClient;
public class ZROHelloWorld { public static void main(String[] args) throws Exception { ZROClient client=ZROClient.fetchClient("localhost",1234,false); RemoteObject out=(RemoteObject)client.getField(null,System.class.getField("out")); out.invoke("println","Hello ZRO world!"); } }
Note: First you need a ZROClient!
In the client,you must first have a ZROClient.The ZROClient communicate with the server. The ZROClient use the Multiton design pattern.The Constructor is private. You can only get/create a ZROClient through the method ZROClient.fetchClient(String host,int port,boolean sharable). The String host is the server host.The int port is the server port.
Note: sharable and non sharable
The third parameter boolean sharable stands for if the client
is sharable. Because actions on one ZROClient is blocked.So in muti-thread
programs,if different thread own the same ZROClient,the efficiency is low.
If you don't want to share a ZROClient with other threads,you specify the
parameter false.
The same ZROClient is returned If sharable and host and
port are the same:
ZROClient one=ZROClient.fetchClient("localhost",1234,true); ZROClient two=ZROClient.fetchClient("localhost",1234,true); //one==two
ZROClient one=ZROClient.fetchClient("localhost",1234,true); ZROClient two=ZROClient.fetchClient("localhost",5678,true); //one!=two
ZROClient one=ZROClient.fetchClient("localhost",1234,false); ZROClient two=ZROClient.fetchClient("localhost",1234,true); //one!=two
ZROClient one=ZROClient.fetchClient("localhost",1234,true); ZROClient two=ZROClient.fetchClient("localhost",1234,false); //one!=two
The program first get the Remote Object points to the System.out in server's jvm.
Note: get a static field
ZROClient.getField(null,Field)
Becuase the field is static,so the first parameter is null. The
second parameter is of the type java.lang.reflect.Field.
Note: why the return type is Object other than RemoteObject
In many methods,the return type is Object other than RemoteObject:
java.lang.Object ZROClient.getField
java.lang.Object ZROClient.getField.invoke
Some Object are transported through the network directly.They
are:
primitive type: int long double float short
byte char boolean
primitive wrap type: Integer Long Double Float
Short Byte Character Boolean
special: String
If the return type is common Object such as java.util.Vector,then a RemoteObject is returned.If the return type is the types listed,the real object is returned.
//to get the java.lang.File.pathSeparator RemoteObject pathSeparator=(RemoteObject)client.getField(null,java.io.File.class.getField("pathSeparator")); //this line will throw a ClassCastException,Because the static field pathSeparator of File is of type String //so the String is returned ,not the RemoteObject String pathSeparator=(String)client.getField(null,java.io.File.class.getField("pathSeparator")); //correct
How to determin which type to cast
This depends the declare type. If the declare
type is the immutable types listed beyond,then the real object is returned. Otherwise
the return type is RemoteObject
Note: How to invoke method
If the method is static,then ZROClient.invoke(null,Method,args)
client.invoke(null,System.class.getMethod("exit",new Class[]{int.class}),0); //System.exit(0) will cause the server process exitIf the method is not static,the RemoteObject.invoke
In this example ,we will create a JFrame that runs on server.
package com.zms.zro.test;
import javax.swing.JFrame; import javax.swing.WindowConstants; import com.zms.zro.RemoteObject; import com.zms.zro.ZROClient;
public class JFrameTest { public static void main(String[] args) throws Exception { ZROClient client=ZROClient.fetchClient("localhost",1234,false); //JFrame frame=new JFrame("A Frame"); RemoteObject frame=(RemoteObject)client.newInstance(JFrame.class,"A Frame"); //frame.setBounds(100,100,200,200); frame.invoke("setBounds",100,100,200,200); //frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); frame.invoke("setDefaultCloseOperation",WindowConstants.DISPOSE_ON_CLOSE); //frame.setVisible(true); frame.invoke("setVisible",true); } }
Note: How to new Object in remote JVM
ZROClient.newInstance(Constructor,args)
ZROClient.newInstance(Class,args)
A frame with a button:
package com.zms.zro.test;
import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.WindowConstants; import com.zms.zro.RemoteObject; import com.zms.zro.ZROClient;
public class JFrameTestA { public static void main(String[] args) throws Exception { ZROClient client=ZROClient.fetchClient("localhost",1234,false); //JFrame frame=new JFrame("A Frame"); RemoteObject frame=(RemoteObject)client.newInstance(JFrame.class,"A Frame"); //frame.setBounds(100,100,200,200); frame.invoke("setBounds",100,100,200,200); //frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); frame.invoke("setDefaultCloseOperation",WindowConstants.DISPOSE_ON_CLOSE); //Container container=frame.getContentPane(); RemoteObject container=(RemoteObject)frame.invoke("getContentPane"); //container.setLayout(null); container.invoke("setLayout",new Object[]{null}); //JButton button=new JButton("Kick me"); RemoteObject button=(RemoteObject)client.newInstance(JButton.class,"Kick me"); //container.add(button); container.invoke("add",button); //button.setBounds(50,50,80,30); button.invoke("setBounds",50,50,80,30); //frame.setVisible(true); frame.invoke("setVisible",true); } }
ZROClient.newArray(Class,int)
ZROClient.newArray(Class,int[])
RemoteObject.arrayLength()
RemoteObject.arrayGet(int)
RemoteObject.arraySet(int,Object)
Here we will create some arrays on server:
package com.zms.zro.test;Another:
import com.zms.zro.RemoteObject; import com.zms.zro.ZROClient;
public class ArrayTest { public static void main(String[] args) { ZROClient client=ZROClient.fetchClient("majl",1234,false); //int[] ints=new int[10240]; RemoteObject ints=(RemoteObject)client.newArray(int.class,10240); for(int i=0;i<100;i++) { //ints[i]=i*i; ints.arraySet(i,i*i); } System.out.println(ints.arrayLength()); System.out.println(ints.arrayGet(50)); } }
package com.zms.zro.test;
import java.util.Date; import com.zms.zro.RemoteObject; import com.zms.zro.ZROClient;
public class ArrayTest { public static void main(String[] args) { ZROClient client=ZROClient.fetchClient("majl",1234,false); //Date[] dates=new Date[10]; RemoteObject dates=(RemoteObject)client.newArray(Date.class,10); for(int i=0;i<dates.arrayLength();i++) { //dates[i]=new Date(); dates.arraySet(i,client.newInstance(Date.class)); } RemoteObject one=(RemoteObject)dates.arrayGet(5); //getTime System.out.println(one.invoke("getTime")); } }
To avoid baleful clients from connecting. You can set a usename and a password to the ZROServer.When the clients connected,it must first provide the username and the password.
The Server Side:
ZROServer server=new ZROServer(1234,"user","pass");
The Client Side:
ZROClient client=ZROClient.fetchClient("host",1234,true); if(client.needAuth()) { client.doAuth("user","pass"); }