/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sun.jini.phoenix; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.rmi.NoSuchObjectException; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.server.ExportException; import java.rmi.server.ObjID; import java.rmi.server.UnicastRemoteObject; import net.jini.export.Exporter; import sun.rmi.server.UnicastServerRef; import sun.rmi.transport.LiveRef; /** * JRMP exporter to export an object using a well-known object identifier. * This exporter implementation is only designed to work with * Java(TM) 2 Standard Edition implementations from Sun Microsystems(TM), Inc. * * @author Sun Microsystems, Inc. * * @since 2.0 */ public class SunJrmpExporter implements Exporter { /** * The object identifier. */ private final int id; /** * The port. */ private final int port; /** * Weak reference to the impl. */ private WeakReference ref; private static final Method exportMethod; static { try { Class[] paramTypes = new Class[] { Remote.class, Object.class, boolean.class }; exportMethod = UnicastServerRef.class.getMethod("exportObject", paramTypes); } catch (NoSuchMethodException nsme) { throw (Error) new NoSuchMethodError().initCause(nsme); } } /** * Creates a JRMP exporter that exports using the specified well-known * object identifier and the specified port. * * @param id the object identifier * @param port the port (if zero, an anonymous port will be chosen) */ public SunJrmpExporter(int id, int port) { this.id = id; this.port = port; } /** * @throws NullPointerException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ public Remote export(Remote impl) throws ExportException { if (ref != null) { throw new IllegalStateException("already used for export"); } else if (impl == null) { throw new NullPointerException(); } ref = new WeakReference(impl); UnicastServerRef uref = getServerRef(new LiveRef(new ObjID(id), port)); try { Object[] args = new Object[] { impl, null, Boolean.TRUE }; return (Remote) exportMethod.invoke(uref, args); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof ExportException) { throw (ExportException) t; } else if (t instanceof RemoteException) { throw new ExportException("export failed", (Exception) t); } else if (t instanceof RuntimeException) { throw (RuntimeException) t; } else if (t instanceof Error) { throw (Error) t; } else { throw new AssertionError(t); } } catch (IllegalAccessException e) { throw (Error) new IllegalAccessError().initCause(e); } } UnicastServerRef getServerRef(LiveRef lref) { return new UnicastServerRef(lref); } /** * @throws IllegalStateException {@inheritDoc} */ public boolean unexport(boolean force) { if (ref == null) { throw new IllegalStateException( "no object exported through this exporter"); } Remote impl = (Remote) ref.get(); if (impl == null) { return true; } try { return UnicastRemoteObject.unexportObject(impl, force); } catch (NoSuchObjectException ex) { return true; } } }