From: Bryan T. <tho...@us...> - 2007-03-22 15:04:59
|
Update of /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv20431/src/test/org/CognitiveWeb/bigdata/jini Modified Files: TestServiceDiscovery.java TestServer.java ITestService.java Added Files: TestServer.config Log Message: Working on services. Added some JARs for dependencies to simplify deployment. Index: TestServiceDiscovery.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini/TestServiceDiscovery.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** TestServiceDiscovery.java 18 Mar 2007 22:29:43 -0000 1.3 --- TestServiceDiscovery.java 22 Mar 2007 15:04:12 -0000 1.4 *************** *** 49,52 **** --- 49,53 ---- import java.io.IOException; import java.net.InetAddress; + import java.rmi.ConnectException; import junit.framework.TestCase; *************** *** 210,213 **** --- 211,225 ---- } + /* + * try service invocation again. if the service lease is canceled before + * we do this then we should see an exception here. + */ + try { + service.invoke(); + fail("Expecting "+ConnectException.class); + } catch(ConnectException ex) { + log.info("Ignoring expected exception: "+ex); + } + } --- NEW FILE: TestServer.config --- import java.io.*; import net.jini.jeri.BasicILFactory; import net.jini.jeri.BasicJeriExporter; import net.jini.jeri.tcp.TcpServerEndpoint; import net.jini.core.discovery.LookupLocator; import net.jini.discovery.LookupDiscovery; import net.jini.core.entry.Entry; import net.jini.lookup.entry.Name; import net.jini.lookup.entry.Comment; import net.jini.lookup.entry.Address; import net.jini.lookup.entry.Location; import net.jini.lookup.entry.ServiceInfo; //import org.CognitiveWeb.bigdata.jini.TestServer$MyStatus; //import org.CognitiveWeb.bigdata.jini.TestServer$MyServiceType; import java.io.File; import com.sun.jini.config.ConfigUtil; import com.sun.jini.start.ServiceDescriptor; import com.sun.jini.start.NonActivatableServiceDescriptor; /* * Declares how the service will provision itself. */ ServiceDescription { /* * This object is used to export the service proxy. The choice here effects * the protocol that will be used for communications between the clients and * the service. * * @todo Explore JERI nio option and customization support for serialization. */ exporter = new BasicJeriExporter(TcpServerEndpoint.getInstance(0), new BasicILFactory()); /* * @todo test ability to resolve classes in JAR directly. what about an * array of codebases? */ private static codebase = "http://proto.cognitiveweb.org/maven-repository/bigdata/jars/bigdata.jar"; /* @todo restrict the policy to what is actually required by the service. * Among other things, we only need access to a temporary directory and * to the directory in which the journals and index segments will be * stored, not general read/write on the disk. */ private static policy = "policy.all"; /* * The directory containing the various JARs. */ private static libdir = "ant-deploy/"+File.separator; /* * Declare dependencies for the server here. */ private static classpath = // jini libdir+"reggie.jar"+File.pathSeparator+ libdir+"jini-core.jar"+File.pathSeparator+ libdir+"jini-ext.jar"+File.pathSeparator+ libdir+"sun-util.jar"+File.pathSeparator+ // utility JARs. libdir+"log4j-1.2.8.jar"+File.pathSeparator+ libdir+"ctc_utils-5-4-2005.jar"+File.pathSeparator+ libdir+"lgpl-utils-1.0-b1-dev.jar"+File.pathSeparator+ libdir+"cweb-extser-0.1-b2-dev.jar"+File.pathSeparator+ // ICU (unicode support). libdir+"icu4j-3_6.jar"+File.pathSeparator+ // test suites only! libdir+"junit-3.8.1.jar"+File.pathSeparator+ libdir+"cweb-junit-ext-1.1-b2-dev.jar"+File.pathSeparator+ // main bigdata JAR. libdir+"bigdata.jar" ; /* * Configuration file for the service itself. * * @todo The name of this file will be pass to the service implementation * constructor. It should probably be a file that can be read as a Properties * object. */ private static config = "resources/starter/file_classifier.config"; static serviceDescriptors = new ServiceDescriptor[] { new NonActivatableServiceDescriptor( codebase, policy, classpath, "config.FileClassifierServerConfig", new String[] { config }) }; } /* * Declares how the service will advertise itself. */ AdvertDescription { /* * Entry attributes used to describe the service. */ entries = new Entry[] { new Comment("Test service"), // human facing comment. new Name("Test service"), // human facing name. // new MyServiceType("Test service", /*display name*/ // "Test Service" /*short description*/), // service type // new MyStatus(StatusType.NORMAL), new Location("floor","room","building"), new Address("street", "organization", "organizationalUnit", "locality", "stateOrProvince", "postalCode", "country"), new ServiceInfo("bigdata", // product or package name "SYSTAP,LLC", // manufacturer "SYSTAP,LLC", // vendor "0.1-beta", // version "bigdata", // model "serial#" // serialNumber ) }; /* * Note: multicast discovery is always used if LookupDiscovery.ALL_GROUPS is * specified. */ // groups = LookupDiscovery.ALL_GROUPS; groups = new String[]{"bigdata"}; /* * One or more unicast URIs of the form jini://host/ or jini://host:port/. * This MAY be an empty array if you want to use multicast discovery _and_ * you have specified LookupDiscovery.ALL_GROUPS above. */ unicastLocators = new LookupLocator[] { // empty new LookupLocator("jini://localhost/") // new LookupLocator("jini://SYSTAP-BBT.systap.com/") }; serviceIdFile = new File("serviceId.id"); } Index: ITestService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini/ITestService.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ITestService.java 18 Mar 2007 22:29:43 -0000 1.1 --- ITestService.java 22 Mar 2007 15:04:13 -0000 1.2 *************** *** 63,73 **** * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ ! * ! * @client This interface must be available to the client in order for it to ! * execute the methods defined by the interface without the use of ! * reflection. ! * ! * @server This interface must be available to the server since it exposes this ! * interface on its service. */ public interface ITestService extends Remote --- 63,67 ---- * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ ! * @download */ public interface ITestService extends Remote Index: TestServer.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini/TestServer.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** TestServer.java 18 Mar 2007 22:29:43 -0000 1.3 --- TestServer.java 22 Mar 2007 15:04:13 -0000 1.4 *************** *** 49,79 **** import java.io.IOException; import java.rmi.Remote; ! import java.rmi.RemoteException; import net.jini.admin.JoinAdmin; import net.jini.core.entry.Entry; - import net.jini.core.lease.Lease; import net.jini.core.lookup.ServiceID; - import net.jini.core.lookup.ServiceItem; - import net.jini.core.lookup.ServiceRegistrar; - import net.jini.core.lookup.ServiceRegistration; import net.jini.discovery.DiscoveryEvent; ! import net.jini.discovery.DiscoveryListener; import net.jini.discovery.LookupDiscovery; import net.jini.export.Exporter; - import net.jini.export.ProxyAccessor; import net.jini.id.Uuid; import net.jini.id.UuidFactory; - import net.jini.jeri.BasicILFactory; - import net.jini.jeri.BasicJeriExporter; - import net.jini.jeri.tcp.TcpServerEndpoint; import net.jini.lease.LeaseListener; import net.jini.lease.LeaseRenewalEvent; import net.jini.lease.LeaseRenewalManager; ! import net.jini.lookup.entry.Address; ! import net.jini.lookup.entry.Comment; ! import net.jini.lookup.entry.Location; ! import net.jini.lookup.entry.Name; ! import net.jini.lookup.entry.ServiceInfo; import net.jini.lookup.entry.ServiceType; import net.jini.lookup.entry.Status; --- 49,72 ---- import java.io.IOException; import java.rmi.Remote; ! import java.rmi.server.ExportException; import net.jini.admin.JoinAdmin; + import net.jini.config.Configuration; + import net.jini.config.ConfigurationException; + import net.jini.config.ConfigurationProvider; + import net.jini.core.discovery.LookupLocator; import net.jini.core.entry.Entry; import net.jini.core.lookup.ServiceID; import net.jini.discovery.DiscoveryEvent; ! import net.jini.discovery.DiscoveryManagement; import net.jini.discovery.LookupDiscovery; + import net.jini.discovery.LookupDiscoveryManager; import net.jini.export.Exporter; import net.jini.id.Uuid; import net.jini.id.UuidFactory; import net.jini.lease.LeaseListener; import net.jini.lease.LeaseRenewalEvent; import net.jini.lease.LeaseRenewalManager; ! import net.jini.lookup.JoinManager; import net.jini.lookup.entry.ServiceType; import net.jini.lookup.entry.Status; *************** *** 82,85 **** --- 75,80 ---- import org.apache.log4j.Logger; + import com.sun.jini.start.ServiceStarter; + /** * Launches a server used by the test. The server is launched in a separate *************** *** 88,141 **** * invocation and one to shutdown the server. * - * @todo Look into the manager classes for service joins, discovery, etc. The - * code in this class can probably be simplified drammatically. - * * @version $Id$ * @author <a href="mailto:tho...@us...">Bryan Thompson * </a> */ ! public class TestServer implements DiscoveryListener, LeaseListener { ! public static Logger log = Logger.getLogger(TestServer.class); ! private ServiceID serviceID; ! private ServiceItem item; ! private ServiceRegistration reg; ! final private LeaseRenewalManager leaseManager = new LeaseRenewalManager(); /** * Server startup performs asynchronous multicast lookup discovery. The ! * {@link #discovered(DiscoveryEvent)}method is invoked asynchronously ! * to register {@link TestServerImpl}instances. */ ! public TestServer() { ! /* ! * Generate a ServiceID ourselves. This makes it easier to register the ! * same service against multiple lookup services. ! * ! * @todo If you want to restart (or re-register) the same service, then ! * you need to read the serviceID from some persistent location. If you ! * are using activation, then the service can be remotely started using ! * its serviceID which takes that responsibility out of your hands. When ! * using activation, you will only create a serviceID once when you ! * install the service onto some component and activition takes ! * responsiblity for starting the service on demand. ! */ ! Uuid uuid = UuidFactory.generate(); ! serviceID = new ServiceID(uuid.getMostSignificantBits(), ! uuid.getLeastSignificantBits()); try { ! LookupDiscovery discover = new LookupDiscovery( ! LookupDiscovery.ALL_GROUPS); ! discover.addDiscoveryListener(this); } catch (IOException ex) { ! throw new RuntimeException(ex); } --- 83,239 ---- * invocation and one to shutdown the server. * * @version $Id$ * @author <a href="mailto:tho...@us...">Bryan Thompson * </a> + * + * @todo work through use the {@link ServiceStarter} (in start.jar). I am + * having trouble getting past some classpath errors using + * <pre> + java -Djava.security.policy=policy.all -classpath ant-deploy\reggie.jar;ant-deploy\jini-core.jar;ant-deploy\jini-ext.jar;ant-deploy\sun-util.jar;ant-deploy\bigdata.jar -jar ant-deploy\start.jar src\test\org\CognitiveWeb\bigdata\jini\TestServer.config + * </pre> + * + * @todo The serviceID should probably be persisted as a named root object in + * the journal. Each resource (journal or index segment) should also + * have its own UUID. Finally, each index name should have its own UUID. */ ! public class TestServer implements LeaseListener /*, ServiceIDListener*/ { ! public static final transient Logger log = Logger ! .getLogger(TestServer.class); ! private ServiceID serviceID; ! private DiscoveryManagement discoveryManager; ! private JoinManager joinManager; ! private Configuration config; ! private TestServiceImpl impl; ! private Exporter exporter; ! private ITestService proxy; /** * Server startup performs asynchronous multicast lookup discovery. The ! * {@link #discovered(DiscoveryEvent)} method is invoked asynchronously to ! * register a proxy for a {@link TestServiceImpl} instance. The protocol for ! * remote communications between the proxy and the {@link TestServiceImpl} ! * is specified by a {@link Configuration}. ! * ! * @todo use a specific group (bigdata) for discovery. ! * ! * @todo support NIO protocol for data intensive APIs (data service, file ! * transfer). Research how heavy mashalling is and what options exist ! * to make it faster and lighter. */ ! public TestServer(String[] args) { ! final String SERVICE_LABEL = "ServiceDescription"; ! ! final String ADVERT_LABEL = "AdvertDescription"; ! ! Entry[] entries = null; ! LookupLocator[] unicastLocators = null; ! // File serviceIdFile = null; ! String[] groups = null; ! ! serviceID = getServiceID(); try { + + config = ConfigurationProvider.getInstance(args); ! /* ! * Extract how the service will perform service discovery. ! */ ! ! groups = (String[]) config.getEntry(ADVERT_LABEL, "groups", ! String[].class, LookupDiscovery.ALL_GROUPS/* default */); ! ! unicastLocators = (LookupLocator[]) config.getEntry( ! ADVERT_LABEL, "unicastLocators", ! LookupLocator[].class, null/* default */); ! ! /* ! * Extract how the service will advertise itself from the ! * Configuration. ! */ ! ! entries = (Entry[]) config.getEntry(ADVERT_LABEL, "entries", ! Entry[].class, null/* default */); ! ! // serviceIdFile = (File) config.getEntry(ADVERT_LABEL, ! // "serviceIdFile", File.class, null); // default ! /* ! * Extract how the service will provision itself from the ! * Configuration. ! * ! * @todo extract a Properties object to hand to the Journal ! * constructor. Some things should be injected after the ! * fact, such as the serviceID. ! */ ! ! // use the configuration to construct an exporter ! exporter = (Exporter) config.getEntry(// ! SERVICE_LABEL, // component ! "exporter", // name ! Exporter.class // type (of the return object) ! ); ! ! // create the service object (and its proxy). ! impl = new TestServiceImpl(config); ! ! // export a proxy object for this service instance. ! proxy = (ITestService) exporter.export(impl); ! ! log.info("Proxy is " + proxy + "(" + proxy.getClass() + ")"); ! ! } catch(ConfigurationException ex) { ! ! log.fatal("Configuration error: "+ex, ex); ! ! System.exit(1); ! ! } catch (ExportException ex) { ! ! log.fatal("Export error: "+ex, ex); ! ! System.exit(1); ! ! } ! ! try { ! ! /* ! * Note: This class will perform multicast discovery if ALL_GROUPS ! * is specified and otherwise requires you to specify one or more ! * unicast locators (URIs of hosts running discovery services). As ! * an alternative, you can use LookupDiscovery, which always does ! * multicast discovery. ! */ ! discoveryManager = new LookupDiscoveryManager( ! groups, unicastLocators, null // DiscoveryListener ! ); ! ! // DiscoveryManagement discoveryManager = new LookupDiscovery( ! // groups); ! ! // @todo use ServiceIDListener? ! joinManager = new JoinManager(proxy, // service proxy ! entries, // attr sets ! serviceID, // ServiceIDListener ! discoveryManager, // DiscoveryManager ! new LeaseRenewalManager()); } catch (IOException ex) { ! log.fatal("Lookup service discovery error: "+ex, ex); ! ! try { ! /* unexport the proxy */ ! unexport(true); ! } catch (Throwable t) { ! /* ignore */ ! } ! ! System.exit(1); } *************** *** 143,272 **** } /** ! * Log a message and register the {@link TestServerImpl}. Events are ! * aggregated but we can still receive multiple events depending on the ! * latency between discovery of various service registrars. Since the ! * multicast protocol was used to discover service registrars, we can wind ! * up registering with more than one registrar. * ! * @todo If we do not receive this message after some timeout then the ! * server should log an error (in main()) and exit with a non-zero ! * status code. This means that the service needs to expose an ! * indicator of whether or not it has been registered. * ! * @todo Modify service proxy to use RMI. The client stub should be ! * downloaded from the codebase and should know how to commuicate with ! * the discovered service, e.g., using RMI or a custom NIO protocol. * ! * @todo This should be a fast operation and should not make remote calls. ! * Service registration therefore needs to happen in another thread so ! * that the service registrar can continue about its business. */ ! public void discovered(DiscoveryEvent evt) { ! ! /* ! * At this point we have discovered one or more lookup services. ! */ ! registerService( evt.getRegistrars() ); ! } ! ! /** ! * Registers a service proxy with each identified registrar. The ! * registration happens in another thread to keep the latency down for the ! * {@link DiscoveryListener#discovered(net.jini.discovery.DiscoveryEvent)} ! * event. ! * ! * @param registrars ! * One or more service registrars. ! */ ! private void registerService( final ServiceRegistrar[] registrars ) { ! ! log.info("Discovered "+registrars.length+" service registrars"); ! ! new Thread("Register Service") { ! public void run() { ! // the service ! Object impl = new TestServerImpl().getProxy(); ! // Create an information item about a service ! item = new ServiceItem(serviceID, impl, new Entry[] { ! new Comment("Test service(comment)"), // human facing comment. ! new Name("Test service(name)"), // human facing name. ! new MyServiceType("Test service (display name)", ! "Test Service (short description)"), // service type ! new MyStatus(StatusType.NORMAL), ! new Location("floor","room","building"), ! new Address("street", "organization", "organizationalUnit", ! "locality", "stateOrProvince", "postalCode", ! "country"), ! new ServiceInfo("bigdata", // product or package name ! "SYSTAP,LLC", // manufacturer ! "SYSTAP,LLC", // vendor ! "0.1-beta", // version ! "bigdata", // model ! "serial#" // serialNumber ! ) }); ! ! for (int i = 0; i < registrars.length; i++) { ! /* ! * Register a service. The service requests a "long" lease using ! * Lease.FOREVER. The registrar will decide on the actual length ! * of the lease. ! */ ! ServiceRegistrar registrar = registrars[i]; ! while (reg == null) { ! try { ! // Register the service. ! reg = registrar.register(item, Lease.FOREVER); ! /* ! * Setup automatic lease renewal. ! * ! * Note: A single lease manager can handle multiple services ! * and the lease of a given service on multiple service ! * registrars. It knows which lease is about to expire and ! * preemptively extends the lease on the behalf of the ! * registered service. It will notify the LeaseListener iff ! * it is unable to renew a lease. ! */ ! log.info("lease will expire in " ! + (reg.getLease().getExpiration() - System ! .currentTimeMillis()) + "ms"); ! leaseManager ! .renewUntil(reg.getLease(), Lease.FOREVER, TestServer.this); ! /* ! * Service has been registered and lease renewal is ! * operating. ! */ ! break; ! } catch (RemoteException ex) { ! // retry until successful. ! try { ! Thread.sleep(100); ! } catch (InterruptedException ex2) { ! } ! } ! } ! } ! } ! }.start() ! ; } /** ! * Log a message. */ ! public void discarded(DiscoveryEvent arg0) { ! ! log.info(""); ! } /** ! * Note: This is only invoked if the automatic lease renewal by the ! * lease manager is denied by the service registrar. In that case we ! * should probably update the Status to indicate an error condition. */ public void notify(LeaseRenewalEvent event) { --- 241,326 ---- } + // /* + // * @todo look into this as an alternative means to shutdown a service. + // */ + // void shutdown() { + // try { + // Object admin = ((Administrable) proxy).getAdmin(); + // DestroyAdmin destroyAdmin = (DestroyAdmin) admin; + // destroyAdmin.destroy(); + // } catch (RemoteException e) { // handle + // // exception + // // + // } + // } + /** ! * Unexports the proxy. * ! * @param force ! * When true, the object is unexported even if there are pending ! * or in progress service requests. * ! * @return true iff the object is (or was) unexported. * ! * @see Exporter#unexport(boolean) */ ! public boolean unexport(boolean force) { ! if(exporter.unexport(true)) { ! proxy = null; + return true; + } + + return false; + } /** ! * Generate a ServiceID ourselves. This makes it easier to register the same ! * service against multiple lookup services. ! * ! * @todo If you want to restart (or re-register) the same service, then you ! * need to read the serviceID from some persistent location. If you ! * are using activation, then the service can be remotely started ! * using its serviceID which takes that responsibility out of your ! * hands. When using activation, you will only create a serviceID once ! * when you install the service onto some component and activition ! * takes responsiblity for starting the service on demand. */ ! private ServiceID getServiceID() { ! Uuid uuid = UuidFactory.generate(); ! ! return new ServiceID(uuid.getMostSignificantBits(), ! uuid.getLeastSignificantBits()); ! ! } ! ! // /** ! // * @todo implement {@link ServiceIDListener} and pass into the ! // * {@link JoinManager} constructor if you want to use a persistent ! // * {@link ServiceID}. This method is responsible for saving the ! // * serviceID on stable storage when it is invoked. ! // * ! // * @param serviceID ! // */ ! // public void serviceIDNotify(ServiceID serviceID) { ! // ! // log.info("serviceID=" + serviceID); ! // ! // } /** ! * Note: This is only invoked if the automatic lease renewal by the lease ! * manager is denied by the service registrar. ! * ! * @todo how should we handle being denied a lease? Wait a bit and try ! * re-registration? There can be multiple discovery services and this ! * is only one lease rejection, so perhaps the service is still under ! * lease on another discovery service? */ public void notify(LeaseRenewalEvent event) { *************** *** 278,288 **** /** * Launch the server in a separate thread. */ public static void launchServer() { new Thread("launchServer") { public void run() { ! TestServer.main(new String[] {}); } }.start(); } --- 332,347 ---- /** * Launch the server in a separate thread. + * <p> + * Note: The location of the test service configuration is hardwired to a + * test resource. */ public static void launchServer() { new Thread("launchServer") { public void run() { ! TestServer ! .main(new String[] { "src/test/org/CognitiveWeb/bigdata/jini/TestServer.config" }); } }.start(); + log.info("Starting service."); } *************** *** 294,300 **** */ public static void main(String[] args) { ! final long lifespan = 3 * 60 * 1000; // life span in seconds. log.info("Will start test server."); ! TestServer testServer = new TestServer(); log.info("Started test server."); try { --- 353,359 ---- */ public static void main(String[] args) { ! final long lifespan = 5 * 1000; // life span in seconds. log.info("Will start test server."); ! TestServer testServer = new TestServer(args); log.info("Started test server."); try { *************** *** 305,311 **** } /* ! * @todo This forces a hard reference to remain for the test server. */ ! log.info("Server will die: "+testServer); } --- 364,392 ---- } /* ! * Terminate manager threads. */ ! try { ! log.info("Terminating manager threads."); ! testServer.joinManager.terminate(); ! testServer.discoveryManager.terminate(); ! } catch (Exception ex) { ! log.error("Could not terminate: "+ex, ex); ! } ! /* ! * Unexport the proxy, making the service no longer available. If you do ! * not do this then the client can still make requests even after you ! * have terminated the join manager and the service is no longer visible ! * in the service browser. ! */ ! log.info("Unexporting the service proxy."); ! testServer.unexport(true); ! ! // /* ! // * Note: The reference to the service instance here forces a hard ! // * reference to remain for the test server. If you comment out this log ! // * statement, then you need to do something else to hold onto the hard ! // * reference. ! // */ ! // log.info("Server will die: "+testServer); } *************** *** 316,319 **** --- 397,401 ---- * @version $Id$ * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @download */ public static class MyStatus extends Status { *************** *** 351,354 **** --- 433,437 ---- * @author <a href="mailto:tho...@us...">Bryan Thompson * </a> + * @download */ public static class MyServiceType extends ServiceType *************** *** 397,550 **** * </a> */ ! public static class TestServerImpl implements ProxyAccessor, ITestService/*, Serializable*/ { /** - * Note: Mark the {@link Logger} as transient since we do NOT need to - * serialize its state. - * <p> - * - * @todo When the service uses a proxy and a remote communications - * protocol, the service instance is remote and this object is not - * instantiated on the client (test this hypothesis by removing - * log4j from the codebase). - */ - public static final transient Logger log = Logger.getLogger(TestServerImpl.class); - - // Note required when using a service proxy. the Exporter handles the proxy generation. - // /** - // * - // */ - // private static final long serialVersionUID = -920558820563934297L; - - /** - * The location of the JERI configuration file. - * - * @todo provide a command line option to override the file location. - */ - private transient static String CONFIG_FILE = "jeri/jeri.config"; - - private ITestService proxy; - - // /** - // * - // * @param args - // * @throws Exception - // * - // * @see http://jan.newmarch.name/java/jini/tutorial/Jeri.xml for an - // * explanation of what is going on here. - // */ - // public static void main(String[] args) throws Exception { - // - // String[] configArgs = new String[] { CONFIG_FILE }; - // - // // get the configuration (by default a FileConfiguration) - // Configuration config = ConfigurationProvider - // .getInstance(configArgs); - // System.out.println("Configuration: " + config.toString()); - // - // // and use the configuration to construct an exporter - // Exporter exporter = (Exporter) config.getEntry( - // // - // TestServerImpl.class.getName(), // component - // "exporter", // name - // Exporter.class, // type (of the return object) - // new BasicJeriExporter(TcpServerEndpoint.getInstance(0), - // new BasicILFactory()) /* default */,// - // Configuration.NO_DATA // data. - // ); - // - // // export an object of this class - // Remote proxy = exporter.export(new TestServerImpl()); - // System.out.println("Proxy is " + proxy.toString()); - // - // // now unexport it once finished - // exporter.unexport(true); - // - // } - - /* - * @todo presumably service shutdown should clear the proxy reference - * once the service has been removed from the registry. - */ - public Object getProxy() { - - return proxy; - - } - - /** * Service constructor. * ! * @todo can the constructor accept arguments? */ ! public TestServerImpl() /*@todo throws RemoteException ?*/ { ! ! /* ! * @todo when this is added the test will succeed the first time but ! * thereafter will fail with a connection refused to the end point ! * for the _expired_ service. While that exception makes sense in ! * that the expired service should not be connectable, I do not ! * understand why adding or dropping this line has any influence. ! * Perhaps the problem is that it changes GC behavior and the prior ! * test service is otherwise NOT expired? Look into what this ! * service is doing to shutdown after the test and what is should ! * be doing. ! * ! * So - the test does NOT attempt to close down the service - I was ! * deliberately leaving it open so that I could explore the service ! * in the Service Browser. The issue may be that this replaces the ! * SecurityManager after one was already installed in the VM by the ! * test itself! ! */ ! // System.setSecurityManager(new SecurityManager()); ! ! try { ! ! // @todo work out use of a configuration file. ! // String[] configArgs = new String[] { CONFIG_FILE }; ! // ! // // get the configuration (by default a FileConfiguration) ! // Configuration config = ConfigurationProvider ! // .getInstance(configArgs); ! // System.out.println("Configuration: " + config.toString()); ! // ! // // and use the configuration to construct an exporter ! // Exporter exporter = (Exporter) config.getEntry( ! // // ! // TestServerImpl.class.getName(), // component ! // "exporter", // name ! // Exporter.class, // type (of the return object) ! // new BasicJeriExporter(TcpServerEndpoint.getInstance(0), ! // new BasicILFactory()) /* default */,// ! // Configuration.NO_DATA // data. ! // ); ! ! // hardwired jeri exporter using TCP. ! Exporter exporter = new BasicJeriExporter(TcpServerEndpoint ! .getInstance(0), new BasicILFactory()); ! ! // export an object of this class ! proxy = (ITestService) exporter.export(this); ! log.info("Proxy is " + proxy + "(" + proxy.getClass() + ")"); ! } catch(Exception ex) { ! // @todo should we retry the operation? ! log.error(ex); ! throw new RuntimeException(ex); ! } - // @todo who will unexport the proxy? - - // // now unexport it once finished - // exporter.unexport(true); - - // System.err.println("Created: "+this); - log.info("Created: "+this); } public void invoke() { ! // System.err.println("invoked: "+this); log.info("invoked: "+this); } --- 480,502 ---- * </a> */ ! public static class TestServiceImpl implements ITestService { /** * Service constructor. * ! * @throws ConfigurationException */ ! public TestServiceImpl(Configuration config) ! throws ConfigurationException { ! log.info("Created: " + this ); } public void invoke() { ! log.info("invoked: "+this); + } |