Jini-talk with Jim Waldo -- Full transcript

Jini architect addresses Jini's importance in ever-changing environments

Frank Sommers: During your JavaOne 2001 presentation, you talked about how the network's "edge" forces us to rethink how we build our networked information systems. Considering that the three largest cell phone manufacturers alone produce about six new cell phones every second, most of which access the Internet, that edge is expanding very fast. How does mobility impact our network-based software architectures?

Jim Waldo: Mobility is an interesting new wrinkle in our networks. We have always built networks with the idea that the things the network hooks together don't move around much. If you move your machine from one place to another, it essentially becomes a different machine. It's hard to convince the network that it's the same. Your identity may be the same if you have certificates issued by a certificate authority, or if you can log in through some network-wide login mechanism. But, say, if you take your laptop from one office to another, your machine gets a new IP address through DHCP (Dynamic Host Configuration Protocol) or some other mechanism. As far as the network is concerned, it's a different machine.

One way to deal with that problem is to consider the machinery and the things that move around as being "relocateable" services. Just as objects can move around the network, objects can move outside the network and relocate themselves, find services, and offer services that are in a different place.

If I move from place to place, there are pieces of information associated with me: my current phone number, my current location, the home directory with which I'm working, and where my mail is delivered. One way to deal with this is to have a static location where everything that knows my location goes, and that then forwards the needed information to me. This is the notion mobile IP takes, for instance. It works as long as you assume that the network doesn't break and you're never out of touch with your home network -- assumptions that are, generally, false.

Another way to deal with this is to say that when I move from one place to another, there are a set of services associated with me: a service that tells where I am, or one that tells how to contact me. You need to register those services locally, and propagate those services on the network.

The easiest way to do that is to return to where those services were and add a forwarding address. But you may also have a hierarchy of lookup services, so that when you look for services that represent an individual, you have some hint as to where that person last was. But if hints don't work, you may go into higher-level lookup services until something directs you to the current location.

In essence, the physical device becomes an implementation of the service. Implementations change over time. So, if you move from one place to another, you may change the implementation of the machine by which the service is being offered, but it's the same service.

Sommers: Many people associate mobility with small devices. But you're saying that size does not matter when it comes to mobility.

Waldo: Small devices are an interesting form of a service's mobile implementation. But Jini is not about devices any more than Java is about applets. Jini is about services and their users, and hooking the two together. You can implement those services in any appropriate way: as a device, as a piece of software, or as a collection of other services. It really isn't about devices. It's about accomplishing things on the network, and isolating what you want done, described by a Java interface, from how it gets done, which is an implementation.

Motion is really just a form of change. Jini is really about networks' ability to change without having to stop and restart. It lets networks change in chaotic and spontaneous ways. One way change can happen is when a networked service moves around. Another way is when something gets pulled off or put on the network. Those are all ways networks experience change all the time.

Embrace change in the enterprise MIS

Sommers: When you mention the word "change," most corporate MIS (management information system) managers associate large expenses with change. What you're saying suggests that Jini is a great way to reduce that cost, because it's an infrastructure designed for change.

Waldo: That was our original thought. Change is not a rare event -- it's constant. We had to figure out a way to allow change to happen without involving people. If change required people, and considering networks now growing into millions of machines and the amount of change those networks experience, we would all have to become system administrators. The only way to avoid that is to automate the ability to deal with change.

Sommers: Do you think Jini is the ultimate model for an MIS infrastructure?

Waldo: I think Jini is the best model we have currently for a network infrastructure. Enterprises tend to use networks a lot; therefore, it's an enterprise network infrastructure as well. But if people start using networks in their homes, then it becomes a home infrastructure. Enterprises want to save money; you don't want to hire a system administrator at home.

This is true even for automobile electronics. If you change your CD player to the newest and latest CD or MP3 player, you still want it to interact with other things in your car -- your speakers or the telephone. You don't want the kid at Best Buy reconfiguring your auto network when he installs the new CD player. You want that to be automatic.

So the same problem you have in enterprises, in your home, and in your automobile exists anywhere there is a network. Enterprises have the problem first because they tend to have the largest networks. But it will be everywhere.

Sommers: For many MIS managers, change is not only a source of expense, but is also a source of fear, because change is also a chance for making errors. How does Jini address the issue of reliability in the presence of constant change?

