1 /* 2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.jndi.toolkit.corba; 27 28 // Needed for RMI/IIOP 29 import java.rmi.Remote; 30 31 import java.lang.reflect.Method; 32 import java.lang.reflect.InvocationTargetException; 33 import java.util.Hashtable; 34 import java.util.Properties; 35 import java.util.Enumeration; 36 37 import org.omg.CORBA.ORB; 38 39 import javax.naming.*; 40 41 import com.sun.jndi.cosnaming.CNCtx; 42 43 /** 44 * Contains utilities for performing CORBA-related tasks: 45 * 1. Get the org.omg.CORBA.Object for a java.rmi.Remote object. 46 * 2. Create an ORB to use for a given host/port, and environment properties. 47 * 48 * @author Simon Nash 49 * @author Bryan Atsatt 50 */ 51 52 public class CorbaUtils { 53 /** 54 * Returns the CORBA object reference associated with a Remote 55 * object by using the javax.rmi.CORBA package. 56 *<p> 57 * Use reflection to avoid hard dependencies on javax.rmi.CORBA package. 58 * This method effective does the following: 59 *<blockquote><pre> 60 * java.lang.Object stub; 61 * try { 62 * stub = PortableRemoteObject.toStub(remoteObj); 63 * } catch (Exception e) { 64 * throw new ConfigurationException("Object not exported or not found"); 65 * } 66 * if (!(stub instanceof javax.rmi.CORBA.Stub)) { 67 * return null; // JRMP impl or JRMP stub 68 * } 69 * try { 70 * ((javax.rmi.CORBA.Stub)stub).connect(orb); // try to connect IIOP stub 71 * } catch (RemoteException e) { 72 * // ignore 'already connected' error 73 * } 74 * return (javax.rmi.CORBA.Stub)stub; 75 * 76 * @param remoteObj The non-null remote object for 77 * @param orb The non-null ORB to connect the remote object to 78 * @return The CORBA Object for remoteObj; null if <tt>remoteObj</tt> 79 * is a JRMP implementation or JRMP stub. 80 * @exception ClassNotFoundException The RMI-IIOP package is not available 81 * @exception ConfigurationException The CORBA Object cannot be obtained 82 * because of configuration problems. 83 */ remoteToCorba(Remote remoteObj, ORB orb)84 public static org.omg.CORBA.Object remoteToCorba(Remote remoteObj, ORB orb) 85 throws ClassNotFoundException, ConfigurationException { 86 synchronized (CorbaUtils.class) { 87 if (toStubMethod == null) { 88 initMethodHandles(); 89 } 90 } 91 92 // First, get remoteObj's stub 93 94 // javax.rmi.CORBA.Stub stub = PortableRemoteObject.toStub(remoteObj); 95 96 java.lang.Object stub; 97 98 try { 99 stub = toStubMethod.invoke(null, new java.lang.Object[]{remoteObj}); 100 101 } catch (InvocationTargetException e) { 102 Throwable realException = e.getTargetException(); 103 // realException.printStackTrace(); 104 105 ConfigurationException ce = new ConfigurationException( 106 "Problem with PortableRemoteObject.toStub(); object not exported or stub not found"); 107 ce.setRootCause(realException); 108 throw ce; 109 110 } catch (IllegalAccessException e) { 111 ConfigurationException ce = new ConfigurationException( 112 "Cannot invoke javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote)"); 113 114 ce.setRootCause(e); 115 throw ce; 116 } 117 118 // Next, make sure that the stub is javax.rmi.CORBA.Stub 119 120 if (!corbaStubClass.isInstance(stub)) { 121 return null; // JRMP implementation or JRMP stub 122 } 123 124 // Next, make sure that the stub is connected 125 // Invoke stub.connect(orb) 126 try { 127 connectMethod.invoke(stub, new java.lang.Object[]{orb}); 128 129 } catch (InvocationTargetException e) { 130 Throwable realException = e.getTargetException(); 131 // realException.printStackTrace(); 132 133 if (!(realException instanceof java.rmi.RemoteException)) { 134 ConfigurationException ce = new ConfigurationException( 135 "Problem invoking javax.rmi.CORBA.Stub.connect()"); 136 ce.setRootCause(realException); 137 throw ce; 138 } 139 // ignore RemoteException because stub might have already 140 // been connected 141 } catch (IllegalAccessException e) { 142 ConfigurationException ce = new ConfigurationException( 143 "Cannot invoke javax.rmi.CORBA.Stub.connect()"); 144 ce.setRootCause(e); 145 throw ce; 146 } 147 // Finally, return stub 148 return (org.omg.CORBA.Object)stub; 149 } 150 151 /** 152 * Get ORB using given server and port number, and properties from environment. 153 * 154 * @param server Possibly null server; if null means use default; 155 * For applet, it is the applet host; for app, it is localhost. 156 * @param port Port number, -1 means default port 157 * @param env Possibly null environment. Contains environment properties. 158 * Could contain ORB itself; or applet used for initializing ORB. 159 * Use all String properties from env for initializing ORB 160 * @return A non-null ORB. 161 */ getOrb(String server, int port, Hashtable<?,?> env)162 public static ORB getOrb(String server, int port, Hashtable<?,?> env) { 163 // See if we can get info from environment 164 Properties orbProp; 165 166 // Extract any org.omg.CORBA properties from environment 167 if (env != null) { 168 if (env instanceof Properties) { 169 // Already a Properties, just clone 170 orbProp = (Properties) env.clone(); 171 } else { 172 // Get all String properties 173 Enumeration<?> envProp; 174 orbProp = new Properties(); 175 for (envProp = env.keys(); envProp.hasMoreElements();) { 176 String key = (String)envProp.nextElement(); 177 Object val = env.get(key); 178 if (val instanceof String) { 179 orbProp.put(key, val); 180 } 181 } 182 } 183 } else { 184 orbProp = new Properties(); 185 } 186 187 if (server != null) { 188 orbProp.put("org.omg.CORBA.ORBInitialHost", server); 189 } 190 if (port >= 0) { 191 orbProp.put("org.omg.CORBA.ORBInitialPort", ""+port); 192 } 193 194 // Get Applet from environment 195 if (env != null) { 196 Object applet = env.get(Context.APPLET); 197 if (applet != null) { 198 // Create ORBs for an applet 199 return initAppletORB(applet, orbProp); 200 } 201 } 202 203 // Create ORBs using orbProp for a standalone application 204 return ORB.init(new String[0], orbProp); 205 } 206 207 /** 208 * Check whether object factory code base is trusted. 209 * Classes may only be loaded from an arbitrary URL code base when 210 * the system property com.sun.jndi.rmi.object.trustURLCodebase 211 * has been set to "true". 212 */ isObjectFactoryTrusted(Object obj)213 public static boolean isObjectFactoryTrusted(Object obj) 214 throws NamingException { 215 216 // Extract Reference, if possible 217 Reference ref = null; 218 if (obj instanceof Reference) { 219 ref = (Reference) obj; 220 } else if (obj instanceof Referenceable) { 221 ref = ((Referenceable)(obj)).getReference(); 222 } 223 224 if (ref != null && ref.getFactoryClassLocation() != null && 225 !CNCtx.trustURLCodebase) { 226 throw new ConfigurationException( 227 "The object factory is untrusted. Set the system property" + 228 " 'com.sun.jndi.cosnaming.object.trustURLCodebase' to 'true'."); 229 } 230 return true; 231 } 232 233 /** 234 * This method returns a new ORB instance for the given applet 235 * without creating a static dependency on java.applet. 236 */ initAppletORB(Object applet, Properties orbProp)237 private static ORB initAppletORB(Object applet, Properties orbProp) { 238 try { 239 Class<?> appletClass = Class.forName("java.applet.Applet", true, null); 240 if (!appletClass.isInstance(applet)) { 241 throw new ClassCastException(applet.getClass().getName()); 242 } 243 244 // invoke the static method ORB.init(applet, orbProp); 245 Method method = ORB.class.getMethod("init", appletClass, Properties.class); 246 return (ORB) method.invoke(null, applet, orbProp); 247 } catch (ClassNotFoundException e) { 248 // java.applet.Applet doesn't exist and the applet parameter is 249 // non-null; so throw CCE 250 throw new ClassCastException(applet.getClass().getName()); 251 } catch (NoSuchMethodException e) { 252 throw new AssertionError(e); 253 } catch (InvocationTargetException e) { 254 Throwable cause = e.getCause(); 255 if (cause instanceof RuntimeException) { 256 throw (RuntimeException) cause; 257 } else if (cause instanceof Error) { 258 throw (Error) cause; 259 } 260 throw new AssertionError(e); 261 } catch (IllegalAccessException iae) { 262 throw new AssertionError(iae); 263 } 264 } 265 266 // Fields used for reflection of RMI-IIOP 267 private static Method toStubMethod = null; 268 private static Method connectMethod = null; 269 private static Class<?> corbaStubClass = null; 270 /** 271 * Initializes reflection method handles for RMI-IIOP. 272 * @exception ClassNotFoundException javax.rmi.CORBA.* not available 273 */ initMethodHandles()274 private static void initMethodHandles() throws ClassNotFoundException { 275 // Get javax.rmi.CORBA.Stub class 276 corbaStubClass = Class.forName("javax.rmi.CORBA.Stub"); 277 278 // Get javax.rmi.CORBA.Stub.connect(org.omg.CORBA.ORB) method 279 280 try { 281 connectMethod = corbaStubClass.getMethod("connect", 282 new Class<?>[] {org.omg.CORBA.ORB.class}); 283 } catch (NoSuchMethodException e) { 284 throw new IllegalStateException( 285 "No method definition for javax.rmi.CORBA.Stub.connect(org.omg.CORBA.ORB)"); 286 } 287 288 // Get javax.rmi.PortableRemoteObject class 289 Class<?> proClass = Class.forName("javax.rmi.PortableRemoteObject"); 290 291 // Get javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote) method 292 try { 293 toStubMethod = proClass.getMethod("toStub", 294 new Class<?>[] {java.rmi.Remote.class}); 295 296 } catch (NoSuchMethodException e) { 297 throw new IllegalStateException( 298 "No method definition for javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote)"); 299 } 300 } 301 } 302