Advanced Customization > Services and Infrastructure Customization > Developing Server Logic > Lightweight Services
  
Lightweight Services
Lightweight services reside in the application layer between the client and the business service layer. Lightweight services are light because they do not start automatically and dispatch events. Consequently, lightweight services are not specified in the wt.properties file with wt.services entries.
Lightweight service methods should be designed to do the following:
Reduce the number of round trips between the client and the server.
Provide task-specific and higher-level functionality than business service methods.
Ensure client transactional integrity.
Lightweight services can dispatch events but should not listen for them. If a service is not started automatically, it will not be able to hear events that it is supposed to listen for until it is started.
Lightweight services are an effective means to ensure client transactional integrity. Several client-server operations can be grouped into a single, lightweight service method call that will carry out these operations on the server in a single transaction.
Lightweight services can be implemented in the following two ways:
Through a modeled class that extends wt.services.StandardManager
Through a non-modeled, inner class that implements wt.method.RemoteAccess
The following subsections describe both implementations.
The Modeling Implementation
Lightweight services are modeled like business services in that they are defined by a remote interface and have an implementation class that extends StandardManager. The remote interface enables the service to run in the method server and be invoked by remote clients (for example, standalone JAVA client). The mapping between the service interface and implementation class is accomplished with a naming convention. The implementation class for a lightweight service must have the same name as the interface with "Standard" at the beginning of the name.
To use a lightweight service, create an instance of the generated Forwarder class and call the service’s methods through the Forwarder. This is similar to a business service where a static attribute on the Helper class is initialized with an instance of the Forwarder class. In both cases, the mechanism for invoking service operations is identical.
Example: A lightweight service named CommentLogger can be found in WTDesigner.mdl in the wt.services.test package. The CommentLogger interface defines a lightweight service that will log a message to the server log file. This service could be useful for standalone JAVA clients that want to include a message in the server log. Without such a service, all System.out.println calls will send their output to the browser’s Java console window instead of the server log file. StandardCommentLogger implements this service by extending wt.services.StandardManager and the CommentLogger interface. Note that the name must be StandardCommentLogger in order for the ManagerService to find the implementation class for the CommentLogger service. Since CommentLogger has a stereotype of RemoteInterface, a Forwarder class named CommentLoggerFwd is automatically generated. It is this class that is used to invoke the CommentLogger service methods:
CommentLoggerFwd logger = new CommentLoggerFwd();
logger.log("a message");
The Inner Class Implementation
The second way of implementing a lightweight service is through a non-modeled, inner class that implements wt.method.RemoteAccess. An example of an inner class implementation follows. The objectives are to invoke a complex server-side activity, collecting information of interest to the client, while minimizing the number of classes loaded by the client. These techniques improve performance for the client because loading classes can be slow and expensive.
In this example, note the type of the inner class. To avoid IllegalAccess violations, the forwarder must be declared as a "public static class". Using this declaration, the MethodServer is able to instantiate and invoke methods on the inner class.
Note also the technique for invocation of the desired server method. To avoid loading classes specified as part of the action to be carried out in the MethodServer, we specify the target inner class and method of interest as Strings. Any reference to the class itself will cause it and all the classes it needs to be loaded into the client VM, which is not desirable.