Waldo: Change is something that MIS managers rightfully fear. On the other hand, MIS managers also know that they must have change. Change was never really planned for in most distributed computing environments because we assumed networks were fairly small and static. But as networks became bigger, and as the rate of change became faster, the need to design a network system that allows for change has become more important.

Jini was designed with the idea that change occurs all the time, making change nearly automatic. MIS managers need, really, a way to change the broken things without causing other things to break. Jini gives you that isolation.

For instance, Jini lets you run your old and your new services simultaneously. You can plug in a service's new version, and your old clients can use it, even while the old version still exists, because those versions are just alternate implementations of the same interface. You can then instrument the new service, and if it has a problem, you can shut it down, and every service client can return to the old version immediately. That happens automatically. You just have to unplug the new service's machine, or unregister it, and then you can phase in those kinds of changes. You don't have to change the whole network; you can change one thing at a time.

To avoid human error, you avoid requiring human involvement. Many human errors occur in network configurations because of typing errors; for example, in assigning network addresses, where services are misdescribed or misapplied by the system administrator.

In the Jini world, when you plug in a service to the network, once it gets its IP address (automatically done via DHCP), a mechanism started programmatically registers the service with the Jini lookup service without any human intervention. The description is not human-entered, but is the Java type of the service being offered. The clients that need to use it already know what that type is in order to make the method calls to talk to the service. We avoid human error by automating the process that was error-prone.

Sommers: Enterprise-wide networked systems use many protocol types. Not only network protocols, such as TCP/IP, but also "homemade" protocols, invented by a company's own programmers. Many enterprises maintain these in manuals and operational books, which often descend from generations of MIS managers. When such a protocol changes, everything using that protocol breaks. How does Jini address this issue?

Waldo: Protocol means a lot of things. The low-level networking protocols, like TCP, describe how you send packets of information. Jini does not deal at that level; it assumes that your network can move packets of bits from one place to another. The next protocol layer is how those bits get interpreted, such as protocols like XML and IIOP (Inter-ORB Protocol). Jini allows a service to use whatever protocol is appropriate for it.

In the Jini world, the client doesn't talk to the service directly using one of those protocols. Instead, the client gets a Java object from a lookup service that implements the right interface representing the service. That object was put into the lookup service by the ultimate service providing the information or the computation that the client needs. In effect, the client injects a piece of the service into its own address space, and makes method calls on that Java object. That object generates the wire protocols to talk to the service. This means that different services can use different protocols.

Traditionally in distributed computing systems, those who have agreed on a wire protocol have gained interoperability. Jini and Java RMI (Remote Method Invocation) really changed the rules by saying that since you're getting the object that talks to the service from the service, how that wire protocol information is exchanged is a private matter between the object piece from the service that gets injected into the client, and the service.

This means you can hide the protocols behind the Java objects that move around the network. If you had private protocols that work well for you, or can't be changed, you can wrap them in a Java object and actually use them while developing new services with more modern protocols. Whatever protocol is best for that service the client can also use. And different implementations of the same service can use different protocols in the Jini world. That's a fundamental change in the way we build distributed systems.

Sommers: In the 1980s and early 1990s, many American corporations realized the need to reengineer their operations to better respond to global competition. With networked services becoming strategic to many organizations, and networks becoming overly complex, do you think the time has come to think about reengineering the corporate MIS infrastructure as well? Do you see Jini playing a role in this arena?

Waldo: There is a tremendous amount of talent in MIS departments around the world being used for fairly trivial tasks. Troubleshooting and crisis management are not terribly enjoyable, nor challenging. They are challenging only in the sense that they are constant and you have to do it. It's like being in the line of fire all the time. People in these MIS organizations have the talent to figure out ways in which companies can use their computational resources more effectively. However, with the existing infrastructure, they don't have the time to do the thinking that's required to accomplish that.

I think Jini could help reengineer MIS infrastructures. Rather than being a reactive organization, where the MIS manager's goal is to keep things from falling into total chaos, using Jini, the organization can become more proactive, where the MIS manager's goal is to plan for the strategic network upgrade over time to meet user needs. Managers will have the time to think about what is needed, instead of reacting to their day-to-day problems. MIS management becomes a very different job; it's not troubleshooting, it's planning. Using Jini, managers can concentrate on things like service quality. They can manage the change and do long-range planning. They can focus on what they will need a year from now rather than keeping what they have together with the bailing wire and chewing gum they currently use.

