tnameserv(1)

tnameserv(1) πŸ’–

Java IDL and RMI-IIOP Tools ✨

okay bestie, buckle up, because we're about to talk about the tnameserv command from the Java IDL and RMI-IIOP tools, and honestly? it's giving "quiet little workhorse that runs the whole naming service" and I'm obsessed πŸŽ€


✨ NAME ✨

tnameserv β€” Interface Definition Language (IDL). yeah that's it, that's the whole vibe πŸ’…


🌸 SYNOPSIS 🌸

tnameserve -ORBInitialPort [ nameserverport ]
  • -ORBInitialPort nameserverport β€” this is the initial port where the naming service listens for the bootstrap protocol. and what's that protocol for, you ask? it's what implements the ORB resolve_initial_references and list_initial_references methods. periodt 🫢

πŸ’œ DESCRIPTION πŸ’œ

so Java IDL ships with the Object Request Broker Daemon (aka ORBD). ORBD is a daemon process and it's literally carrying the whole squad: a Bootstrap Service, a Transient Naming Service, a Persistent Naming Service, and a Server Manager. the Java IDL tutorials all use ORBD, no cap. but here's the tea β€” you can swap the tnameserv command in for the orbd command in any of the examples that use a Transient Naming Service. iconic behavior honestly ✨

see orbd(1) or Naming Service at http://docs.oracle.com/javase/8/docs/technotes/guides/idl/jidlNaming.html

k so the CORBA Common Object Services (COS) Naming Service gives you a tree-structure directory for object references, similar to how a file system gives you a directory structure for files. the Transient Naming Service that comes with Java IDL, tnameserv, is a simple implementation of the COS Naming Service specification. lowkey elegant, highkey useful 🌸

object references get stored in the name space by name, and each object reference-name pair is called a name binding. name bindings can be organized under naming contexts. and naming contexts? they're name bindings too, bestie β€” they serve the same organizational function as a file system subdirectory. all bindings are stored under the initial naming context, and the initial naming context is the only persistent binding in the name space. everything else in the name space is lost when the Java IDL naming service process stops and restarts. so like… don't get too attached to the rest of it, it's transient for a reason πŸ’€

for an applet or application to use COS naming, its ORB has to know the port of a host running a naming service, OR have access to an initial naming context string for that naming service. and the naming service can be either the Java IDL naming service or another COS-compliant naming service. options, we love to see it πŸ‘‘


πŸ¦‹ START THE NAMING SERVICE πŸ¦‹

you must start the Java IDL naming service before an application or applet that uses its naming service. installing the Java IDL product creates a script (on Oracle Solaris: tnameserv) or an executable file (on Windows: tnameserv.exe) that starts the Java IDL naming service. and you want to start the naming service so it runs in the background, mmkay? 🌈

if you don't specify otherwise, the Java IDL naming service listens on port 900 for the bootstrap protocol used to implement the ORB resolve_initial_references and list_initial_references methods, like this:

tnameserv -ORBInitialPort nameserverport&

if you don't specify the name server port, then port 900 is used by default. now here's a lil warning: when you're running Oracle Solaris software, you must become the root user to start a process on a port below 1024. for this reason, it's recommended that you use a port number greater than or equal to 1024. to specify a different port β€” for example, 1050 β€” and to run the naming service in the background, from a UNIX command shell, enter:

tnameserv -ORBInitialPort 1050&

from an MS-DOS system prompt (Windows), enter:

start tnameserv -ORBInitialPort 1050

clients of the name server must be made aware of the new port number. how, you ask? set the org.omg.CORBA.ORBInitialPort property to the new port number when you create the ORB object. don't skip this step bestie, the clients will literally be lost 😭


🧚 RUN THE SERVER AND CLIENT ON DIFFERENT HOSTS 🧚

in most of the Java IDL and RMI-IIOP tutorials, the naming service, server, and client are all running on the development machine. cute, cozy, unrealistic. in real-world deployment, the client and server probably run on different host machines from the Naming Service. main character deployment energy fr fr ✨

for the client and server to find the Naming Service, they must be made aware of the port number and host on which the naming service is running. do this by setting the org.omg.CORBA.ORBInitialPort and org.omg.CORBA.ORBInitialHost properties in the client and server files to the machine name and port number on which the Naming Service is running. an example of this is shown in Getting Started Using RMI-IIOP at http://docs.oracle.com/javase/8/docs/technotes/guides/rmi-iiop/rmiiiopexample.html

you could also use the command-line options -ORBInitialPort nameserverport# and -ORBInitialHost nameserverhostname to tell the client and server where to find the naming service. for one example of doing this using the command-line option, see Java IDL: The Hello World Example on Two Machines at http://docs.oracle.com/javase/8/docs/technotes/guides/idl/tutorial/jidl2machines.html

for example β€” and this is a cute lil scenario, stay with me β€” suppose the Transient Naming Service, tnameserv, is running on port 1050 on host nameserverhost. the client is running on host clienthost, and the server is running on host serverhost.

start tnameserv on the host nameserverhost:

tnameserv -ORBInitialPort 1050

start the server on the serverhost:

java Server -ORBInitialPort 1050 -ORBInitialHost nameserverhost

start the client on the clienthost:

java Client -ORBInitialPort 1050 -ORBInitialHost nameserverhost

see how it all comes together? 🫢 that's the whole point.


πŸŽ€ STOP THE NAMING SERVICE πŸŽ€

to stop the Java IDL naming service, use the relevant operating system command β€” such as kill for a Unix process or Ctrl+C for a Windows process. the naming service keeps waiting for invocations until it is explicitly shut down. so like, it's not gonna quit on its own, it's committed πŸ’…

