The preferred means of accessing services is through JNDI. However, not all services are appropriate for JNDI binding. For example, they might not be remotable, might require additional security, or might not make good design sense within the context of remote naming services. So for the cases when JNDI is not appropriate for one of these reasons, services possess convenience methods inherited through the ServiceAdapter for looking up and referencing other services. Alternatively, a service can make direct use of JMX, although this tightens the service's coupling to the JMX infrastructure and requires use of the JMX MBeanServer (see the JMX API).
Services are not bound to JNDI by default, but can be automatically bound if the service's jrun.xml definition specifies a bindToJNDI attribute that is set to true, as the following example shows:
<attribute name="bindToJNDI">true</attribute>
Note: Alternatively, you can call the service's setBindToJNDI(boolean) method, passing true.
When bound to JNDI, services are available under the following namespace:
The following example looks up the LoggerService (assuming that the bindToJNDI attribute is set to true for the LoggerService) and uses the logInfo method to write to the JRun log file:
...
import jrunx.logger.LoggerService;
...
try {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "jrun.naming.JRunContextFactory");
p.put(Context.PROVIDER_URL, "localhost:2918");
InitialContext ctx = new InitialContext(p);
LoggerService ls = (LoggerService) ctx.lookup("jrun:service/LoggerService");
ls.logInfo("Message logged using LoggerService");
} // end try
catch (Exception e) {
System.out.println(e);
}
...
For all services that extend jrunx.kernel.ServiceAdapter (including jrunx.kernel.ServicePartition), there are a series of convenience methods for accessing other running services, including the following methods:
lookup method first searches for the service in the current partition (if one exists), and then searches for the service in the default partition. For example, if the current service is part of the ejb partition in the default server, and the following is called:
SchedulerService scheduler = (SchedulerService) lookup("SchedulerService");
the lookup method will first search for java:comp/jrun/default/ejb/SchedulerService. If a service is not bound at that location, lookup then searches for java:comp/jrun/default/SchedulerService. If no service is found, lookup returns null.
lookup method, the findObjectInstance method first searches for the service in the current partition (if one exists), and then searches for the service in the default partition. After an ObjectInstance is found it can be used to invoke methods that are exposed through its MBean interface, as the following example shows:...
// Get the scheduler
javax.management.ObjectInstance oi = findObjectInstance("SchedulerService");
if (oi != null)
{
try
{
// Invoke the scheduler
Object[] params = new Object[] { this, new Long(interval) };
String[] types = new String[] { "java.lang.Runnable", "long" };
invokeMethod(oi.getObjectName(), "scheduleFromNow", params, types);
}
catch (Exception ex)
{
debug(ex);
}
}
...
Note: The convenience method, invokeMethod, is a wrapper around the MBeanServer invoke method.
The JMX specification prohibits users from directly referencing services by type. Instead, services return ObjectInstance and ObjectName objects that are used to invoke service methods through the MBeanServer. For details, see the JMX specification.
Typically, custom services use either JNDI or convenience methods, as described in "Creating services".
Send me an e-mail when comments are added to this page | Comment Report
Current page: http://livedocs.adobe.com/jrun/4/JRun_SDK_Guide/creatingservices4.htm