Sommers: If an MIS manager decides he's ready to make this paradigm shift, how would you suggest he go about it? What would be the first steps?

Waldo: First, begin to understand what Jini really is and how a Jini network works. Many books and articles can help you in that area.

Next, embrace Java as fully as you can. Many MIS managers have already done that, but they especially need to realize that Java and the object mobility it provides is a key entry into Jini.

Beyond that, start some pilot projects to see how this could work. Pick two or three problem projects, services that are necessary but difficult to maintain, or services users demand but you're not quite sure how to create. Create those services in a Jini-enabled fashion, and then experiment with how you can change them over time. The nice thing about Jini is you don't have to convert everything to Jini all at once. You can convert just a small area, a portion of the enterprise, or just some applications used in the enterprise. You can ease into it as you gain more experience.

Sommers: Are you aware of similar technologies today that MIS managers could choose if they want such a different paradigm for their management information systems?

Waldo: Actually, I don't think so. Jini differs from most other technologies in that it takes the network seriously as an entity in itself. It's not a way to build things that get connected by the network, but a way to build networks of connected things. It makes the network an entity that always runs, and may have parts changing as it runs.

It is a different approach from most distributed systems, which say that the network is merely a data exchange mechanism between the things you build, so you build these components that get connected by these wires, as opposed to building a system that is the network.

The only people who think in the terms that we in the Jini world think of the network are the telcos (telephone companies), where the network is very much an entity, separate from all network-connected pieces.

Sommers: And telco networks are typically very reliable...

Waldo: The telcos are reliable because the network is the entity guaranteed to be there all the time. Things change all over the place in the telephone network, but the changes never bring the telephone network down. That's how we have to start thinking of our enterprise networks, our home networks, our personal networks, our ubiquitous networks. We rely on the network, not the things connected by the network.

During his JavaOne 2001 keynote, James Gosling made an interesting point. He said we talk a lot about network services and people translate that into servers, but services aren't servers, even though they may run on a server. The service lives on the network and if its location changes on the network, it shouldn't matter to the clients because they access the service from the network, not from an entity connected on the network.

The network provides the service, not the things on the network. You don't dial through a particular switch on the telephone network, even though the switch enables that to work. Instead, you just use a telephone network to call somebody on another telephone. We must think of our corporate computational networks in that same way.

Ubiquitous high-availability

Sommers: As people increasingly depend on the network-provided services, we will have less tolerance when these services are unavailable. Considering our experience with the reliability of existing computer software, do you think we are ready to place increasing trust in our networks?

Waldo: I sometimes talk these days about the environment we have led computer users to expect. We have conditioned them to expect unreliable computers that are fragile and break easily. They have grown used to their computers crashing.

As we start moving computation into a more embedded system, people won't see the thing that contains a computer as a computer. They will see it as a telephone, a refrigerator, or a television set. We don't expect those things to be fragile or to crash, or that they are complicated pieces of equipment that we can't rely on. As software people, we will have the same level of expectation placed on our product that is placed on many other products. Consumers will require reliable products. To make them reliable, we must make them smaller, simpler, and able to interact with other small and simple components. Then we have to make sure the whole thing works together, which will require the kind of network service architecture that Jini is about.

Jini is about little components offering simple services that can be knit together as needed to provide complex services. These little components, and their interaction, can be reliable. And if one crashes, you can easily find an equivalent service on the network to replace it. That's the key to reliability.

Sommers: Do you mean redundancy and replication for services?

Waldo: Absolutely. Redundancy and replication are the only ways to make reliable systems out of unreliable parts. At least, they're the only way we know. We have to apply those techniques in software, as well. We apply them in hardware sometimes, but not very well in software. In software, we've made larger and larger things so that any small errors somewhere in your big program can crash the whole thing. We should, and will soon, consider that unacceptable.

Sommers: Currently, when you talk about redundancy, typically, a high expense is associated with that. If you want to get your database management system up in a redundant fashion, you typically need additional licenses, which quickly becomes expensive.

Waldo: The expense of these redundant systems is often dictated by the scale of the thing that is made redundant. If you have a large and complicated database, running on expensive hardware, and you want to make that redundant, it's very expensive, because you have to buy a second, very large piece of software, running on a second, very large piece of hardware.

