 |
|
<<O>> Difference Topic
ProxyUsage
(12 - 01 Aug 2007 - Main.JohnCatherino)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005
| | | Using TCP port ####
Codebase server running: http://hostName:NNNN/
| |
< < | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically it will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this exact port number. It is possible to run the CodebaseServer? on a fixed port, by specifying it in its constructor, rather than using zero. The ItemServer? can also run on a fixed port, using the static Remote.config rel="nofollow" method. | > > | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically it will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this exact port number. It is possible to run the CodebaseServer? on a fixed port, by specifying it in its constructor, rather than using zero. The ItemServer? can also run on a fixed port, using the static Remote.config method. | | | (Note: The two port numbers #### and NNNN are not the same. Typically #### = NNNN + 1) |
|
<<O>> Difference Topic
ProxyUsage
(11 - 01 Aug 2007 - Main.JohnCatherino)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005
| | |
| |
< < | All that is required for this example, is the rel="nofollow" cajo project 40kB codebase cajo.jar, rel="nofollow" and the very small source file ProxyTest?, which will be explained completely below; | > > | All that is required for this example, is the cajo project 40kB codebase cajo.jar, and the very small source file ProxyTest?, which will be explained completely below; | | | Test.java:
|
|
<<O>> Difference Topic
ProxyUsage
(10 - 10 May 2007 - Main.edwardnorton)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005 | |
< < | | > > | | | | Using the cajo proxy mechanism |
|
<<O>> Difference Topic
ProxyUsage
(9 - 23 Nov 2006 - Main.cajo)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005 | | | private Proxy proxy = new Proxy();
public Component getProxy() { return proxy; }
public void pressed() { System.out.println("I heard that!"); } | |
< < | public static void main(String args[]) {
try { | > > | public static void main(String args[]) throws Exception { | | | new CodebaseServer?(null, 0);
Test t = new Test();
ItemServer?.bind(t, "main", t.proxy); | | | System.out.println(Remote.getServerPort());
System.out.print("Codebase server running: ");
System.out.println(System.getProperty("java.rmi.server.codebase")); | |
< < | } catch (Exception x) { x.printStackTrace(); } | | | }
} | | | Compiling the example:
The file above is compiled using the following command from the console: | |
< < | javac -classpath cajo.jar;. Test.java
| > > | javac -classpath cajo.jar Test.java
| | | Now the server can be run. To do this, use the following command:
java -classpath cajo.jar;. Test
This will result in the following console output: |
|
<<O>> Difference Topic
ProxyUsage
(8 - 22 Feb 2006 - Main.cajo)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005 | | | All that is required for this example, is the rel="nofollow" cajo project 40kB codebase cajo.jar, rel="nofollow" and the very small source file ProxyTest?, which will be explained completely below; | |
< < | ProxyTest.java: | > > | Test.java: | | |
import java.awt.*;
import java.awt.event.*;
| | | import gnu.cajo.utils.ItemServer;
import gnu.cajo.utils.CodebaseServer; | |
< < | public class ProxyTest? { | > > | public class Test { | | | | |
< < | public static class TestProxy? extends Panel implements ActionListener? { | > > | public static class Proxy extends Panel implements ActionListener? { | | | private Object selfRef, item; | |
< < | TestProxy?() { | > > | Proxy() { | | | super(new BorderLayout?());
Label label = new Label("Test Proxy", Label.CENTER);
add(label, BorderLayout.CENTER); | | | public Dimension getPreferredSize() { return new Dimension(300, 300); }
} | |
< < | private TestProxy? proxy = new TestProxy?(); | > > | private Proxy proxy = new Proxy(); | | | public Component getProxy() { return proxy; }
public void pressed() { System.out.println("I heard that!"); }
public static void main(String args[]) {
try {
new CodebaseServer?(null, 0); | |
< < | ProxyTest? pt = new ProxyTest?();
ItemServer?.bind(pt, "main", pt.proxy); | > > | Test t = new Test();
ItemServer?.bind(t, "main", t.proxy); | | | System.out.print("Server running on interface ");
System.out.println(Remote.getServerHost());
System.out.print("Using TCP port "); | | | }
} | |
< < | The ProxyTest? represents an item, meaning a remotely callable object furnished by a Virtual Machine. It has a proxy, called TestProxy?, which it provides to remote Virtual Machines. TestProxy? is a static member class simply to allow this example to consist of a single source file. Many times, proxies exist in separate files. Combining them this way makes their interaction a little clearer, as we will see. | > > | The Test represents an item, meaning a remotely callable object furnished by a Virtual Machine. It has a proxy, called Proxy, which it provides to remote Virtual Machines. Note: Test is a plain-old Java object. Proxy is a static member class simply to allow this example to consist of a single source file. Many times, proxies exist in separate files. Combining them this way makes their interaction a little clearer, as we will see. | | | | |
< < | TestProxy? is a graphical user interface, provided to remote Virtual Machines, it also interacts with its sending object ProxyTest?. TestProxy? is designed to work seamlessly with the generic cajo graphical Client class, which we will also be using in this example. TestProxy? declares two special methods; setItem, and init. When the ProxyTest? item binds itself, it is using the three argument bind method. This tells the ItemServer? that this third argument is a proxy to the first argument. The ItemServer? will automatically invoke the proxy's setItem method, if it has one, and provide it a remote reference to its serving object, on which it may communicate with it, when it reaches a remote Virtual Machine host. The second method, init, is called by the generic cajo graphical Client class, to signal that it has arrived at its remote Virtual Machine destination. The proxy should perform any local preparation it needs to do, before becoming visible, and return a component to display, in this case itself. The client also provides a remoted reference to the proxy as an argument, which it may give to its remote server object, to provide a link for asynchronous server to client communication. | > > | Proxy is a graphical user interface, provided to remote Virtual Machines, it also interacts with its sending object Test. Note: Proxy is, in this case, a plain-old AWT Panel. Proxy declares two special methods; setItem, and init. When the Test item binds itself, it uses the three argument bind method. This tells the ItemServer? that the third argument is a proxy to the first argument. The ItemServer? will automatically invoke the proxy's setItem method, if it has one, and provide it a remote reference to its serving object, on which it may communicate with it, when it reaches a remote Virtual Machine host. The second method, init, is called by the generic cajo graphical Client class, to signal that it has arrived at its remote Virtual Machine destination. The proxy should perform any local preparation it needs to do, before becoming visible, and return a component to display, in this case itself. The client also provides a remoted reference to the proxy as an argument, which it may give to its remote server object, to provide a link for asynchronous server to client communication. | | | | |
< < | ProxyTest? is the server object. It too has two special methods declared. The first method, getProxy, is called by the generic cajo graphical Client, to request the proxy widget. The second method, pressed, is called by the proxy object, to callback the remote server object asynchronously, whenever its button is pushed. ProxyTest? also starts up a default CodebaseServer?, to provide the necessary resources a remote Virtual Machine would need, in order to instantiate the proxy. | > > | Test is the server object. It too has two special methods declared. The first method, getProxy, is called by the generic cajo graphical Client, to request the proxy widget. The second method, pressed, is called by the proxy object, to callback the remote server object asynchronously, whenever its button is pushed. Test also starts up a default CodebaseServer?, to provide the necessary resources a remote Virtual Machine would need, in order to instantiate the proxy. Test is designed to work seamlessly with the generic cajo graphical Client class, which we will also be using in this example. | | | Compiling the example:
The file above is compiled using the following command from the console: | |
< < | javac -classpath cajo.jar;. ProxyTest.java
| > > | javac -classpath cajo.jar;. Test.java
| | | Now the server can be run. To do this, use the following command: | |
< < | java -classpath cajo.jar;. ProxyTest
| > > | java -classpath cajo.jar;. Test
| | | This will result in the following console output:
Server running on interface hostName
Using TCP port ####
Codebase server running: http://hostName:NNNN/
| |
< < | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically it will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this exact port number. | > > | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically it will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this exact port number. It is possible to run the CodebaseServer? on a fixed port, by specifying it in its constructor, rather than using zero. The ItemServer? can also run on a fixed port, using the static Remote.config rel="nofollow" method. | | | (Note: The two port numbers #### and NNNN are not the same. Typically #### = NNNN + 1) | | | However, there are two very important things to keep in mind:
| |
< < | The client does not have a reference to the proxy, rather it has an exact bitwise copy. Unlike conventional Java, this was an object pass-by-value! Any changes that occur to the remote proxy, none in this particular case; will not be reflected in the original master proxy, held by ProxyTest?. | > > | The client does not have a reference to the proxy, rather it has an exact bitwise copy. Unlike conventional Java, this was an object pass-by-value! Any changes that occur to the remote proxy, none in this particular case; will not be reflected in the original master proxy, held by Test. | | | | |
< < | If many clients request a proxy, they will all receive perfect bitwise copies. This means that the ProxyTest? method, pressed, can be invoked reentrantly by all of its proxies. Each remote call represents a separate thread of execution, if there are any concurrency issues, they will have to be properly synchronised. | > > | If many clients request a proxy, they will all receive perfect bitwise copies. This means that the Test method, pressed, can be invoked reentrantly by all of its proxies. Each remote call represents a separate thread of execution, if there are any concurrency issues, they will have to be properly synchronised. | | | | | | (remembering of course, that the hostName, and NNNN, will vary depending on the server)
Just for fun, you can go to another remote machine, or even the same machine, open a browser window and type in that URL. | |
< < | Behold the graphical widget, running inside the browser! :-) | > > | Behold the graphical proxy widget, running inside the browser! :-) | | | | |
> > | And finally:
Interested to make a Swing version, i.e. JProxyTest? It is a slightly different construction, but fortunately just as easy. |
|
<<O>> Difference Topic
ProxyUsage
(7 - 11 Feb 2006 - Main.cajo)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005 | | |
| |
< < | All that is required for this example, is the rel="nofollow" cajo project 38kB codebase cajo.jar, rel="nofollow" and the very small source file ProxyTest?, which will be explained completely below; | > > | All that is required for this example, is the rel="nofollow" cajo project 40kB codebase cajo.jar, rel="nofollow" and the very small source file ProxyTest?, which will be explained completely below; | | | ProxyTest.java:
| | | Compiling the example:
The file above is compiled using the following command from the console: | |
< < | javac -classpath cajo.jar ProxyTest.java
| > > | javac -classpath cajo.jar;. ProxyTest.java
| | | Now the server can be run. To do this, use the following command: | |
< < | java -cp cajo.jar;. ProxyTest
| > > | java -classpath cajo.jar;. ProxyTest
| | | This will result in the following console output:
Server running on interface hostName
|
|
<<O>> Difference Topic
ProxyUsage
(6 - 22 Aug 2005 - Main.cajo)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005 | | | Server running on interface hostName
Using TCP port ####
Codebase server running: http://hostName:NNNN/ | |
< < |
| > > | | | | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically it will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this exact port number.
(Note: The two port numbers #### and NNNN are not the same. Typically #### = NNNN + 1) | | | Using the proxy:
Now we go to another machine, though we really could use the same machine too. Again we open up a console window, and launch the generic cajo graphical Client, to request the proxy: | |
< < | java -cp cajo.jar gnu.cajo.invoke.Client //hostName:####/
| > > | java -cp cajo.jar gnu.cajo.invoke.Client //hostName:####/
(Note: do not forget the final / as it is required.)
| | | The Client will request the proxy by remotely invoking the ProxyTest? getProxy method, it will then locally invoke the init method on the returned proxy object, and voilą, the graphical proxy widget appears!
Now for the interactive part: |
|
<<O>> Difference Topic
ProxyUsage
(5 - 21 Aug 2005 - Main.cajo)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005 | | | Codebase server running: http://hostName:NNNN/
| |
< < | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically is will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this exact port number. | > > | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically it will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this exact port number.
(Note: The two port numbers #### and NNNN are not the same. Typically #### = NNNN + 1) | | | Using the proxy: |
|
<<O>> Difference Topic
ProxyUsage
(4 - 20 Aug 2005 - Main.cajo)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005
Using the cajo proxy mechanism | |
< < | Some people felt the main cajo project example is a little intense, demonstrating everything at once. However, proxies are such a very valuable mechanism of the cajo framework; here is a streamlined example, focusing exclusively on this powerful technology. | | |
| |
< < | All that is required for this example, is the standard codebase cajo.jar, and the source file ProxyTest?, which will be explained completely below; | > > | All that is required for this example, is the rel="nofollow" cajo project 38kB codebase cajo.jar, rel="nofollow" and the very small source file ProxyTest?, which will be explained completely below; | | | ProxyTest.java:
| | | }
public void actionPerformed(ActionEvent? e) {
try { Remote.invoke(item, "pressed", null); } | |
< < | catch(Exception x) { x.printStackTrace(); } // callback failure | > > | catch(Exception x) { x.printStackTrace(); } // network failure | | | }
public Dimension getPreferredSize() { return new Dimension(300, 300); }
} | | | The ProxyTest? represents an item, meaning a remotely callable object furnished by a Virtual Machine. It has a proxy, called TestProxy?, which it provides to remote Virtual Machines. TestProxy? is a static member class simply to allow this example to consist of a single source file. Many times, proxies exist in separate files. Combining them this way makes their interaction a little clearer, as we will see. | |
< < | TestProxy? is a graphical user interface, provided to remote Virtual Machines, it also interacts with sending object ProxyTest?. TestProxy? is designed to work seamlessly with the generic cajo graphical Client class, which we will also be using in this example. TestProxy? declares two special methods; setItem, and init. When the ProxyTest? item binds itself, it is using the three argument bind method. This tells the ItemServer? that this third argument is a proxy to the first argument. It will automatically invoke a proxy's setItem method, if it has one, and provide it a remote reference to its serving object, on which it may communicate with it, when it reaches a remote Virtual Machine host. The second method, init, is called by the generic cajo graphical Client class, to signal that it has arrived at its remote Virtual Machine destination, and should perform any local preparation it needs to do, before becoming visible. The provides a remoted reference to proxy as an argument, which it may provide to its remote server object, if necessary; making use of the remote item reference provided earlier by the init invocation. | > > | TestProxy? is a graphical user interface, provided to remote Virtual Machines, it also interacts with its sending object ProxyTest?. TestProxy? is designed to work seamlessly with the generic cajo graphical Client class, which we will also be using in this example. TestProxy? declares two special methods; setItem, and init. When the ProxyTest? item binds itself, it is using the three argument bind method. This tells the ItemServer? that this third argument is a proxy to the first argument. The ItemServer? will automatically invoke the proxy's setItem method, if it has one, and provide it a remote reference to its serving object, on which it may communicate with it, when it reaches a remote Virtual Machine host. The second method, init, is called by the generic cajo graphical Client class, to signal that it has arrived at its remote Virtual Machine destination. The proxy should perform any local preparation it needs to do, before becoming visible, and return a component to display, in this case itself. The client also provides a remoted reference to the proxy as an argument, which it may give to its remote server object, to provide a link for asynchronous server to client communication. | | | ProxyTest? is the server object. It too has two special methods declared. The first method, getProxy, is called by the generic cajo graphical Client, to request the proxy widget. The second method, pressed, is called by the proxy object, to callback the remote server object asynchronously, whenever its button is pushed. ProxyTest? also starts up a default CodebaseServer?, to provide the necessary resources a remote Virtual Machine would need, in order to instantiate the proxy. | | | Codebase server running: http://hostName:NNNN/
| |
< < | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically is will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this port number. | > > | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically is will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this exact port number. | | | Using the proxy: | | | Now for the interactive part: | |
< < | When the client VM user presses the push button in the proxy GUI, the remote server proudly exclaims: | > > | When the client VM user presses the button in the proxy GUI, the remote server proudly exclaims: | | | I heard that! | |
< < | There are two very important things to keep in mind however: | > > | However, there are two very important things to keep in mind: | | |
- The client does not have a reference to the proxy, rather it has an exact bitwise copy. Unlike conventional Java, this was an object pass-by-value! Any changes that occur to the remote proxy, none in this particular case; will not be reflected in the original master proxy, held by ProxyTest?.
| |
< < | If many clients request a proxy, they will all receive perfect bitwise copies. This means that the ProxyTest? method, pressed, can be invoked reentrantly by all of its proxies. Each remote call represents a separate thread of execution, if there are any concurrency issues, none in this particular case, they will have to be properly synchronised. | > > | If many clients request a proxy, they will all receive perfect bitwise copies. This means that the ProxyTest? method, pressed, can be invoked reentrantly by all of its proxies. Each remote call represents a separate thread of execution, if there are any concurrency issues, they will have to be properly synchronised. | | | | | | (remembering of course, that the hostName, and NNNN, will vary depending on the server)
Just for fun, you can go to another remote machine, or even the same machine, open a browser window and type in that URL. | |
< < | There is the graphical widget, running inside the browser! :-) | > > | Behold the graphical widget, running inside the browser! :-) | | | |
|
<<O>> Difference Topic
ProxyUsage
(3 - 19 Aug 2005 - Main.cajo)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005
Using the cajo proxy mechanism | |
< < | OK, maybe the example was a little intense, by trying to demonstrate everything at once. Proxies are such a very valuable mechanism of the cajo framework; here is an example focusing exclusively on this technology. | > > | Some people felt the main cajo project example is a little intense, demonstrating everything at once. However, proxies are such a very valuable mechanism of the cajo framework; here is a streamlined example, focusing exclusively on this powerful technology. | | |
|
|
<<O>> Difference Topic
ProxyUsage
(2 - 18 Aug 2005 - Main.cajo)
|
| |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005
Using the cajo proxy mechanism | |
< < | OK, maybe the example went a little too far, in trying to demonstrate everything at once. Proxies are a very valuable mechanism of the cajo framework; so here is a complete example focusing exclusively on them. | > > | OK, maybe the example was a little intense, by trying to demonstrate everything at once. Proxies are such a very valuable mechanism of the cajo framework; here is an example focusing exclusively on this technology. | | |
| |
< < | All that is required for this example, is the standard codebase cajo.jar, and the file which will be explained completely below; | > > | All that is required for this example, is the standard codebase cajo.jar, and the source file ProxyTest?, which will be explained completely below; | | | | |
< < | ProxyTest.java:
| > > | ProxyTest.java:
| | | import java.awt.*;
import java.awt.event.*;
import gnu.cajo.invoke.Remote; | | | }
} | |
< < | The ProxyTest? represents an item, meaning a remotely callable object furnished by a Virtual Machine. It has a proxy, called TestProxy?, which it provides to remote Virtual Machines. TestProxy? is a static member class simply to allow this example to consist of a single source file. Many times, proxies exist in separate files. Combining them this way does make their interaction a little clearer, as we will see. | > > | The ProxyTest? represents an item, meaning a remotely callable object furnished by a Virtual Machine. It has a proxy, called TestProxy?, which it provides to remote Virtual Machines. TestProxy? is a static member class simply to allow this example to consist of a single source file. Many times, proxies exist in separate files. Combining them this way makes their interaction a little clearer, as we will see. | | | | |
< < | TestProxy? is a graphical user interface, provided to remote Virtual Machines, it also interacts with sending object ProxyTest?. TestProxy? is designed to work seamlessly with the generic cajo graphical Client class, which we will also be using in this example. It has two special methods; setItem, and init. When the ProxyTest? binds itself, it uses the three argument method. This tells the ItemServer? that this third argument is a proxy to the first. It will automatically invoke the proxy's setItem method, sinc it has one, and provide it with a remote reference to its serving object, on which it may communicate with it when it reaches a remote Virtual Machine host. The second method init, is called by the generic cajo graphical Client class, to signal that it has arrived at its remote Virtual Machine destination, and should perform any local preparation it needs to do, before becoming visible. It also provides a remoted reference to itself, which it may provide to its remote server object, if necessary, making use of the remote reference provided in the init invocation. | > > | TestProxy? is a graphical user interface, provided to remote Virtual Machines, it also interacts with sending object ProxyTest?. TestProxy? is designed to work seamlessly with the generic cajo graphical Client class, which we will also be using in this example. TestProxy? declares two special methods; setItem, and init. When the ProxyTest? item binds itself, it is using the three argument bind method. This tells the ItemServer? that this third argument is a proxy to the first argument. It will automatically invoke a proxy's setItem method, if it has one, and provide it a remote reference to its serving object, on which it may communicate with it, when it reaches a remote Virtual Machine host. The second method, init, is called by the generic cajo graphical Client class, to signal that it has arrived at its remote Virtual Machine destination, and should perform any local preparation it needs to do, before becoming visible. The provides a remoted reference to proxy as an argument, which it may provide to its remote server object, if necessary; making use of the remote item reference provided earlier by the init invocation. | | | | |
< < | The ProxyTest? is the server object. It too has two special methods. The first method getProxy is called by the generic cajo graphical Client, to request the proxy widget. The second method, pressed, is called by the remote proxy object, to callback the server object asynchronously, whenever the proxy button is pushed. It also starts up a default CodebaseServer?, to provide the necessary resources a remote Virtual Machine would need, in order to instantiate the proxy. In this case it consists solely of the inner class ProxyTest?$TestProxy. | > > | ProxyTest? is the server object. It too has two special methods declared. The first method, getProxy, is called by the generic cajo graphical Client, to request the proxy widget. The second method, pressed, is called by the proxy object, to callback the remote server object asynchronously, whenever its button is pushed. ProxyTest? also starts up a default CodebaseServer?, to provide the necessary resources a remote Virtual Machine would need, in order to instantiate the proxy. | | | Compiling the example:
The file above is compiled using the following command from the console:
javac -classpath cajo.jar ProxyTest.java
Now the server can be run. To do this, use the following command: | |
< < | java -classpath cajo.jar;. ProxyTest
| > > | java -cp cajo.jar;. ProxyTest
| | | This will result in the following console output:
Server running on interface hostName
| | | Codebase server running: http://hostName:NNNN/
| |
< < | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically is will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this port number exactly. | > > | Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically is will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this port number. | | | Using the proxy: | | | Now for the interactive part:
When the client VM user presses the push button in the proxy GUI, the remote server proudly exclaims: | |
< < | I heard that! | > > | I heard that! | | | There are two very important things to keep in mind however:
- The client does not have a reference to the proxy, rather it has an exact bitwise copy. Unlike conventional Java, this was an object pass-by-value! Any changes that occur to the remote proxy, none in this particular case; will not be reflected in the original master proxy, held by ProxyTest?.
| |
< < | If many clients request a proxy, they will all receive perfect bitwise copies. This means that the ProxyTest? pressed method, can be invoked reentrantly by all of its proxies. Each remote call represents a separate thread of execution, if there are any concurrency issues, none in this particular case, they will have to be properly synchronised. | > > | If many clients request a proxy, they will all receive perfect bitwise copies. This means that the ProxyTest? method, pressed, can be invoked reentrantly by all of its proxies. Each remote call represents a separate thread of execution, if there are any concurrency issues, none in this particular case, they will have to be properly synchronised. | | | | |
< < | Extra Fun: | > > | Extra fun: | | | Remember that last line shown when the ProxyTest? started:
Codebase server running: http://hostName:NNNN/
| |
< < | (remembering of course, that the hostName, and NNNN will vary depending on the server) | > > | (remembering of course, that the hostName, and NNNN, will vary depending on the server) | | | | |
< < | Just for fun, you can go to another remote machine, or even the same machine, open a browser session and type in that URL.
Look again, there is the graphical widget running inside the browser! | > > | Just for fun, you can go to another remote machine, or even the same machine, open a browser window and type in that URL.
There is the graphical widget, running inside the browser! :-) | | | | |
> > | |
|
<<O>> Difference Topic
ProxyUsage
(1 - 17 Aug 2005 - Main.cajo)
|
|
> > |
| META TOPICPARENT | name="ExampleSection" |
-- JohnCatherino - 17 Aug 2005
Using the cajo proxy mechanism
OK, maybe the example went a little too far, in trying to demonstrate everything at once. Proxies are a very valuable mechanism of the cajo framework; so here is a complete example focusing exclusively on them.
All that is required for this example, is the standard codebase cajo.jar, and the file which will be explained completely below;
ProxyTest.java:
import java.awt.*;
import java.awt.event.*;
import gnu.cajo.invoke.Remote;
import gnu.cajo.utils.ItemServer;
import gnu.cajo.utils.CodebaseServer;
public class ProxyTest {
public static class TestProxy extends Panel implements ActionListener {
private Object selfRef, item;
TestProxy() {
super(new BorderLayout());
Label label = new Label("Test Proxy", Label.CENTER);
add(label, BorderLayout.CENTER);
Button button = new Button("fun button!");
button.addActionListener(this);
add(button, BorderLayout.SOUTH);
}
public void setItem(Object item) { this.item = item; }
public Component init(Object ref) {
selfRef = ref;
return this;
}
public void actionPerformed(ActionEvent e) {
try { Remote.invoke(item, "pressed", null); }
catch(Exception x) { x.printStackTrace(); } // callback failure
}
public Dimension getPreferredSize() { return new Dimension(300, 300); }
}
private TestProxy proxy = new TestProxy();
public Component getProxy() { return proxy; }
public void pressed() { System.out.println("I heard that!"); }
public static void main(String args[]) {
try {
new CodebaseServer(null, 0);
ProxyTest pt = new ProxyTest();
ItemServer.bind(pt, "main", pt.proxy);
System.out.print("Server running on interface ");
System.out.println(Remote.getServerHost());
System.out.print("Using TCP port ");
System.out.println(Remote.getServerPort());
System.out.print("Codebase server running: ");
System.out.println(System.getProperty("java.rmi.server.codebase"));
} catch (Exception x) { x.printStackTrace(); }
}
}
The ProxyTest represents an item, meaning a remotely callable object furnished by a Virtual Machine. It has a proxy, called TestProxy, which it provides to remote Virtual Machines. TestProxy is a static member class simply to allow this example to consist of a single source file. Many times, proxies exist in separate files. Combining them this way does make their interaction a little clearer, as we will see.
TestProxy is a graphical user interface, provided to remote Virtual Machines, it also interacts with sending object ProxyTest. TestProxy is designed to work seamlessly with the generic cajo graphical Client class, which we will also be using in this example. It has two special methods; setItem, and init. When the ProxyTest binds itself, it uses the three argument method. This tells the ItemServer that this third argument is a proxy to the first. It will automatically invoke the proxy's setItem method, sinc it has one, and provide it with a remote reference to its serving object, on which it may communicate with it when it reaches a remote Virtual Machine host. The second method init, is called by the generic cajo graphical Client class, to signal that it has arrived at its remote Virtual Machine destination, and should perform any local preparation it needs to do, before becoming visible. It also provides a remoted reference to itself, which it may provide to its remote server object, if necessary, making use of the remote reference provided in the init invocation.
The ProxyTest is the server object. It too has two special methods. The first method getProxy is called by the generic cajo graphical Client, to request the proxy widget. The second method, pressed, is called by the remote proxy object, to callback the server object asynchronously, whenever the proxy button is pushed. It also starts up a default CodebaseServer, to provide the necessary resources a remote Virtual Machine would need, in order to instantiate the proxy. In this case it consists solely of the inner class ProxyTest$TestProxy.
Compiling the example:
The file above is compiled using the following command from the console:
javac -classpath cajo.jar ProxyTest.java
Now the server can be run. To do this, use the following command:
java -classpath cajo.jar;. ProxyTest
This will result in the following console output:
Server running on interface hostName
Using TCP port ####
Codebase server running: http://hostName:NNNN/
Where hostName and ####, shown in the first two lines of output, are the address and port that will be needed to connect to the server item. Since the port number is anonymous, meaning selected from the pool of free port numbers, by the operating system. Typically is will change every time the server is run. This is important to remember, because as we will see, the client needs to specify this port number exactly.
Using the proxy:
Now we go to another machine, though we really could use the same machine too. Again we open up a console window, and launch the generic cajo graphical Client, to request the proxy:
java -cp cajo.jar gnu.cajo.invoke.Client //hostName:####/
The Client will request the proxy by remotely invoking the ProxyTest getProxy method, it will then locally invoke the init method on the returned proxy object, and voilą, the graphical proxy widget appears!
Now for the interactive part:
When the client VM user presses the push button in the proxy GUI, the remote server proudly exclaims:
I heard that!
There are two very important things to keep in mind however:
- The client does not have a reference to the proxy, rather it has an exact bitwise copy. Unlike conventional Java, this was an object pass-by-value! Any changes that occur to the remote proxy, none in this particular case; will not be reflected in the original master proxy, held by ProxyTest.
- If many clients request a proxy, they will all receive perfect bitwise copies. This means that the ProxyTest pressed method, can be invoked reentrantly by all of its proxies. Each remote call represents a separate thread of execution, if there are any concurrency issues, none in this particular case, they will have to be properly synchronised.
Extra Fun:
Remember that last line shown when the ProxyTest started:
Codebase server running: http://hostName:NNNN/
(remembering of course, that the hostName, and NNNN will vary depending on the server)
Just for fun, you can go to another remote machine, or even the same machine, open a browser session and type in that URL.
Look again, there is the graphical widget running inside the browser!
|
|