Merge branch 'reuse_remote_naming_contexts' into 'ibm-trunk'
Reuse remote naming contexts
See merge request !56
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/BindingIteratorImpl.java b/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/BindingIteratorImpl.java
index c71dc79..3d4322b 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/BindingIteratorImpl.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/BindingIteratorImpl.java
@@ -4,6 +4,7 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
import org.apache.yoko.orb.CosNaming.tnaming2.NamingContextImpl.BoundObject;
import org.apache.yoko.orb.spi.naming.RemoteAccess;
@@ -22,6 +23,8 @@
private static final long serialVersionUID = 1L;
private static final class Core extends BindingIteratorPOA {
+ private static final AtomicLong NEXT_ID = new AtomicLong();
+ private final long instanceId = NEXT_ID.getAndIncrement();
// the iterator use to access the bindings
private final Iterator<BoundObject> iterator;
@@ -33,6 +36,11 @@
public Core(Collection<BoundObject> boundObjects) {
this.iterator = (new ArrayList<BoundObject>(boundObjects)).iterator();
}
+
+ private byte[] getServantId() {
+ return ("BindingIterator#" + instanceId).getBytes();
+ }
+
/**
* Return the next object in the iteration sequence.
* @param b The BindingHolder used to return the next item. If we've
@@ -91,7 +99,7 @@
public POAServant(POA poa, Core core) throws Exception {
this.poa = poa;
this.core = core;
- poa.activate_object(this);
+ poa.activate_object_with_id(core.getServantId(), this);
}
/**
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/NamingContextBase.java b/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/NamingContextBase.java
index fa92761..94de6ea 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/NamingContextBase.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/NamingContextBase.java
@@ -72,7 +72,7 @@
* must already be bound in the context tree.
* @param obj The object to be bound.
*/
- public void bind(NameComponent[] n, org.omg.CORBA.Object obj)
+ public void bind(NameComponent[] n, org.omg.CORBA.Object obj)
throws NotFound, CannotProceed, InvalidName, AlreadyBound {
// perform various name validations
validateName(n);
@@ -270,7 +270,7 @@
NamingContext context = resolveContext(n[0]);
NameComponent[] subName = extractSubName(n);
- // now pass this along to the next context for the real bind operation.
+ // now pass this along to the next context for the real resolve operation.
return context.resolve(subName);
} else {
NameComponent name = n[0];
@@ -280,9 +280,9 @@
// Object was not found
throw new NotFound(NotFoundReason.missing_node, n);
}
- if (obj instanceof Resolvable) {
+ if (obj instanceof Resolvable) {
return ((Resolvable)obj).resolve();
- } else {
+ } else {
return obj;
}
}
@@ -578,7 +578,7 @@
throw new NotFound(NotFoundReason.not_context, new NameComponent[]{name});
}
- // in theory, this is a naming context. Narrow it an return. Any
+ // in theory, this is a naming context. Narrow it and return. Any
// errors just become a NotFound exception
try {
return NamingContextHelper.narrow(resolvedReference);
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/NamingContextImpl.java b/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/NamingContextImpl.java
index 0164b17..ff20584 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/NamingContextImpl.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/CosNaming/tnaming2/NamingContextImpl.java
@@ -1,9 +1,12 @@
package org.apache.yoko.orb.CosNaming.tnaming2;
import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicLong;
import org.apache.yoko.orb.spi.naming.RemoteAccess;
+import org.apache.yoko.orb.util.UnmodifiableEnumMap;
import org.omg.CORBA.INTERNAL;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.NO_PERMISSION;
@@ -25,24 +28,44 @@
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.Servant;
+import org.omg.PortableServer.POAPackage.ObjectNotActive;
public final class NamingContextImpl extends LocalObject implements NamingContextExt, RemotableObject {
private static final long serialVersionUID = 1L;
+ private static final class ServantCreationLock {
+ }
+
private static final class Core extends NamingContextBase {
- // the bindings maintained by this context
+ private static final AtomicLong NEXT_ID = new AtomicLong();
+
+ /** Unique number for this core */
+ private final long instanceId = NEXT_ID.getAndIncrement();
+
+ /** the unique ids for this context's servants (one per remote access level) */
+ @SuppressWarnings("serial")
+ private final Map<RemoteAccess, String> servantIds = new UnmodifiableEnumMap<RemoteAccess, String>(RemoteAccess.class) {
+ public String computeValueFor(RemoteAccess key) {
+ return "NamingContext#" + instanceId + "$" + key;
+ }
+ };
+
+ /** the bindings maintained by this context */
private final HashMap<BindingKey, BoundObject> bindings = new HashMap<BindingKey, BoundObject>();
- // the root context object
+
+ /** the root context object */
private final org.omg.CORBA.Object rootContext;
+ private Core(org.omg.CORBA.Object rootContext) throws Exception {
+ this.rootContext = rootContext;
+ }
+
/**
- * Construct a TransientNamingContext subcontext.
- * @param orb The orb this context is associated with.
- * @param poa The POA the root context is activated under.
- * @param root The root context.
+ * Get the servant id to use for this context with the specified remote
+ * access level
*/
- Core(org.omg.CORBA.Object root) throws Exception {
- rootContext = root;
+ private byte[] getServantId(RemoteAccess access) {
+ return servantIds.get(access).getBytes();
}
// abstract methods part of the interface contract that the
@@ -204,6 +227,11 @@
return (Objects.equals(name.id, otherKey.name.id) && Objects.equals(name.kind, otherKey.name.kind));
}
+
+ @Override
+ public String toString() {
+ return "" + name;
+ }
}
}
@@ -224,11 +252,11 @@
final NamingContextBase core;
final POA poa;
- protected POAServant(NamingContextImpl localContext, Core core, POA poa) throws Exception {
+ protected POAServant(NamingContextImpl localContext, Core core, POA poa, byte[] servantId) throws Exception {
this.localContext = localContext;
this.core = core;
this.poa = poa;
- poa.activate_object(this);
+ poa.activate_object_with_id(servantId, this);
}
abstract Servant convertLocalContextToRemoteContext(NamingContextImpl o) throws Exception;
@@ -268,9 +296,9 @@
private static final class ReadOnly extends POAServant {
ReadOnly(NamingContextImpl localContext, Core core, POA poa) throws Exception {
- super(localContext, core, poa);
+ super(localContext, core, poa, core.getServantId(RemoteAccess.readOnly));
}
-
+
private SystemException newSystemException() {
return new NO_PERMISSION();
}
@@ -303,7 +331,7 @@
private static final class ReadWrite extends POAServant {
ReadWrite(NamingContextImpl localContext, Core core, POA poa) throws Exception {
- super(localContext, core, poa);
+ super(localContext, core, poa, core.getServantId(RemoteAccess.readWrite));
}
@Override
@@ -370,10 +398,18 @@
this.boundObject = boundObject;
this.type = type;
}
+
+ @Override
+ public String toString() {
+ return name + "->" + boundObject;
+ }
}
private final Core core;
+ /** lock for servant creation */
+ private final Object servantCreationLock = new ServantCreationLock();
+
public NamingContextImpl() throws Exception {
core = new Core(this);
}
@@ -434,7 +470,18 @@
@Override
public Servant getServant(POA poa, RemoteAccess remoteAccess) throws Exception {
- return POAServant.create(this, core, poa, remoteAccess);
+ byte[] sid = core.getServantId(remoteAccess);
+
+ // synchronize around creation to avoid a race
+ synchronized (servantCreationLock) {
+ // check whether the servant needs to be created
+ try {
+ return poa.id_to_servant(sid);
+ } catch (ObjectNotActive expected) {
+ // guaranteed to be the unique creator-thread for this servant
+ return POAServant.create(this, core, poa, remoteAccess);
+ }
+ }
}
@Override
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/spi/naming/NameServiceInitializer.java b/yoko-core/src/main/java/org/apache/yoko/orb/spi/naming/NameServiceInitializer.java
index a20b4aa..ef9049b 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/spi/naming/NameServiceInitializer.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/spi/naming/NameServiceInitializer.java
@@ -27,8 +27,8 @@
public class NameServiceInitializer extends LocalObject implements ORBInitializer {
/** The property name to use to initialize an ORB with this initializer. */
public static final String NS_ORB_INIT_PROP = ORBInitializer.class.getName() + "Class." + NameServiceInitializer.class.getName();
- /**
- * The name of this name service, as used with <code>corbaloc:</code> URLs
+ /**
+ * The name of this name service, as used with <code>corbaloc:</code> URLs
* and with calls to {@link ORB#resolve_initial_references(String)}.
*/
public static final String SERVICE_NAME = "NameService";
@@ -36,15 +36,31 @@
/**
* The POA name this name service will use to activate contexts.
* The name service will first try <code>rootPoa.find_POA()</code>
- * to find the POA with this name. If that returns null, it will
- * call <code>rootPoa.create_POA()</code> to create the POA with
+ * to find the POA with this name. If that returns null, it will
+ * call <code>rootPoa.create_POA()</code> to create the POA with
* this name.
*/
public static final String POA_NAME = "NameServicePOA";
- /**
+ /**
+ * The policies required for the NameService POA. Users providing
+ * the NameService POA must include these policies when creating
+ * the POA. If creation is to be left to this initializer, these
+ * policies will be used automatically.
+ * @param rootPOA the root POA for the ORB in use
+ * @return a new Policy array object, owned by the caller
+ */
+ public static final Policy[] createPOAPolicies(POA rootPOA) {
+ return new Policy[] {
+ rootPOA.create_lifespan_policy(LifespanPolicyValue.TRANSIENT),
+ rootPOA.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID),
+ rootPOA.create_servant_retention_policy(ServantRetentionPolicyValue.RETAIN)
+ };
+ }
+
+ /**
* The ORB argument that specifies remote accessibility of this name service.
- * The next argument must be one of these literal string values:
+ * The next argument must be one of these literal string values:
* <ul>
* <li><code>"</code>{@link #readOnly}<code>"</code></li>
* <li><code>"</code>{@link #readWrite}<code>"</code></li>
@@ -57,7 +73,7 @@
private static final long serialVersionUID = 1L;
private RemoteAccess remoteAccess = readWrite;
-
+
@Override
public void pre_init(ORBInitInfo info) {
try {
@@ -81,7 +97,7 @@
@Override
public void post_init(ORBInitInfo info) {
try {
-
+
final POA rootPOA = (POA) info.resolve_initial_references("RootPOA");
final NamingContextImpl local = (NamingContextImpl) info.resolve_initial_references("NameService");
final String serviceName = getServiceName(info);
@@ -97,16 +113,16 @@
try {
rootPOA.the_POAManager().activate();
-
+
final POA nameServicePOA = findOrCreatePOA(rootPOA);
nameServicePOA.the_POAManager().activate();
final Servant nameServant = local.getServant(nameServicePOA, remoteAccess);
-
+
// return the context stub via the object holder
obj.value = nameServant._this_object();
// return true via the boolean holder
- // to tell the boot manager to re-use
+ // to tell the boot manager to re-use
// this result so we only get called once
add.value = true;
} catch (Exception e) {
@@ -118,11 +134,7 @@
try {
return rootPOA.find_POA(POA_NAME, true);
} catch (AdapterNonExistent e) {
- final Policy[] policies = {
- rootPOA.create_lifespan_policy(LifespanPolicyValue.TRANSIENT),
- rootPOA.create_id_assignment_policy(IdAssignmentPolicyValue.SYSTEM_ID),
- rootPOA.create_servant_retention_policy(ServantRetentionPolicyValue.RETAIN)
- };
+ final Policy[] policies = createPOAPolicies(rootPOA);
return rootPOA.create_POA(POA_NAME, null, policies);
}
}
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/util/UnmodifiableEnumMap.java b/yoko-core/src/main/java/org/apache/yoko/orb/util/UnmodifiableEnumMap.java
new file mode 100644
index 0000000..f241a93
--- /dev/null
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/util/UnmodifiableEnumMap.java
@@ -0,0 +1,45 @@
+package org.apache.yoko.orb.util;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.Map;
+import java.util.Set;
+
+public abstract class UnmodifiableEnumMap<K extends Enum<K>, V> extends EnumMap<K, V> {
+ private static final long serialVersionUID = 1L;
+
+ public UnmodifiableEnumMap(Class<K> keyType) {
+ super(keyType);
+ // initialise all values up front to avoid races later
+ for(K key : keyType.getEnumConstants())
+ super.put(key, computeValueFor(key));
+ }
+
+ protected abstract V computeValueFor(K key);
+
+ @Override
+ public final V remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public final V put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public final void putAll(Map<? extends K, ? extends V> m) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public final Set<K> keySet() {
+ return Collections.unmodifiableSet(super.keySet());
+ }
+
+ @Override
+ public final Collection<V> values() {
+ return Collections.unmodifiableCollection(super.values());
+ }
+}
diff --git a/yoko-core/src/test/java/org/apache/yoko/AbstractOrbTestBase.java b/yoko-core/src/test/java/org/apache/yoko/AbstractOrbTestBase.java
index 801ce71..84a22f8 100644
--- a/yoko-core/src/test/java/org/apache/yoko/AbstractOrbTestBase.java
+++ b/yoko-core/src/test/java/org/apache/yoko/AbstractOrbTestBase.java
@@ -37,7 +37,7 @@
* It also sets the java.endorsed.dirs property and launches the client process.
*
* Currently, the client waits for the server to create a file containing an IOR. This
- * is used to delay the client until the server has started. the setWaitFile(File) method
+ * is used to delay the client until the server has started. the setWaitFile(File) method
* can be used to set the name of this file, which varies in the ORB tests.
*/
public class AbstractOrbTestBase extends TestCase {
@@ -45,15 +45,15 @@
protected JavaProcess server, client;
protected File waitForFile;
int waitForFileTimeout = 10000;
-
+
public AbstractOrbTestBase() {
super();
}
-
+
public AbstractOrbTestBase(String name) {
super(name);
}
-
+
protected void setUp() throws Exception {
super.setUp();
processManager = new ProcessManager(Registry.REGISTRY_PORT);
@@ -84,15 +84,15 @@
getWaitForFile().delete();
}
}
-
+
protected void runServerClientTest(Class<?> serverClass, Class<?> clientClass, String...commonArgs) throws Exception {
runServerClientTest(serverClass.getName(), commonArgs, clientClass.getName(), commonArgs);
}
-
+
protected void runServerClientTest(String serverClass, String clientClass) throws Exception {
runServerClientTest(serverClass, new String[0], clientClass, new String[0]);
}
- protected void runServerClientTest(String serverClass, String[] serverArgs,
+ protected void runServerClientTest(String serverClass, String[] serverArgs,
String clientClass, String[] clientArgs) throws Exception {
server.launch();
Future<Void> serverFuture = server.invokeMainAsync(serverClass, serverArgs);
@@ -108,15 +108,15 @@
}
server.exit(0);
}
-
+
public void setWaitForFile(String file) {
this.waitForFile = new File(file);
}
-
+
public File getWaitForFile() {
return waitForFile;
}
-
+
protected void waitForFile() {
long timeBefore = System.currentTimeMillis();
if(getWaitForFile() != null) {
@@ -127,7 +127,7 @@
}
Thread.sleep(50);
if(System.currentTimeMillis() > timeBefore + waitForFileTimeout) {
- fail("The file " + getWaitForFile() +
+ fail("The file " + getWaitForFile() +
" was not created within " + waitForFileTimeout + "ms");
}
}
@@ -137,5 +137,5 @@
getWaitForFile().deleteOnExit();
}
}
- }
+ }
}
diff --git a/yoko-core/src/test/java/test/common/TestBase.java b/yoko-core/src/test/java/test/common/TestBase.java
index 5fd246f..3cabd35 100644
--- a/yoko-core/src/test/java/test/common/TestBase.java
+++ b/yoko-core/src/test/java/test/common/TestBase.java
@@ -49,7 +49,7 @@
String nameString = context.to_string(name);
out.println(nameString);
}
-
+
protected static void readRef(BufferedReader reader, String[] refStrings) throws IOException {
String line = reader.readLine();
if (line == null) {
@@ -65,7 +65,8 @@
throw new RuntimeException(sw.toString());
}
}
- refStrings[0] = reader.readLine();
- refStrings[1] = reader.readLine();
+ refStrings[0] = reader.readLine(); // IOR
+ refStrings[1] = reader.readLine(); // name
+ System.out.println(refStrings[1] + " = "+ refStrings[0]);
}
}
diff --git a/yoko-core/src/test/java/test/tnaming/Client.java b/yoko-core/src/test/java/test/tnaming/Client.java
index 51b3cb2..c9f879f 100644
--- a/yoko-core/src/test/java/test/tnaming/Client.java
+++ b/yoko-core/src/test/java/test/tnaming/Client.java
@@ -75,6 +75,7 @@
//
// Get "test" objects
//
+ System.out.println("Started ORB, getting test object IORs from file");
try (BufferedReader file = openFileReader(refFile)) {
String[] refStrings = new String[2];
readRef(file, refStrings);
@@ -117,6 +118,7 @@
}
void run() throws Exception {
+ System.out.println("Running naming client tests");
switch (accessibility) {
case READ_ONLY :
testReadOnly();
@@ -137,16 +139,23 @@
}
private void testBoundReferences() throws UserException {
+ System.out.println("Testing bound reference 1");
Util.assertTestIsBound(test1, rootNamingContext, name1);
+ System.out.println("Testing bound reference 2");
Util.assertTestIsBound(test2, rootNamingContext, name2);
+ System.out.println("Testing bound reference 3");
Util.assertTestIsBound(test3, rootNamingContext, name3);
+ System.out.println("Testing bound reference 1 via corbaname");
Util.assertCorbanameIsBound(test1, orb, "corbaname:rir:/NameService#"+name1);
+ System.out.println("Testing bound references complete.");
}
private void testIterators() throws Exception {
+ System.out.println("Testing iterators: narrowing context");
NamingContextExt nc = NamingContextExtHelper.narrow(rootNamingContext.resolve(Util.ITERATOR_TEST_CONTEXT_PATH));
// check the behaviour of the binding iterators
for (int listSize = 0; listSize <= Util.EXPECTED_NAMES.size() + 1; listSize++) {
+ System.out.println("Testing iterators: list size " + listSize);
final BindingListHolder blh = new BindingListHolder();
final BindingIteratorHolder bih = new BindingIteratorHolder();
final BindingHolder bh = new BindingHolder();
@@ -176,6 +185,7 @@
assertEquals(0, bh.value.binding_name.length);
assertEquals(Util.EXPECTED_NAMES, actualNames);
}
+ System.out.println("Testing iterators complete.");
}
private enum WriteMethod {
@@ -220,8 +230,11 @@
}
public void testObjectFactories() throws CannotProceed, InvalidName {
+ System.out.println("Testing object factories: resolvable");
Util.assertFactoryIsBound(rootNamingContext, Server.RESOLVABLE_TEST);
+ System.out.println("Testing object factories: resolver");
Util.assertFactoryIsBound(rootNamingContext, Server.RESOLVER_TEST);
+ System.out.println("Testing object factories complete.");
}
@Override
diff --git a/yoko-core/src/test/java/test/tnaming/ClientForReadOnlyNameService.java b/yoko-core/src/test/java/test/tnaming/ClientForReadOnlyNameService.java
index b234afd..4b4aefa 100644
--- a/yoko-core/src/test/java/test/tnaming/ClientForReadOnlyNameService.java
+++ b/yoko-core/src/test/java/test/tnaming/ClientForReadOnlyNameService.java
@@ -13,7 +13,6 @@
props.put("org.omg.CORBA.ORBSingletonClass", "org.apache.yoko.orb.CORBA.ORBSingleton");
try (Client client = new Client(READ_ONLY, refFile, props, "-ORBInitRef", "NameService=" + Util.NS_LOC )) {
- client.testObjectFactories();
client.run();
}
}
diff --git a/yoko-core/src/test/java/test/tnaming/Server.java b/yoko-core/src/test/java/test/tnaming/Server.java
index 74a0894..232f30e 100644
--- a/yoko-core/src/test/java/test/tnaming/Server.java
+++ b/yoko-core/src/test/java/test/tnaming/Server.java
@@ -22,16 +22,17 @@
package test.tnaming;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
+import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Properties;
import org.apache.yoko.orb.spi.naming.Resolvable;
import org.apache.yoko.orb.spi.naming.Resolver;
-import org.omg.CORBA.*;
+import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextExt;
@@ -50,7 +51,7 @@
private static final NameComponent TEST1 = new NameComponent("Test1", "");
private static final NameComponent TEST2 = new NameComponent("Test2", "");
private static final NameComponent TEST3 = new NameComponent("Test3", "");
-
+
public static final NameComponent RESOLVABLE_TEST = new NameComponent("ResolvableTest", "");
public static final NameComponent RESOLVER_TEST = new NameComponent("ResolverTest", "");
@@ -90,7 +91,7 @@
return resolvable.resolve();
}
};
-
+
System.out.println("created references");
} catch (Throwable t) {
System.err.println("Caught throwable: " + t);
@@ -101,7 +102,10 @@
void run() throws Exception {
System.out.println("server starting to run");
- try (PrintWriter out = new PrintWriter(new FileWriter(refFile))) {
+
+ // use a temporary file to avoid the client picking up an empty file when debugging the server
+ Path tmp = Files.createTempFile(refFile, "");
+ try (PrintWriter out = new PrintWriter(new FileWriter(tmp.toFile()))) {
System.out.println("server opened file for writing");
try {
NamingContext nc1 = rootNamingContext.new_context();
@@ -118,7 +122,7 @@
Util.assertNameNotBound(rootNamingContext, TEST1);
rootNamingContext.bind(new NameComponent[]{TEST1}, test1);
-
+
Util.assertTestIsBound("Test1", rootNamingContext, TEST1);
nc1.bind(new NameComponent[]{TEST2}, test2);
@@ -141,6 +145,7 @@
Util.assertNameNotBound(rootNamingContext, LEVEL1, LEVEL2, TEST3);
nc1.rebind_context(new NameComponent[]{LEVEL2}, nc2);
+ System.out.println("All contexts bound");
} catch (Exception e) {
e.printStackTrace(out);
throw e;
@@ -151,25 +156,30 @@
// condition between the client sending a request and the
// server not being ready yet.
//
+ System.out.println("Writing IORs to file");
writeRef(orb, out, test1, rootNamingContext, new NameComponent[]{TEST1});
writeRef(orb, out, test2, rootNamingContext, new NameComponent[]{LEVEL1, TEST2});
writeRef(orb, out, test3, rootNamingContext, new NameComponent[]{LEVEL1, LEVEL2, TEST3});
out.flush();
+ System.out.println("IORs written to file");
} catch (java.io.IOException ex) {
System.err.println("Can't write to `" + ex.getMessage() + "'");
throw ex;
}
+ // rename the completed file
+ Files.move(tmp, Paths.get(refFile));
+
orb.run();
}
- public void bindObjectFactories() throws NotFound, CannotProceed, InvalidName, AlreadyBound {
+ public void bindObjectFactories() throws NotFound, CannotProceed, InvalidName, AlreadyBound {
rootNamingContext.bind(new NameComponent[]{RESOLVABLE_TEST}, resolvable);
Util.assertFactoryIsBound(rootNamingContext, RESOLVABLE_TEST);
rootNamingContext.bind(new NameComponent[]{RESOLVER_TEST}, resolver);
Util.assertFactoryIsBound(rootNamingContext, RESOLVER_TEST);
}
-
+
@Override
public void close() throws Exception {
try {