Summary
When you look at the complexity of web services configuration, the extent of tool involvement and the plethora of standards that are being created to solve the ever growing list of shortcommings, it is a wonder that anyone is making progress. Jini has already solved these problems!
Advertisement
Web Services Developers and Vendors are Relearning
All of these problems that the new set of WS-standards are trying to
address have been solved before. The simple requirement of XML messaging is forcing everyone to dance the XML tune across the board.
I've heard others say similar things about Jini. The startup cost of both platforms can be significant, if you take the wrong approach. But, what I see is that the WS-crowd doesn't really lower the barrier as much as hide it behind endless tools that reduce flexibilty and aim you at solving problems the same way each time.
My years of experience with Jini have caused me to develop some tools that enhance the speed at which I can develop a Jini service. The WS-tools seem to enable people to create the same common solution over and over.
I am going to show here how I would create the same solution that is in the article, but using Jini. The only issue is that I am not going to show the use of SOAP for RPC. The JERI stack is plugable, and an RMI to SOAP translator could be put in place that would have access to the appropriate WSDL to generate all the necessary XML for the call. I haven't done that because my services don't talk to SOAP entities. There are statments such as
Jini is nowhere nearly as complex to set up as CORBA is...no need for IDLS,
etc. Jini's got a much smaller footprint than CORBA...where it fails to
compete is over multi-language development environments...it's absolutely
Java Centric...whereas CORBA isn't!
that make it clear that JERI is not a visible part of the Jini solution to most developers.
In JAX-RPC, we'd never create the interface ourselves, we'd let the tools do it from the WSDL. In Jini, the interface is the firstclass representation of the service contract, we don't have any other representation of that, so we define the interface as in
import java.rmi.*;
public interface Time extends Remote {
public String sayTimeBack(String) throws RemoteException;
}
The Service Definition
With Jini, we need to handle the service registration process and manage the persistence of the ServiceID value that we get on the initial registration. There are straight forward steps needed to make that happen. I created a class which does all of this for me and which I can subclass to create my service. This is a tool that is part of the software, instead of a tool that is external to the software such as the IDE based wizards found in J2EE IDEs.
import org.wonderly.jini2.*;
import net.jini.config.*;
import java.util.Date;
public class TimeImpl extends PersistentJiniService implements Time {
public static void main( String args[] ) throws Exception {
new TimeImpl( args );
}
public TimeImpl( String args[] ) throws ConfigurationException {
super( args );
startService( "Time Service", "timeserv.ser" );
}
public String sayTimeBack(String) throws RemoteException {
Date date = new Date(System.currentTimeMillis());
String result = " Hello, " + str
+ ". The time on the server is "
+ date.toString();
return result;
}
}
Jini differs with WS-programming in that configuration is more dynamic with the new Jini2.0 Configuration interface. In this example, I've used the startnow project's classes that I created. These classes make it straight forward to create a Jini service.
The Client
A client that uses this service could have a wide range of ways that the service might be invoked. The ServiceDiscoveryManager (SDM) provides a simple way to use services. For uses that are synchronous, this class is the one to use for most needs. If you need a more asynchronous mechanism, the LookupDiscovery or LookupLocatorDiscovery classes can tell you dynamically about the appearance of services.