But you can get a cheaper level of redundancy and replication by making small components redundant. That doesn't add a lot of expense, because the thing that is redundant and replicated is small and simple. There are already a lot of small, redundant components in airplanes, automobiles, and other mechanical devices. We could do the same thing in software components.

Sommers: That will be bad news for a lot of software vendors, because they tend to have high revenues typically coming from enterprises willing to pay large amounts in return for high availability. Are you talking about the commoditization of high availability?

Waldo: Making things small and simple doesn't necessarily make them commodities. There are small and simple things that do one thing very well. I hope, in fact, this will open up the software market so that you don't have to compete by doing everything better than anybody else. You can compete by doing one small thing.

Type systems vs. the semantic Web

Sommers: Many people nowadays talk about XML's role in providing semantic context for Web services. Jini's primary mechanism of semantics, however, lies in the Java language's service type. Last March, the WWW Consortium's Tim Berners-Lee published "The Semantic Web" in Scientific American, describing what the future of the Web might be like. How do you envision Jini playing a role in the semantic Web? How would you compare the XML-based, semantic approach to Jini's reliance on a type system?

Waldo: I think we're a long way from understanding semantics. It would be wonderful if we could teach machines to understand things the way we understand them. We don't have a good model of how we understand semantics, much less a model that we can translate into a computer program. I think that work, like what Tim is pushing on the semantic Web, is wonderful. But I don't believe it will succeed in my lifetime. So, I'm looking at other aspects. I could be absolutely wrong, and they could be wildly successful. When they are, they might be able to replace all of the work we're doing on Jini. But I don't think so.

Type systems don't give you a complete semantics, but rather describe the kinds of things in the world. So, that way they are a semantics, because they tie some language into those things. We have rules on how you combine types to get other types. Semantics isn't just the meaning of constituent parts, but how you combine those meanings to define their combination. So the composition model really makes something into a semantics. We don't understand the semantics of natural language, but we do understand the semantics of type systems.

Bill Venners: I laugh because we're speaking a natural language, and we're understanding each other...

Waldo: We understand each other, but we don't understand why or how. It would seem easy if I knew the meanings of all the words to come up with rules that would let me say, If you combine these words together, here is what the meaning of the combination is. But it's unbelievably hard. The formal semantics that we have available for natural language are limited to trivial pieces. And the progress we're making, when it has worked, is quite small. Computers are understanding natural language better by basically ignoring the work that linguists have done for the past 20 years, and returning to a notion of statistical analysis and Markov models, where you get an idea of what might be said based on surface analysis and the probabilities of one word following another. But it doesn't really give this combinatorial ability.

Type composition, we understand. And in the Java language, we can specify it quite well. Java is an artificial language; it doesn't give us as rich a meaning as we get in a natural language. It's very hard to express metaphorical meaning in Java types. But the exact matching we get is what we ground the identification in Jini in. And that's why we use a type system.

Sommers: You're saying that type systems have a well-proven logical model, whereas for these other types of semantic notions there is no model at all, at least not yet.

Waldo: That's right. Or what models we do have are known to be inadequate for anything interesting. We're engineers in the Jini group. We took something that we understood to be inadequate but well specified and used it as the foundation of what we've built. And we're seeing how far that train will lead us. We think it's a fairly interesting train.

Venners: Would you give an example of what you mean by composition of types in the Java system?

Waldo: The whole polymorphic type hierarchy is a notion of compositionality, as is the notion of being able to implement multiple interfaces. One problem if you're using natural language in a directory system to describe a service is what you do with a multifunction device. So, if the device is a printer, scanner, and a fax machine, how do you describe the relationship between combinations of printers/scanners/fax machines to printers, and scanners, and fax machines?

Using the type system, that's simple. The device implements three interfaces: the printer interface, the scanner interface, and the fax interface. Using a descriptive language, like English, it's difficult to describe what their relationship is.

In Java, we have compositionality of subtyping. A color printer is a printer type, which gives us one form of compositionality. In addition, there is the notion of mixing interfaces together to build types out of other types. Both are well specified. It's not rich semantics; you really only have two types of relationships: subtype and compositional type. But it's rich enough to do a lot, and that's what we're looking for.