⚠️ note that names registered with the Java IDL naming service disappear when the service is terminated. gone. poof. so write that down πŸ“

⭐ OPTIONS ⭐

  • -Joption β€” passes option to the Java Virtual Machine, where option is one of the options described on the reference page for the Java application launcher. for example, -J-Xms48m sets the startup memory to 48 MB. see java(1). slay ✨

✨ EXAMPLES ✨


ADD OBJECTS TO THE NAME SPACE

okay bestie, so this next example is gonna show you how to actually add names to the name space 🌸 It's a completely self-contained Transient Naming Service client (yes, self-contained, she needs nothing from you πŸ’…) and it builds this lil cutie tree right here:

Initial Naming Context
     plans
     Personal
          calendar
          schedule

So in this scenario, plans is an object reference, and Personal is a naming context that's holding two object references: calendar and schedule. Very demure, very mindful. πŸŽ€

import java.util.Properties;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
public class NameClient {
    public static void main(String args[]) {
        try {

Back in Start the Naming Service, the nameserver got started on port 1050. So this next bit of code makes sure our client program knows about that port number, no cap:

            Properties props = new Properties();
            props.put("org.omg.CORBA.ORBInitialPort", "1050");
            ORB orb = ORB.init(args, props);

Then this code grabs the initial naming context and assigns it to ctx. And the second line? It copies ctx into a dummy object reference called objref β€” that's the one we attach to all the names and yeet into the name space. πŸ¦‹

            NamingContext ctx =
                NamingContextHelper.narrow(
                    orb.resolve_initial_references("NameService"));
             NamingContext objref = ctx;

Next up: this code makes a name called plans of type text and binds it to that dummy object reference. Then plans gets added under the initial naming context using the rebind method. And why rebind instead of bind, you ask? Because rebind lets you run this program over and over and over again without catching exceptions from bind β€” she's forgiving like that πŸ’–

            NameComponent nc1 = new NameComponent("plans", "text");
            NameComponent[] name1 = {nc1};
            ctx.rebind(name1, objref);
            System.out.println("plans rebind successful!");

Now this code creates a naming context called Personal of type directory. The resulting object reference, ctx2, gets bound to the name and added under the initial naming context. Look at her go ✨

            NameComponent nc2 = new NameComponent("Personal", "directory");
            NameComponent[] name2 = {nc2};
            NamingContext ctx2 = ctx.bind_new_context(name2);
            System.out.println("new naming context added..");

The rest of the code binds that dummy object reference using the names schedule and calendar under the Personal naming context (ctx2). 🫢

            NameComponent nc3 = new NameComponent("schedule", "text");
            NameComponent[] name3 = {nc3};
            ctx2.rebind(name3, objref);
            System.out.println("schedule rebind successful!");
            NameComponent nc4 = new NameComponent("calender", "text");
            NameComponent[] name4 = {nc4};
            ctx2.rebind(name4, objref);
            System.out.println("calender rebind successful!");
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
    }
}
πŸ‘€ not me pointing out that the original literally spells it calender in the code β€” we keep it exactly as written, bestie, typos are load-bearing here πŸ™ˆ

BROWSING THE NAME SPACE

Now the fun part: peeking at what's already in there. Here's a sample program showing how to browse the name space πŸ‘‘

import java.util.Properties;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
public class NameClientList {
    public static void main(String args[]) {
        try {

Again, in Start the Naming Service the nameserver was started on port 1050, and this code makes sure the client program knows it:

            Properties props = new Properties();
            props.put("org.omg.CORBA.ORBInitialPort", "1050");
            ORB orb = ORB.init(args, props);

And this next bit obtains the initial naming context:

            NamingContext nc =
            NamingContextHelper.narrow(
                orb.resolve_initial_references("NameService"));

The list method lists the bindings inside the naming context. In this case, up to 1000 bindings from the initial naming context come back in the BindingListHolder β€” and any bindings left over get returned in the BindingIteratorHolder. She's not a quitter, she just paginates πŸ’…

            BindingListHolder bl = new BindingListHolder();
            BindingIteratorHolder blIt= new BindingIteratorHolder();
            nc.list(1000, bl, blIt);

This code pulls the array of bindings out of the returned BindingListHolder. And if there are literally no bindings? Program ends, we go home, no notes. 😭

            Binding bindings[] = bl.value;
            if (bindings.length == 0) return;

The remainder loops through the bindings and prints out the names:

            for (int i=0; i < bindings.length; i++) {
                // get the object reference for each binding
                org.omg.CORBA.Object obj = nc.resolve(bindings[i].binding_name);
                String objStr = orb.object_to_string(obj);
                int lastIx = bindings[i].binding_name.length-1;
                // check to see if this is a naming context
                if (bindings[i].binding_type == BindingType.ncontext) {
                    System.out.println("Context: " +
                        bindings[i].binding_name[lastIx].id);
                } else {
                    System.out.println("Object: " +
                        bindings[i].binding_name[lastIx].id);
                }
            }
        } catch (Exception e) {
            e.printStackTrace(System.err)
        }
    }
}
πŸ“ the original says this sample program "shoes" how to browse β€” we're keeping the lore intact. Also that last e.printStackTrace(System.err) really does be missing its semicolon. fr fr. we do not fix. we report. πŸ™ˆ

✨ SEE ALSO ✨

  • orbd(1) β€” go say hi to her sister πŸ’œ

and that's the whole page, bestie!! this one ships with JDK 8 and was dated 21 November 2013 β€” vintage, iconic, still slaying πŸŒˆπŸ‘‘πŸ’–