| /** |
| * |
| * 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 org.apache.yoko.rmi.impl; |
| |
| import java.io.Externalizable; |
| import java.io.IOException; |
| import java.io.Serializable; |
| import java.lang.reflect.Constructor; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.net.URLClassLoader; |
| import java.rmi.AccessException; |
| import java.rmi.MarshalException; |
| import java.rmi.NoSuchObjectException; |
| import java.rmi.Remote; |
| import java.rmi.RemoteException; |
| import java.rmi.ServerError; |
| import java.rmi.ServerException; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import java.security.PrivilegedActionException; |
| import java.security.PrivilegedExceptionAction; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| |
| import javax.rmi.PortableRemoteObject; |
| import javax.rmi.CORBA.Stub; |
| import javax.rmi.CORBA.Tie; |
| import javax.rmi.CORBA.Util; |
| import javax.rmi.CORBA.UtilDelegate; |
| import javax.rmi.CORBA.ValueHandler; |
| |
| import org.apache.yoko.rmi.util.GetSystemPropertyAction; |
| import org.apache.yoko.osgi.ProviderLocator; |
| import org.omg.CORBA.Any; |
| import org.omg.CORBA.BAD_PARAM; |
| import org.omg.CORBA.COMM_FAILURE; |
| import org.omg.CORBA.INVALID_TRANSACTION; |
| import org.omg.CORBA.INV_OBJREF; |
| import org.omg.CORBA.MARSHAL; |
| import org.omg.CORBA.NO_IMPLEMENT; |
| import org.omg.CORBA.NO_PERMISSION; |
| import org.omg.CORBA.OBJECT_NOT_EXIST; |
| import org.omg.CORBA.SystemException; |
| import org.omg.CORBA.TCKind; |
| import org.omg.CORBA.TRANSACTION_REQUIRED; |
| import org.omg.CORBA.TRANSACTION_ROLLEDBACK; |
| import org.omg.CORBA.TypeCode; |
| import org.omg.CORBA.portable.IDLEntity; |
| import org.omg.CORBA.portable.UnknownException; |
| |
| public class UtilImpl implements UtilDelegate { |
| private static final Logger logger = Logger.getLogger(UtilImpl.class.getName()); |
| |
| // Note: this field must be declared before the static intializer that calls Util.loadClass |
| // since that method will call loadClass0 which uses this field... if it is below the static |
| // initializer the _secman field will be null |
| private static final SecMan _secman = getSecMan(); |
| |
| private static final ClassLoader BEST_GUESS_AT_EXTENSION_CLASS_LOADER; |
| static { |
| ClassLoader candidateLoader = getClassLoader(UtilImpl.class); |
| |
| if (candidateLoader == null) { |
| // looks like this class was loaded by the boot class loader |
| // so it is safe to try loading stuff by reflection without |
| // worrying about whether we have imported the packages into the OSGi bundle |
| candidateLoader = findFirstNonNullLoader( |
| "sun.net.spi.nameservice.dns.DNSNameService", |
| "javax.transaction.UserTransaction"); |
| } |
| |
| // We will try to find the extension class |
| // loader by ascending the loader hierarchy |
| // starting from whatever loader we found. |
| for (ClassLoader l = candidateLoader; l != null; l = l.getParent()) { |
| candidateLoader = l; |
| } |
| |
| BEST_GUESS_AT_EXTENSION_CLASS_LOADER = candidateLoader; |
| } |
| |
| private static ClassLoader findFirstNonNullLoader(String...classNames) { |
| for (String className : classNames) { |
| try { |
| final Class<?> c = Class.forName(className); |
| ClassLoader cl = getClassLoader(c); |
| if (cl != null) return cl; |
| } catch (Exception|NoClassDefFoundError swallowed) { |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Translate a CORBA SystemException to the corresponding RemoteException |
| */ |
| public RemoteException mapSystemException(final SystemException theException) { |
| |
| SystemException ex = theException; |
| |
| if (ex instanceof UnknownException) { |
| Throwable orig = ((UnknownException) ex).originalEx; |
| if (orig instanceof Error) { |
| return new ServerError("Error occurred in server thread", |
| (Error) orig); |
| } else if (orig instanceof RemoteException) { |
| return new ServerException( |
| "RemoteException occurred in server thread", |
| (Exception) orig); |
| } else if (orig instanceof RuntimeException) { |
| throw (RuntimeException) orig; |
| } |
| } |
| |
| Class<? extends SystemException> exclass = ex.getClass(); |
| String name = exclass.getName(); |
| |
| // construct the exception message according to �1.4.8 |
| |
| StringBuffer buf = new StringBuffer("CORBA "); |
| |
| final String prefix = "org.omg.CORBA"; |
| if (name.startsWith(prefix)) { |
| buf.append(name.substring(prefix.length() + 1)); |
| } else { |
| buf.append(name); |
| } |
| |
| buf.append(" "); |
| buf.append(ex.minor); |
| |
| switch (ex.completed.value()) { |
| case org.omg.CORBA.CompletionStatus._COMPLETED_YES: |
| buf.append(" Yes"); |
| break; |
| |
| case org.omg.CORBA.CompletionStatus._COMPLETED_NO: |
| buf.append(" No"); |
| break; |
| |
| case org.omg.CORBA.CompletionStatus._COMPLETED_MAYBE: |
| buf.append(" Maybe"); |
| break; |
| } |
| |
| String exceptionMessage = buf.toString(); |
| |
| return createRemoteException(ex, exceptionMessage); |
| } |
| |
| private RemoteException createRemoteException(SystemException sysEx, String s) { |
| RemoteException result; |
| try { |
| throw sysEx; |
| } catch (BAD_PARAM|COMM_FAILURE|MARSHAL e) { |
| result = new MarshalException(s); |
| } catch (INV_OBJREF|NO_IMPLEMENT|OBJECT_NOT_EXIST e) { |
| result = new NoSuchObjectException(s); |
| } catch(NO_PERMISSION e) { |
| result = new AccessException(s); |
| } catch (TRANSACTION_REQUIRED e) { |
| result = createRemoteException("javax.transaction.TransactionRequiredException", s); |
| } catch (TRANSACTION_ROLLEDBACK e) { |
| result = createRemoteException("javax.transaction.TransactionRolledbackException", s); |
| } catch (INVALID_TRANSACTION e) { |
| result = createRemoteException("javax.transaction.InvalidTransactionException", s); |
| } catch (SystemException catchAll) { |
| result = new RemoteException(s); |
| } |
| result.detail = sysEx; |
| return result; |
| } |
| |
| private static RemoteException createRemoteException(String className, String s) { |
| RemoteException result; |
| try { |
| @SuppressWarnings("unchecked") |
| Class<? extends RemoteException> clazz = Util.loadClass(className, null, null); |
| Constructor<? extends RemoteException> ctor = clazz.getConstructor(String.class); |
| result = ctor.newInstance(s); |
| } catch (Throwable t) { |
| result = new RemoteException(s); |
| result.addSuppressed(t); |
| } |
| return result; |
| } |
| |
| static SystemException mapRemoteException(RemoteException rex) { |
| if (rex.detail instanceof org.omg.CORBA.SystemException) |
| return (org.omg.CORBA.SystemException) rex.detail; |
| |
| if (rex.detail instanceof RemoteException) |
| rex = (RemoteException) rex.detail; |
| |
| SystemException sysEx; |
| |
| if (rex instanceof java.rmi.NoSuchObjectException) { |
| sysEx = new org.omg.CORBA.INV_OBJREF(rex.getMessage()); |
| } else if (rex instanceof java.rmi.AccessException) { |
| sysEx = new org.omg.CORBA.NO_PERMISSION(rex.getMessage()); |
| } else if (rex instanceof java.rmi.MarshalException) { |
| sysEx = new org.omg.CORBA.MARSHAL(rex.getMessage()); |
| } else { |
| sysEx = createSystemException(rex); |
| } |
| sysEx.initCause(rex); |
| throw sysEx; |
| } |
| |
| private static SystemException createSystemException(RemoteException rex) { |
| return createSystemException(rex, rex.getClass()); |
| } |
| |
| /** |
| * utility method to check for JTA exception types without linking to the JTA classes directly |
| */ |
| private static SystemException createSystemException(RemoteException rex, Class<?> fromClass) { |
| // Recurse up the parent chain, |
| // until we reach a known JTA type. |
| switch(fromClass.getName()) { |
| // Of course, we place some known elephants in Cairo. |
| case "java.lang.Object": |
| case "java.lang.Throwable": |
| case "java.lang.Exception": |
| case "java.lang.RuntimeException": |
| case "java.lang.Error": |
| case "java.io.IOException": |
| case "java.rmi.RemoteException": |
| return new UnknownException(rex); |
| case "javax.transaction.InvalidTransactionException": |
| return new INVALID_TRANSACTION(rex.getMessage()); |
| case "javax.transaction.TransactionRolledbackException": |
| return new TRANSACTION_ROLLEDBACK(rex.getMessage()); |
| case "javax.transaction.TransactionRequiredException": |
| return new TRANSACTION_REQUIRED(rex.getMessage()); |
| } |
| return createSystemException(rex, fromClass.getSuperclass()); |
| } |
| |
| /** |
| * Write an org.omg.CORBA.Any containing the given object. |
| * <p/> |
| * The object is not converted or translated, simply written. Thus, it must |
| * be either an IDL-generated entity, a Serializable value or an |
| * org.omg.CORBA.Object. Specifically, a Remote objects and Servants cannot |
| * be written, but their corresponding Stubs can. |
| * |
| * @param out The stream to which the value should be written |
| * @param obj The object/value to write |
| * @throws org.omg.CORBA.MARSHAL if the value cannot be written |
| */ |
| public void writeAny(org.omg.CORBA.portable.OutputStream out, Object obj) |
| throws org.omg.CORBA.SystemException { |
| // |
| // In this implementation of RMI/IIOP we do not use type codes |
| // beyond the implementation of this method, and it's |
| // counterpart readAny. |
| // |
| |
| org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(); |
| Any any = orb.create_any(); |
| |
| if (obj == null) { |
| // JDK 1.3.1-1 doesn't like NULL typecodes, so |
| // we write it as a null Value. |
| |
| any.insert_Value(null); |
| |
| } else if (obj instanceof String) { |
| any.insert_Value((String) obj); |
| |
| } else if (obj instanceof org.omg.CORBA.Object) { |
| any.insert_Object((org.omg.CORBA.Object) obj); |
| |
| } else if (obj instanceof Any) { |
| any.insert_any((Any) obj); |
| |
| } else if (obj instanceof IDLEntity) { |
| any.insert_Value((Serializable) obj); |
| |
| } else if (obj instanceof java.rmi.Remote) { |
| Remote ro = (Remote) obj; |
| org.omg.CORBA.Object corba_obj; |
| try { |
| corba_obj = (org.omg.CORBA.Object) PortableRemoteObject |
| .toStub(ro); |
| } catch (java.rmi.NoSuchObjectException ex) { |
| throw (org.omg.CORBA.MARSHAL) new org.omg.CORBA.MARSHAL( |
| "object not exported " + ro).initCause(ex); |
| } |
| |
| any.insert_Object((org.omg.CORBA.Object) corba_obj); |
| |
| } else if (obj instanceof Serializable || obj instanceof Externalizable) { |
| |
| any.insert_Value((Serializable) obj); |
| |
| } else { |
| throw new MARSHAL("cannot write as " + obj.getClass() |
| + " to an Any"); |
| } |
| |
| out.write_any(any); |
| } |
| |
| public Object readAny(org.omg.CORBA.portable.InputStream in) |
| throws org.omg.CORBA.SystemException { |
| Any any = in.read_any(); |
| TypeCode typecode = any.type(); |
| |
| switch (typecode.kind().value()) { |
| |
| case TCKind._tk_null: |
| case TCKind._tk_void: |
| return null; |
| |
| case TCKind._tk_value: |
| case TCKind._tk_value_box: |
| return any.extract_Value(); |
| |
| case TCKind._tk_abstract_interface: |
| org.omg.CORBA_2_3.portable.InputStream in23 = (org.omg.CORBA_2_3.portable.InputStream) any |
| .create_input_stream(); |
| return in23.read_abstract_interface(); |
| |
| case TCKind._tk_string: |
| return any.extract_string(); |
| |
| case TCKind._tk_objref: |
| org.omg.CORBA.Object ref = any.extract_Object(); |
| return ref; |
| |
| case TCKind._tk_any: |
| return any.extract_any(); |
| |
| default: |
| String id = "<unknown>"; |
| try { |
| id = typecode.id(); |
| } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) { |
| } |
| |
| throw new MARSHAL("cannot extract " + id + " (" |
| + typecode.kind().value() + ") value from Any"); |
| } |
| } |
| |
| /** |
| * Write a remote object. It must already be exported. |
| * <p/> |
| * This method accepts values of org.omg.CORBA.Object (including stubs), and |
| * instances of java.rmi.Remote for objects that have already been exported. |
| */ |
| public void writeRemoteObject(org.omg.CORBA.portable.OutputStream out, |
| Object obj) throws org.omg.CORBA.SystemException { |
| org.omg.CORBA.Object objref = null; |
| |
| if (obj == null) { |
| out.write_Object(null); |
| return; |
| |
| } else if (obj instanceof org.omg.CORBA.Object) { |
| objref = (org.omg.CORBA.Object) obj; |
| |
| } else if (obj instanceof Remote) { |
| try { |
| objref = (javax.rmi.CORBA.Stub) PortableRemoteObject |
| .toStub((java.rmi.Remote) obj); |
| |
| } catch (java.rmi.NoSuchObjectException ex) { |
| } |
| |
| if (objref == null) { |
| |
| try { |
| PortableRemoteObject.exportObject((java.rmi.Remote) obj); |
| objref = (javax.rmi.CORBA.Stub) PortableRemoteObject |
| .toStub((java.rmi.Remote) obj); |
| } catch (java.rmi.RemoteException ex) { |
| throw (MARSHAL) new MARSHAL("cannot convert Remote to Object").initCause(ex); |
| } |
| } |
| |
| } else { |
| throw new MARSHAL( |
| "object is neither Remote nor org.omg.CORBA.Object: " |
| + obj.getClass().getName()); |
| } |
| |
| out.write_Object(objref); |
| } |
| |
| public void writeAbstractObject(org.omg.CORBA.portable.OutputStream out, Object obj) { |
| logger.finer("writeAbstractObject.1 " + " out=" + out); |
| |
| if (obj instanceof org.omg.CORBA.Object || obj instanceof Serializable) { |
| |
| // skip // |
| |
| } else if (obj instanceof Remote) { |
| org.omg.CORBA.Object objref = null; |
| |
| try { |
| objref = (org.omg.CORBA.Object) PortableRemoteObject |
| .toStub((Remote) obj); |
| |
| } catch (java.rmi.NoSuchObjectException ex) { |
| } |
| |
| if (objref == null) { |
| try { |
| PortableRemoteObject.exportObject((Remote) obj); |
| objref = (org.omg.CORBA.Object) PortableRemoteObject |
| .toStub((Remote) obj); |
| } catch (RemoteException ex) { |
| throw (MARSHAL) new MARSHAL("unable to export object").initCause(ex); |
| } |
| } |
| obj = objref; |
| } |
| |
| org.omg.CORBA_2_3.portable.OutputStream out_ = (org.omg.CORBA_2_3.portable.OutputStream) out; |
| |
| logger.finer("writeAbstractObject.2 " + " out=" + out); |
| |
| out_.write_abstract_interface(obj); |
| } |
| |
| @SuppressWarnings("unchecked") |
| protected java.util.Map<Remote, Tie> tie_map() { |
| return RMIState.current().tie_map; |
| } |
| |
| public void registerTarget(Tie tie, Remote obj) { |
| if (obj == null) |
| throw new IllegalArgumentException("remote object is null"); |
| |
| tie.setTarget(obj); |
| tie_map().put(obj, tie); |
| |
| // log.info("exported instance of "+obj.getClass()+" in |
| // "+RMIState.current().getName()); |
| } |
| |
| public Tie getTie(Remote obj) { |
| if (obj == null) |
| return null; |
| |
| return tie_map().get(obj); |
| } |
| |
| public ValueHandler createValueHandler() { |
| return ValueHandlerImpl.get(); |
| } |
| |
| public String getCodebase(@SuppressWarnings("rawtypes") Class clz) { |
| if (clz == null) |
| return null; |
| |
| if (clz.isArray()) |
| return getCodebase(clz.getComponentType()); |
| |
| if (clz.isPrimitive()) |
| return null; |
| |
| ClassLoader theLoader = clz.getClassLoader(); |
| |
| // ignore system classes |
| if (theLoader == null) |
| return null; |
| |
| // ignore J2SE base class loader |
| if (theLoader == (Object.class).getClassLoader()) |
| return null; |
| |
| // ignore standard extensions |
| if (theLoader == BEST_GUESS_AT_EXTENSION_CLASS_LOADER) |
| return null; |
| |
| RMIState state = RMIState.current(); |
| ClassLoader stateLoader = state.getClassLoader(); |
| |
| try { |
| // is the class loaded with the stateLoader? |
| if (clz.equals(stateLoader.loadClass(clz.getName()))) { |
| java.net.URL codebaseURL = state.getCodeBase(); |
| |
| if (codebaseURL != null) { |
| logger.finer("class " + clz.getName() + " => " |
| + codebaseURL); |
| |
| // System.out.println ("class "+clz.getName()+" => |
| // "+codebaseURL); |
| return codebaseURL.toString(); |
| } |
| } |
| } catch (ClassNotFoundException ex) { |
| // ignore |
| } |
| |
| return AccessController.doPrivileged(new GetSystemPropertyAction("java.rmi.server.codebase")); |
| } |
| |
| static class SecMan extends java.rmi.RMISecurityManager { |
| @SuppressWarnings("rawtypes") |
| public Class[] getClassContext() { |
| return super.getClassContext(); |
| } |
| } |
| |
| private static SecMan getSecMan() { |
| try { |
| return AccessController.doPrivileged(new PrivilegedExceptionAction<SecMan>() { |
| public SecMan run() { |
| return new SecMan(); |
| } |
| }); |
| } catch (PrivilegedActionException e) { |
| throw new RuntimeException(e); |
| } |
| |
| } |
| |
| @SuppressWarnings("rawtypes") |
| public Class loadClass(String name, String codebase, ClassLoader loader) |
| throws ClassNotFoundException { |
| try { |
| return loadClass0(name, codebase, loader); |
| } catch (ClassNotFoundException ex) { |
| logger.log(Level.FINER, "cannot load from " + codebase + " " + |
| ex.getMessage(), ex); |
| throw ex; |
| } |
| } |
| |
| static public Class<?> loadClass0(String name, String codebase, ClassLoader loader) |
| throws ClassNotFoundException { |
| |
| try { |
| return ProviderLocator.loadClass(name, null, loader); |
| } catch (ClassNotFoundException e) { |
| //skip |
| } |
| Class<?> result = null; |
| |
| ClassLoader stackLoader = null; |
| ClassLoader thisLoader = Util.class.getClassLoader(); |
| Class<?>[] stack = _secman.getClassContext(); |
| for (int i = 1; i < stack.length; i++) { |
| ClassLoader testLoader = stack[i].getClassLoader(); |
| if (testLoader != null && testLoader != thisLoader) { |
| stackLoader = thisLoader; |
| break; |
| } |
| } |
| |
| if (stackLoader != null) { |
| try { |
| result = stackLoader.loadClass(name); |
| } catch (ClassNotFoundException ex) { |
| // skip // |
| } |
| |
| if (result != null) { |
| return result; |
| } |
| } |
| |
| // try loading using our loader, just in case we really were loaded |
| // using the same classloader the delegate is in. |
| if (thisLoader != null) { |
| try { |
| result = thisLoader.loadClass(name); |
| } catch (ClassNotFoundException ex) { |
| // skip // |
| } |
| |
| if (result != null) { |
| return result; |
| } |
| } |
| |
| if (codebase != null && !"".equals(codebase) |
| && !Boolean.getBoolean("java.rmi.server.useCodeBaseOnly")) { |
| logger.finer("trying RMIClassLoader"); |
| try (URLClassLoader url_loader = new URLClassLoader(new URL[]{new URL(codebase)}, loader)) { |
| result = url_loader.loadClass(name); |
| } catch (ClassNotFoundException ex) { |
| logger.log(Level.FINER, "RMIClassLoader says " + ex.getMessage(), ex); |
| } catch (MalformedURLException ex) { |
| logger.log(Level.FINER, "RMIClassLoader says " + ex.getMessage(), ex); |
| logger.finer("FAILED class download " + name + " from " + codebase + " " + ex.getMessage()); |
| } catch (RuntimeException ex) { |
| logger.log(Level.FINER, "FAILED class download " + name + " from " + codebase + " " + ex.getMessage(), ex); |
| } catch (IOException unimportant) { |
| } |
| |
| if (result != null) { |
| return result; |
| } |
| |
| } else { |
| |
| codebase = (String) AccessController.doPrivileged(new GetSystemPropertyAction("java.rmi.server.codebase")); |
| |
| if (codebase != null) { |
| try { |
| result = java.rmi.server.RMIClassLoader.loadClass(codebase, |
| name); |
| } catch (ClassNotFoundException ex) { |
| // skip // |
| } catch (MalformedURLException ex) { |
| // skip // |
| } |
| |
| if (result != null) { |
| return result; |
| } |
| } |
| } |
| |
| if (loader == null) { |
| loader = getContextClassLoader(); |
| } |
| |
| try { |
| result = loader.loadClass(name); |
| } catch (ClassNotFoundException ex) { |
| logger.log(Level.FINER, "LocalLoader says " + ex.getMessage(), ex); |
| } |
| |
| if (result != null) { |
| return result; |
| } |
| |
| throw new ClassNotFoundException(name); |
| } |
| |
| public boolean isLocal(Stub stub) throws RemoteException { |
| try { |
| if (stub instanceof RMIStub) { |
| return true; |
| } else { |
| return stub._is_local(); |
| } |
| } catch (org.omg.CORBA.SystemException ex) { |
| throw mapSystemException(ex); |
| } |
| } |
| |
| public RemoteException wrapException(Throwable ex) { |
| if (ex instanceof Error) { |
| return new java.rmi.ServerError(ex.getMessage(), (Error) ex); |
| |
| } else if (ex instanceof RemoteException) { |
| return new java.rmi.ServerException(ex.getMessage(), (Exception) ex); |
| |
| } else if (ex instanceof org.omg.CORBA.portable.UnknownException) { |
| org.omg.CORBA.portable.UnknownException uex = (org.omg.CORBA.portable.UnknownException) ex; |
| |
| return new java.rmi.ServerError( |
| ex.getMessage(), |
| (uex.originalEx instanceof Error ? (Error) uex.originalEx |
| : new Error("[OTHER EXCEPTION] " + ex.getMessage()))); |
| |
| } else if (ex instanceof org.omg.CORBA.SystemException) { |
| return mapSystemException((org.omg.CORBA.SystemException) ex); |
| |
| } else if (ex instanceof RuntimeException) { |
| throw (RuntimeException) ex; |
| |
| } else { |
| return new java.rmi.RemoteException(ex.getMessage(), ex); |
| } |
| } |
| |
| static ClassLoader getContextClassLoader() { |
| return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { |
| public ClassLoader run() { |
| return Thread.currentThread().getContextClassLoader(); |
| } |
| }); |
| } |
| |
| static ClassLoader getClassLoader(final Class<?> clz) { |
| if (System.getSecurityManager() == null) { |
| return clz.getClassLoader(); |
| } else { |
| return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { |
| public ClassLoader run() { |
| return clz.getClassLoader(); |
| } |
| }); |
| } |
| } |
| |
| static Object copyRMIStub(RMIStub stub) throws RemoteException { |
| ClassLoader loader = getContextClassLoader(); |
| |
| if (getClassLoader(stub._descriptor.type) == loader) { |
| return stub; |
| } |
| |
| RemoteDescriptor desc = stub._descriptor; |
| |
| Class<?> targetClass; |
| |
| try { |
| targetClass = Util.loadClass(desc.type.getName(), stub |
| ._get_codebase(), loader); |
| } catch (ClassNotFoundException ex) { |
| logger.log(Level.FINER, "copyRMIStub exception (current loader is: " + loader |
| + ") " + ex.getMessage(), ex); |
| throw new RemoteException("Class not found", ex); |
| } |
| |
| return PortableRemoteObjectImpl.narrow1(RMIState.current(), stub, |
| targetClass); |
| } |
| |
| static boolean copy_with_corba = false; |
| |
| /** |
| * Copy a single object, maintaining internal reference integrity. |
| * <p/> |
| * This is done by writing and reading the object to/from a temporary |
| * stream. As such, this should be called after the receiving context's |
| * class-loaders etc. have been set up. |
| */ |
| public Object copyObject(Object obj, org.omg.CORBA.ORB orb) |
| throws RemoteException { |
| if (obj == null) |
| return null; |
| |
| if (orb == null) |
| throw new NullPointerException(); |
| |
| if (obj instanceof String || obj instanceof Number) |
| return obj; |
| |
| if (obj instanceof RMIStub) { |
| return copyRMIStub((RMIStub) obj); |
| } |
| |
| /* |
| * try { org.omg.CORBA_2_3.portable.OutputStream out = |
| * (org.omg.CORBA_2_3.portable.OutputStream) orb.create_output_stream |
| * (); |
| * |
| * out.write_value ((java.io.Serializable) obj); |
| * |
| * org.omg.CORBA_2_3.portable.InputStream in = |
| * (org.omg.CORBA_2_3.portable.InputStream) out.create_input_stream (); |
| * |
| * return in.read_value (); |
| * } catch (org.omg.CORBA.SystemException ex) { throw |
| * mapSystemException (ex); } |
| */ |
| try { |
| TypeRepository rep = RMIState.current().repo; |
| CopyState state = new CopyState(rep); |
| return state.copy(obj); |
| } catch (CopyRecursionException ex) { |
| throw new MarshalException("unable to resolve recursion", ex); |
| } catch (org.omg.CORBA.SystemException ex) { |
| throw mapSystemException(ex); |
| } |
| |
| } |
| |
| static final Object READ_SERIALIZABLE_KEY = new Object(); |
| |
| /** |
| * Copy an array of objects, maintaining internal reference integrity. |
| * <p/> |
| * This is done by writing and reading the object array to/from a temporary |
| * stream. As such, this should be called after the receiving context's |
| * class-loaders etc. have been set up. |
| */ |
| public Object[] copyObjects(Object[] objs, org.omg.CORBA.ORB orb) |
| throws RemoteException { |
| |
| if (objs == null || orb == null) |
| throw new NullPointerException(); |
| |
| if (objs.length == 0) |
| return objs; |
| |
| try { |
| |
| TypeRepository rep = RMIState.current().repo; |
| CopyState state = new CopyState(rep); |
| try { |
| return (Object[]) state.copy(objs); |
| } catch (CopyRecursionException ex) { |
| throw new MarshalException("unable to resolve recursion", ex); |
| } |
| |
| /* |
| * int length = objs.length; |
| * |
| * for (int i = 0; i < length; i++) { |
| * |
| * Object val = objs[i]; |
| * |
| * if (val == null || val instanceof String || val instanceof |
| * Number) { // do nothing, just leave the object in place // |
| * } else if (val instanceof RMIStub) { objs[i] = |
| * copyRMIStub((RMIStub)val); |
| * } else { if (orb == null) { orb = RMIState.current().getORB(); } |
| * |
| * if (out == null) { out = |
| * (org.omg.CORBA_2_3.portable.OutputStream) orb |
| * .create_output_stream(); } |
| * |
| * out.write_value((java.io.Serializable) val); objs[i] = |
| * READ_SERIALIZABLE_KEY; } |
| * } |
| * |
| * if (out != null) { |
| * |
| * org.omg.CORBA_2_3.portable.InputStream in = |
| * (org.omg.CORBA_2_3.portable.InputStream) out |
| * .create_input_stream(); |
| * |
| * for (int i = 0; i < length; i++) { if (objs[i] == |
| * READ_SERIALIZABLE_KEY) { objs[i] = in.read_value(); } } } |
| * |
| * return objs; |
| */ |
| |
| } catch (org.omg.CORBA.SystemException ex) { |
| throw mapSystemException(ex); |
| } |
| } |
| |
| public void unexportObject(Remote obj) |
| throws java.rmi.NoSuchObjectException { |
| if (obj == null) |
| return; |
| |
| java.util.Map<Remote, Tie> tie_map = tie_map(); |
| |
| if (tie_map == null) |
| return; |
| |
| Tie tie = tie_map.remove(obj); |
| |
| if (tie == null) { |
| logger.fine("unexporting unknown instance of " |
| + obj.getClass().getName() + " from " |
| + RMIState.current().getName()); |
| return; |
| } else { |
| logger.finer("unexporting instance of " + obj.getClass().getName() |
| + " from " + RMIState.current().getName()); |
| } |
| |
| tie.deactivate(); |
| } |
| } |