|
|
|
Sponsored Link •
|
|
Advertisement
|
Summary
In this document I show a Java application, which ran as a server on my laptop during the Cyberspace demo, that was responsible for launching resources.
In the Cyberspace demo, I used a server running locally on my laptop called the Cyberspace Console.
The browser plug-in and the Place services themselves (via a call to launchResource() on the
service context object) connected via a socket and "localhost" to
the Cyberspace Console, to request that a new resource be launched for the user.
If the resource was a Jini service, the Cyberspace Console exec'ed an
ObjectLauncher.
Here's the code for CyberspaceConsole:
/*
* This source code (.java) file is Copyright (C) 2000 Artima Software, Inc. All rights reserved.
* This file accompanies the Jini Place Service Draft Specification, written by Bill
* Venners and published on the World Wide Web at:
*
* http://www.artima.com/jini/cyberspace/DraftSpec.html,
*
* This source file may not be copied, modified, or redistributed EXCEPT as allowed
* by the following statements: From August 11, 2000 through December 31, 2000, you may
* copy and/or modify these files to test and experiment with the Place API,
* described in the Jini Place Service Draft Specification. Any bug fixes must be given
* back to Artima Software, Inc. You may not redistribute this file or any binary (such
* as .class) files generated from this file. You may not distribute modified versions
* this files or any binary (such as .class) files generated from modified versions of
* this file. You may not remove this copyright notice. You may not use this file in
* printed media without the express permission of Bill Venners. And if that weren't
* enough, you must destroy all copies of this file, and any binary (such as
* .class) files generated from this file, by December 31, 2000.
*
* ARTIMA SOFTWARE, INC. MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THIS SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
* BILL VENNERS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY A LICENSEE AS A RESULT
* OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*/
import java.io.IOException;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ObjectInputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.StreamCorruptedException;
import java.io.OptionalDataException;
public class CyberspaceConsole {
private static final int PORT = 7718;
// The command sent from either the Netscape browser's Cyberspace Plug-In
// or a Jini Place service itself. CMD_LAUNCH_URL means a URL follows
// the command. CMD_LAUNCH_OBJECT means a serialized marshalled
// ServiceItem follows the command. In the demo, the browser plug-in
// passes the serialized marshalled service item that came across the
// network as the application/x-serviceui MIME type.
private static final int CMD_LAUNCH_URL = 0;
private static final int CMD_LAUNCH_OBJECT = 1;
// The command to launch a Jini service and service UI. This likely just
// works on my computer, which was good enough for the demo. To get the demo
// working on your computer, you'll have to tweak this variable.
private static String[] execCmd = {
"c:\\jdk1.3\\bin\\java",
"-cp",
"d:\\projects\\serviceui\\apicode;d:\\projects\\cyberspace\\apicode; /
c:\\jini1_0_1\\lib\\jini-core.jar;c:\\jini1_0_1\\lib\\jini-ext.jar; /
c:\\jini1_0_1\\lib\\sun-util.jar; d:\\projects\\cyberspace\\launcher",
"-Djava.security.policy=c:/jini1_0_1/example/lookup/policy.all",
"ObjectLauncher",
""
};
// The command to launch the Netscape browser. Once again, this is hard-coded for my
// computer, which was good enough for the demo. To get this working on your own
// system, you may need to edit this variable. You may also need to make sure that
// the browser is in your path.
private static String[] browserCmd = {
//"d:\\progra~1\\Netscape\\Communicator\\Program\\netscape",
"netscape",
"-browser",
""
};
private static class MonitorInputStreamThread extends Thread {
private Reader reader;
private Writer writer;
public MonitorInputStreamThread(InputStream in) {
reader = new InputStreamReader(new BufferedInputStream(in));
writer = new OutputStreamWriter(System.out);
setDaemon(true);
}
public void run() {
try {
int c;
while ((c = reader.read()) != -1) {
writer.write(c);
writer.flush();
}
}
catch (IOException ioe) {
ioe.printStackTrace(System.out);
}
System.out.println("MonitorInputStreamThread exiting...");
}
}
// A thread that handles a single client request.
private static class ServerThread extends Thread {
private Socket sock;
public ServerThread(Socket sock) {
this.sock = sock;
}
public void run() {
try {
BufferedInputStream in =
new BufferedInputStream(
sock.getInputStream()
);
try {
// The first byte is a command that indicates what
// type of data follows.
int command = in.read();
if (command == CMD_LAUNCH_URL) {
launchURL(in);
}
else if (command == CMD_LAUNCH_OBJECT) {
launchObject(in);
}
else {
System.out.println("Unkown command, ignoring.");
}
}
finally {
in.close();
}
}
catch (IOException ioe) {
ioe.printStackTrace(System.out);
}
finally {
try {
sock.close();
}
catch (IOException e) {
}
}
}
}
public static void main(String[] args)
throws IOException {
// Listen on port 7777 for incoming commands
ServerSocket listener = new ServerSocket(PORT);
try {
for (;;) {
Socket sock = listener.accept();
// Start a new ServerThread to handle each
// incoming request.
ServerThread ss = new ServerThread(sock);
ss.start();
}
}
finally {
listener.close();
}
}
private static void launchURL(InputStream in) {
ObjectInputStream ois;
try {
// Client passes the URL as a String object, so wrap
// the InputStream in an ObjectInputStream.
ois = new ObjectInputStream(in);
}
catch (StreamCorruptedException sce) {
System.out.println("URL String object input stream corrupted. Aborting.");
return;
}
catch (IOException ioe) {
System.out.println("IOException while deserializing URL String. Aborting.");
return;
}
String url;
try {
// Deserialize the URL String object
url = (String) ois.readObject();
}
catch (OptionalDataException ode) {
System.out.println("OptionalDataException while attempting to deserialize a URL String. Aborting.");
return;
}
catch (IOException ioe) {
System.out.println("IOException while deserializing URL String. Aborting.");
return;
}
catch (ClassNotFoundException cnfe) {
System.out.println("ClassNotFoundException while deserializing URL String. Aborting.");
return;
}
System.out.println("runResourceWithUI(" + url + ")");
String[] cmd;
// If its a .serviceui file, pass the URL to the ObjectLauncher.
// Otherwise, just pass the URL to the browser.
if (url.endsWith(".serviceui")) {
execCmd[5] = url;
cmd = execCmd;
}
else {
browserCmd[2] = url;
cmd = browserCmd;
}
try {
Process process = Runtime.getRuntime().exec(cmd);
// Start threads to suck the bytes out of the stderr
// and stdout. If you don't do this, Windows will hang.
// Besides, it's sometimes nice to see what those Jini
// services are printing to the stdout and stderr. That's
// what makes this the Cyberspace *Console*.
InputStream processOut = process.getInputStream();
InputStream processErr = process.getErrorStream();
Thread thread = new MonitorInputStreamThread(processOut);
thread.start();
thread = new MonitorInputStreamThread(processErr);
thread.start();
}
catch (IOException ioe) {
ioe.printStackTrace(System.out);
}
}
private static void launchObject(InputStream in) {
BufferedInputStream buffin = new BufferedInputStream(in);
execCmd[5] = "";
try {
Process process = Runtime.getRuntime().exec(execCmd);
// Start threads to suck the bytes out of the stderr
// and stdout. If you don't do this, Windows will hang.
// Besides, it's sometimes nice to see what those Jini
// services are printing to the stdout and stderr. That's
// what makes this the Cyberspace *Console*.
InputStream processOut = process.getInputStream();
InputStream processErr = process.getErrorStream();
Thread thread = new MonitorInputStreamThread(processOut);
thread.start();
thread = new MonitorInputStreamThread(processErr);
thread.start();
// Feed the bytes of the serialized object to the process's stdin
BufferedOutputStream buffout = new BufferedOutputStream(process.getOutputStream());
try {
int c;
while ((c = buffin.read()) != -1) {
buffout.write(c);
}
}
finally {
buffout.flush();
buffout.close();
}
}
catch (IOException ioe) {
ioe.printStackTrace(System.out);
}
}
}
To discuss the ideas presented in this article please post to the cyberspace@jini.org mailing list, or visit:
http://www.artima.com/jini/jf/cyberspace/index.html
For a more in-depth explanation of the cyberspace project, please see the A Walk Through Cyberspace article.
|
Sponsored Links
|