Venners: I once heard you say that computers are not good at understanding strings, but are good at understanding types, which is what people aren't. But doesn't the programmer understand type when writing code and then sending it out the door? Isn't that a proxy for the programmer understanding a type? So, isn't it the programmer who doesn't understand the strings, also?

Waldo: A program is good at comparing a couple things for type equivalence. It's really hard for a programmer to compare two strings for meaning equivalence. As a programmer, I can understand the meaning equivalence of those two things. I know that a color printer is a type of printer, but a ribbon printer is not. But it's tough to write a program that understands that. Subtyping and compositional relationships in a type system are easy in Java: I say, Is this a ..., and I'm done. I don't have an equivalent primitive in the Java language that says "means the same as" and that takes two strings. We could get the Java people to do that, but it would be difficult.

Sommers: If you look at most successful technologies, many are based on rigorous mathematical and logical theories. For instance, relational algebra provided a foundation for many successful database technologies today. In distributed computing, could type systems be a logical foundation?

Waldo: It's part of a logical foundation. I'm not sure what the logical foundation of distributed computing is yet. It's one of the things I like to think about in my spare time. A number of logics get built into distributed computing. One is an identification logic, which in Jini's case is based on the type system in Java, and therefore could be specified fairly well mathematically. There are also various security logics. Butler Lampson came out with his logic of authentication some time ago, which is the beginning of such a formal specification about what it means to authenticate over a distributed system. I think that needs a lot of work. Now that we know we can do it, we need to do it in a more expansive way, to see what alternatives there are. Luca Cardelli, now at Microsoft Research, has worked a lot on various Lambda calculi for distributed systems. Interesting stuff, but it hasn't quite connected with reality yet.

One of my favorite cartoons is on the cover of Sape Mullender's Distributed Systems. Its character looks into a river; the character is pointing one way, and his reflection is pointing the other. And it's labeled "Where theory meets practice." In distributed systems, we have good theory and good experience in implementing systems, but the two don't quite meet yet. We haven't grounded the systems that we've built on the theories that we've developed in such a way that the two are connected. We may be close.

One thing I like about distributed systems is they require both types of thinking -- practical engineering and the theoretical ability. At some point you hope they would touch. Doing distributed computing, I often think, is an act of faith. You never know, but you believe you will be able to do these things. I think everybody that does distributed computing is, at heart, a mystic.

Sommers: It looks like almost everybody does distributed computing these days...

Waldo: Well, almost everybody does computing that gets distributed. I'm not sure I would say everyone does distributed computing, yet. I think everybody should do distributed computing. A lot of people tend to forget that they are. They try to forget that there is a network involved there, one that makes fundamental changes in their lives.

Discovering services

Sommers: Many people working with Jini quickly discover that an object -- a Jini proxy, for instance -- contains data as well as method calls. Currently, Jini provides a fairly limited way to use that data in service discovery. Jini service discovery is based primarily only on Java language type, simple matching of entry attributes associated with a service, and a unique service ID. Do you envision richer semantics for Jini service discovery?

Waldo: I wouldn't say those three are the only means of service discovery. Those are the only ways we guarantee will always exist, but Jini's whole architecture is based on the notion that the infrastructure should be simple, and that the ability to provide value-added services should be easy to do. So, when people say they want much more complicated ways of finding their services, I tell them to write services that offer those complicated ways. You could have another service beyond the Jini lookup service that registers itself in the Jini lookup service, but also takes the contents of that lookup service and organizes it in completely different ways.

Sommers: A data access layer?

Waldo: It could be an access layer, it could be a SQL database on the attributes of the entities in the Jini lookup service. It could be a specialized filter that watches things coming in and informs you of things in which it thinks you might be interested. All those things are possible services. They are not part of the Jini infrastructure because that infrastructure is an attempt to keep things as small and simple as possible, but the Jini infrastructure does enable those services because the information is there and it can find and use them.

Those sorts of services could provide others ways of accessing and massaging that information in a way you find most easily digestible. What you find most easily digestible may not be the same as what other people find most easily digestible, which is another reason we don't provide these kinds of services in Jini, because Jini is trying to be the layer everybody requires. You may have a service that organizes the information in a way you find best. I may have a service that organizes the information in a very different way, which I find best. I shouldn't foist my service off on you, nor should you foist yours on me. That would be incompatible with the Jini philosophy.

