The Artima Developer Community
Sponsored Link

The Object Launcher
By Bill Venners

Advertisement

Summary
In this document I show a Java application, used in the Cyberspace demo, that wraps a Jini service and service UI.


In the Cyberspace demo, I launched each Jini service and service UI in its own JVM. The Java application that I ran to start the JVM for a Jini service and service UI was named ObjectLauncher. ObjectLauncher was fired up by CyberspaceConsole. Here's the code for ObjectLauncher:

/*
 * 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.net.URL;
import java.net.URLConnection;
import java.net.MalformedURLException;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.rmi.MarshalledObject;
import java.rmi.RMISecurityManager;
import net.jini.core.lookup.ServiceItem;
import net.jini.lookup.entry.UIDescriptor;
import net.jini.core.entry.Entry;
import net.jini.lookup.ui.MainUI;
import net.jini.lookup.ui.attribute.UIFactoryTypes;
import net.jini.lookup.ui.factory.JFrameFactory;
import net.jini.lookup.ui.factory.FrameFactory;
import java.util.Iterator;
import javax.swing.JFrame;
import java.awt.Frame;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

// Launch a Jini service, either from a URL passed as a command line
// argument, or from a serialized marshalled service item read in
// from the standard input.
public class ObjectLauncher {

    public static void main(String[] args) {

        // If no command line argument, assume a serialized marshalled
        // Jini service item is being fed to the standard input.
        boolean fromURL = true;
        if (args.length == 0) {
            fromURL = false;
        }

        try {

            System.setSecurityManager(new RMISecurityManager());

            // Will read the serialized marshalled service item from InputStream "is".
            // If grabbing via a URL, get the stream from a URL object. Else
            // just assume its coming in at the standard input.
            InputStream is = System.in;
            if (fromURL) {

                URL url  = new URL(args[0]);

                System.out.println(
                    "Launching object from URL: " + url.toString());

                URLConnection conn = url.openConnection();
                is = url.openStream();

                // Get info about the resource
                String type = conn.getContentType();
                if ((!type.equals("application/x-serviceui")) && (!type.equals("application/jini"))) {
                    System.out.println("Wrong MIME type. Not a Jini service item: " + type);
                    return;
                }
            }
            else {
                System.out.println(
                    "Launching object passed by browser.");
            }

            try {

                ObjectInputStream ois =
                    new ObjectInputStream(
                        new BufferedInputStream(is)
                    );

                // Should be a serialized MarshalledObject
                MarshalledObject mo = null;
                try {
                    mo = (MarshalledObject) ois.readObject();
                }
                catch (ClassNotFoundException cnfe) {
                    System.out.println("Unable to deserialize the marshalled object.");
                    cnfe.printStackTrace(System.out);
                    return;
                }

                // Unmarshalling should yield a Jini ServiceItem
                ServiceItem serviceItem;
                try {
                    serviceItem = (ServiceItem) mo.get();
                }
                catch (ClassNotFoundException cnfe) {
                    System.out.println("Unable to unmarshal the service item.");
                    cnfe.printStackTrace(System.out);
                    return;
                }

                int attrCount = serviceItem.attributeSets.length;
                Entry[] attr = serviceItem.attributeSets;

                // Now search for an appropriate service UI from among
                // UIDescriptor's in the ServiceItem
                UIDescriptor selectedDescriptor = null;
outer:          for (int i = 0; i < attrCount; ++i) {

                    if (attr[i] instanceof UIDescriptor) {

                        UIDescriptor desc = (UIDescriptor) attr[i];

                        if (desc.attributes == null) {
                            continue;
                        }

                        // Looking for a Main UI
                        if (!desc.role.equals(MainUI.ROLE)) {
                            continue;
                        }

                        // Iterate through the attributes, looking for
                        // a JFrame or Frame.
                        Iterator it = desc.attributes.iterator();
                        while (it.hasNext()) {

                            Object uiAttr = it.next();
                            if (uiAttr instanceof UIFactoryTypes) {

                                UIFactoryTypes factoryTypes = (UIFactoryTypes) uiAttr;

                                boolean found = false;

                                found = factoryTypes.isAssignableTo(JFrameFactory.class);
                                if (!found) {
                                    found = factoryTypes.isAssignableTo(FrameFactory.class);
                                }

                                if (found) {
                                    // Should also look through required packages here, but
                                    // ignoring that for the demo
                                    selectedDescriptor = desc;
                                    break outer;
                                }
                            }
                        }
                    }
                }

                if (selectedDescriptor == null) {
                    System.out.println("Found no appropriate UI.");
                    System.exit(0);
                }

                // Get the UI Factory for the chosen UI
                Object uiFactory = null;
                try {
                    uiFactory = selectedDescriptor.getUIFactory(serviceItem.service.getClass().getClassLoader());
                }
                catch (ClassNotFoundException cnfe) {
                    System.out.println("Class not found. Couldn't unmarshal the UI factory.");
                    cnfe.printStackTrace(System.out);
                    return;
                }

                if (uiFactory instanceof JFrameFactory) {

                    JFrameFactory swingJFrameFactory = (JFrameFactory) uiFactory;
                    JFrame jf =  swingJFrameFactory.getJFrame(serviceItem);

                    // Add a WindowListener so that the process exits nicely
                    jf.addWindowListener(
                        new WindowAdapter() {
                            public void windowClosing(WindowEvent e) {
                                // This one gets called after the user Selects some operating
                                // system thing that requests the window to be closed.
                                System.exit(0);
                            }
                            public void windowClosed(WindowEvent e) {
                                // This one gets called after dispose() is called, such
                                // as when the user selects Exit.
                                System.exit(0);
                            }
                        }
                    );
                    jf.setLocation(100, 100);
                    jf.pack();

                    // If this is a place service, set the size to a nice size for the demo, because
                    // pack makes all links line up on one long horizontal line, which is 110 pixels
                    // tall. The only other JFrame is the calculator, which comes out (331, 258)
                    // This is obviously a hard coded demo thing.
                    Dimension dim = jf.getSize();
                    if (dim.height < 150 && dim.width > 360) {
                        jf.setSize(360, 270);
                    }
                    jf.setVisible(true);
                }
                else {

                    FrameFactory awtFrameFactory = (FrameFactory) uiFactory;
                    Frame frame =  awtFrameFactory.getFrame(serviceItem);

                    // Add a WindowListener so that the process exits nicely
                    frame.addWindowListener(
                        new WindowAdapter() {
                            public void windowClosing(WindowEvent e) {
                                // This one gets called after the user Selects some operating
                                // system thing that requests the window to be closed.
                                System.exit(0);
                            }
                            public void windowClosed(WindowEvent e) {
                                // This one gets called after dispose() is called, such
                                // as when the user selects Exit.
                                System.exit(0);
                            }
                        }
                    );

                    frame.setLocation(100, 100);

                    // This is colorschemer, so just set it to an appropriate size (for a nice looking demo)
                    // Yet another hard coded demo thing.
                    frame.setSize(468, 350);
                    frame.setVisible(true);
                }
            }
            finally {
                is.close();
            }
        }
        catch (MalformedURLException e) {
            System.out.println(e.toString());
            e.printStackTrace(System.out);
        }
        catch (IOException e) {
            System.out.println(e.toString());
            e.printStackTrace(System.out);
        }
    }
}

Discussion Forum

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.

ServiceUI is a trademark of Artima Software, Inc.

Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us