alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Transport.java)

This example Java source code file (Transport.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

channel, classloader, dispatcher, ioexception, log, objectendpoint, objid, remoteexception, rmi, security, servernotactiveexception, string, target, threadlocal, transport, void

The Transport.java Java example source code

/*
 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.rmi.transport;

import java.io.IOException;
import java.io.ObjectOutput;
import java.rmi.MarshalException;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.LogStream;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteCall;
import java.rmi.server.RemoteServer;
import java.rmi.server.ServerNotActiveException;
import java.security.AccessControlContext;
import sun.rmi.runtime.Log;
import sun.rmi.server.Dispatcher;
import sun.rmi.server.UnicastServerRef;

/**
 * Transport abstraction for enabling communication between different
 * VMs.
 *
 * @author Ann Wollrath
 */
@SuppressWarnings("deprecation")
public abstract class Transport {

    /** "transport" package log level */
    static final int logLevel = LogStream.parseLevel(getLogLevel());

    private static String getLogLevel() {
        return java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction("sun.rmi.transport.logLevel"));
    }

    /* transport package log */
    static final Log transportLog =
        Log.getLog("sun.rmi.transport.misc", "transport", Transport.logLevel);

    /** References the current transport when a call is being serviced */
    private static final ThreadLocal<Transport> currentTransport = new ThreadLocal<>();

    /** ObjID for DGCImpl */
    private static final ObjID dgcID = new ObjID(ObjID.DGC_ID);

    /**
     * Returns a <I>Channel that generates connections to the
     * endpoint <I>ep. A Channel is an object that creates and
     * manages connections of a particular type to some particular
     * address space.
     * @param ep the endpoint to which connections will be generated.
     * @return the channel or null if the transport cannot
     * generate connections to this endpoint
     */
    public abstract Channel getChannel(Endpoint ep);

    /**
     * Removes the <I>Channel that generates connections to the
     * endpoint <I>ep.
     */
    public abstract void free(Endpoint ep);

    /**
     * Export the object so that it can accept incoming calls.
     */
    public void exportObject(Target target) throws RemoteException {
        target.setExportedTransport(this);
        ObjectTable.putTarget(target);
    }

    /**
     * Invoked when an object that was exported on this transport has
     * become unexported, either by being garbage collected or by
     * being explicitly unexported.
     **/
    protected void targetUnexported() { }

    /**
     * Returns the current transport if a call is being serviced, otherwise
     * returns null.
     **/
    static Transport currentTransport() {
        return currentTransport.get();
    }

    /**
     * Verify that the current access control context has permission to accept
     * the connection being dispatched by the current thread.  The current
     * access control context is passed as a parameter to avoid the overhead of
     * an additional call to AccessController.getContext.
     */
    protected abstract void checkAcceptPermission(AccessControlContext acc);

    /**
     * Service an incoming remote call. When a message arrives on the
     * connection indicating the beginning of a remote call, the
     * threads are required to call the <I>serviceCall method of
     * their transport.  The default implementation of this method
     * locates and calls the dispatcher object.  Ordinarily a
     * transport implementation will not need to override this method.
     * At the entry to <I>tr.serviceCall(conn), the connection's
     * input stream is positioned at the start of the incoming
     * message.  The <I>serviceCall method processes the incoming
     * remote invocation and sends the result on the connection's
     * output stream.  If it returns "true", then the remote
     * invocation was processed without error and the transport can
     * cache the connection.  If it returns "false", a protocol error
     * occurred during the call, and the transport should destroy the
     * connection.
     */
    public boolean serviceCall(final RemoteCall call) {
        try {
            /* read object id */
            final Remote impl;
            ObjID id;

            try {
                id = ObjID.read(call.getInputStream());
            } catch (java.io.IOException e) {
                throw new MarshalException("unable to read objID", e);
            }

            /* get the remote object */
            Transport transport = id.equals(dgcID) ? null : this;
            Target target =
                ObjectTable.getTarget(new ObjectEndpoint(id, transport));

            if (target == null || (impl = target.getImpl()) == null) {
                throw new NoSuchObjectException("no such object in table");
            }

            final Dispatcher disp = target.getDispatcher();
            target.incrementCallCount();
            try {
                /* call the dispatcher */
                transportLog.log(Log.VERBOSE, "call dispatcher");

                final AccessControlContext acc =
                    target.getAccessControlContext();
                ClassLoader ccl = target.getContextClassLoader();

                Thread t = Thread.currentThread();
                ClassLoader savedCcl = t.getContextClassLoader();

                try {
                    t.setContextClassLoader(ccl);
                    currentTransport.set(this);
                    try {
                        java.security.AccessController.doPrivileged(
                            new java.security.PrivilegedExceptionAction<Void>() {
                            public Void run() throws IOException {
                                checkAcceptPermission(acc);
                                disp.dispatch(impl, call);
                                return null;
                            }
                        }, acc);
                    } catch (java.security.PrivilegedActionException pae) {
                        throw (IOException) pae.getException();
                    }
                } finally {
                    t.setContextClassLoader(savedCcl);
                    currentTransport.set(null);
                }

            } catch (IOException ex) {
                transportLog.log(Log.BRIEF,
                                 "exception thrown by dispatcher: ", ex);
                return false;
            } finally {
                target.decrementCallCount();
            }

        } catch (RemoteException e) {

            // if calls are being logged, write out exception
            if (UnicastServerRef.callLog.isLoggable(Log.BRIEF)) {
                // include client host name if possible
                String clientHost = "";
                try {
                    clientHost = "[" +
                        RemoteServer.getClientHost() + "] ";
                } catch (ServerNotActiveException ex) {
                }
                String message = clientHost + "exception: ";
                UnicastServerRef.callLog.log(Log.BRIEF, message, e);
            }

            /* We will get a RemoteException if either a) the objID is
             * not readable, b) the target is not in the object table, or
             * c) the object is in the midst of being unexported (note:
             * NoSuchObjectException is thrown by the incrementCallCount
             * method if the object is being unexported).  Here it is
             * relatively safe to marshal an exception to the client
             * since the client will not have seen a return value yet.
             */
            try {
                ObjectOutput out = call.getResultStream(false);
                UnicastServerRef.clearStackTraces(e);
                out.writeObject(e);
                call.releaseOutputStream();

            } catch (IOException ie) {
                transportLog.log(Log.BRIEF,
                    "exception thrown marshalling exception: ", ie);
                return false;
            }
        }

        return true;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java Transport.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.