By having these things as services, I can, by the way, find your service and see how you view the data in case that might be useful for me, assuming you will allow me to do that.

Building a team

Sommers: I'd like to ask you about something rather different. What your team at Sun has been able to do is quite remarkable. You're really defining a new paradigm of computing. I would like to ask you about the concept of leadership. As the Jini team leader, you have clearly assembled some very remarkable people.

Waldo: God help any manager who has to deal with a team like the Jini team. Our manager, Mark Hodapp, fortunately takes management as seriously as I take technology, and he's exceptionally good at it. I don't know how he puts up with us most of the time.

I spend a lot more time thinking about this than I generally would admit -- on how you build a team, and how we got the Jini team. Part of it is being careful about hiring at all levels, and making sure you get exceptional people. We had a lot of discussions where we said, "Well, this person seems to be good enough," but we weren't staggered by them. We finally got to the point of saying, "If we are not staggered by them, we don't hire them." I also try to hire people who are a lot smarter than I am. I think I've succeeded in most cases.

Much of it is just finding people who have the right sense of aesthetic -- a lot has to do with taste, and a desire to keep things simple and elegant. Finding those people is very hard. When you find them, you try to keep them at all cost.

The Jini team has been an exceptionally stable team. Very few people have left the team, and much of the team's core predates Jini by a lot. Bob Scheifler was working on X Windows, so, of course, we knew his work. But he was the last member of the group to join. Prior to that, Ann Wollrath and I worked together for nine years. Ken Arnold and I had worked together for 15 years, on the first CORBA implementation and earlier projects. So, finding good people, keeping them happy and interested, and having a manager who gives engineers the freedom and time to do the work were the keys to putting our team together.

My previous manager had an epiphany one day. He came by my office, and said, "You know, I finally got it figured out. There are two kinds of managers. There are managers who are in control, and know what's going on, and lead the team, and they are the ones who make the decisions. I am not that kind of manager. Not with this team." By the way, that was not the current Jini team, but was an equally good group of people. He continued, "Then there are managers like rock group managers: To make sure the equipment is set up, the bus arrives on time, and everybody gets out of the way, so the band can play. That's the kind of manager I've got to be." Being the sensitive guy that I am, I told him, "And make sure the brown M&Ms are out, too."

He had it right, if you have a top-notch group of engineers, the manager's job is to get people out of their way, and let them do their work. And you're not going to understand it, or figure out what they're doing. But you've got to have faith that what they're doing is top-notch work, because they've done it before. At Sun, we were lucky; it's more fun than you can imagine, working with people like that.

What's next?

Sommers: What's next for the Jini team? What are you working on?

Waldo: Right now we're working on the problem of how to make a secure distributed system where you move code around. That's our biggest, single task right now. We're also working on a set of things that will make Jini more scalable, and easier to use out of the box.

With security, we'll try a new model for release. We have released things in a classical fashion, where we would put out an early release, and then a beta release, and then a final release, with a fair amount of time in between. With the security release, we will put out a very early release, and then put out releases more often so that the Jini community can give us as much feedback as possible. Security is really hard. The more people we have looking at it, the more likely we'll get it right.

One of the other great things about Jini has been the Jini community -- a bunch of people who aren't part of the official Jini team, who have adopted the technology, and are interested enough in the technology to work on it and contribute to its development. So, for example, Bill Venners, to pick a random example, who is now in the room, did the service UI work. That's as much a part of the core Jini specification as anything else, even though it hasn't been fully blessed by the Jini community, because we're still figuring out how to do that full blessing. But it's a de facto standard. People are just using it because it's good work.

And we have other people in the community doing things that really expand the notion of who develops Jini. The core Jini team is doing some stuff, but other Jini developments are going on by people who are just as good as the core team. It is a community effort. They're doing it because they believe in it, they think it's good stuff, and they want to contribute to that. So I don't know what's next for Jini, because other people are doing a lot of interesting stuff as well.

Frank Sommers is founder and CEO of Autospaces, a company focused on bringing Jini technology to the automotive software market. Bill Venners has been writing software professionally for 14 years. Based in Silicon Valley, he provides software consulting and training services at Artima Software. He is the author of Inside the Java 2 Virtual Machine (Enterprise Computing, October 1999) and creator of Artima.com, a resource for Java and Jini developers.

Learn more about this topic

Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more