In this topic
- About utility objects
- Using utility objects
- Writing a utility object
- Defining a custom interface
- Defining a Java class that implements the custom interface
- Implementing the custom interface
- Deploying the utility object
- Consuming a utility object
About utility objects
A utility object is a Java extension that encapsulates geographic information system (GIS) functionality that is achieved by making fine-grained ArcObjects calls and exposes that functionality through a coarse-grained application user interface (API), ensuring that the fine-grained ArcObjects calls do not cross process or thread boundaries. Utility objects are used to improve performance of ArcGIS for Server and ArcGIS Engine applications. Typically, applications that make lots of fine-grained ArcObjects calls across process or thread boundaries tend to suffer from poor performance because of the cost of round trips incurred by the calls. Utility objects are used to eliminate these cross-context calls and hence improve application performance.
Extending ArcGIS for Server with utility objects allows you to easily share your components across the ArcGIS developer products, such as ArcGIS for Server and ArcGIS Engine. These utility objects do not need to be tied to any particular server object configuration or type and can even be used in an empty server context.
This strategy does have some limitations. When extending the GIS server with a utility object, the object must be created for each request made on a particular server object or context. This means that for pooled server objects, each time a request is made, the utility object must be created, which can affect performance if there is a high initialization cost. Because the object is created for each request, you can't use it to cache information through its lifecycle.
A major advantage of utility objects is that they can be used to alleviate performance problems caused by the overhead of making fine-grained ArcObjects calls across threads (between Java threads and ArcObjects threads) in user interface-based ArcGIS Engine applications.
A major advantage of utility objects is that they can be used to alleviate performance problems caused by the overhead of making fine-grained ArcObjects calls across threads (between Java threads and ArcObjects threads) in user interface-based ArcGIS Engine applications.
Using utility objects
One of the uses of utility objects is to solve a particular class of performance problems that could affect ArcGIS for Server and user interface-based ArcGIS Engine applications.
These performance problems are the result of the overhead incurred in making fine-grained ArcObjects calls across processes (between the web server and the GIS server) in ArcGIS for Server applications and across threads (between Java threads and ArcObjects threads) in user interface-based Engine applications.
Utility objects provide a logical solution to such problems by preventing fine-grained calls across contexts, ensuring that these calls execute within the GIS server process (as opposed to the web server) in ArcGIS for Server applications and within the ArcObjects thread (as opposed to Java threads) in user inteface-based Engine applications.
Writing a utility object
The following steps describe the procedure for writing a utility object. These procedural steps are the same regardless of the client application (whether Server or Engine) that will consume the utility object.
Defining a custom interface
An implementer of the utility pbject should define a custom interface that describes an API for clients to call methods on it. A custom interface can only use the following permitted data types in its method definitions:
- All Java primitive types except primitive characters (“char”).
- Single-dimensional array of all Java primitive types except primitive characters (“char”)
- Java string types
- Single-dimensional array of Java string types
- ArcObjects interface types
- Single-dimensional array of ArcObjects interface types
To qualify as being part of an ArcGIS Java extension, the custom interface needs to be decorated with the @ArcGISExtension annotation.
The following code snippet shows an example of a custom interface that declares a single method that computes the total area of features in a feature layer:
[Java]
@ArcGISExtension
// Custom interface.
public interface ICalculateArea{
public double calculateArea(IFeatureLayer featureLayer)throws IOException,
AutomationException;
}
Defining a Java class that implements the custom interface
For ArcGIS to recognize this class as a Java extension, it needs to be decorated with the @ArcGISExtension annotation as shown in the following code snippet:
[Java]
@ArcGISExtension
// Decorated with annotation.
public class CalcAreaUtil implements ICalculateArea{}
Implementing the custom interface
The utility object should now implement all of the custom interfaces it has defined.
The following snippet shows an implementation of the calculateArea” method declared on the ICalculateArea custom interface. The implementation iterates through all the features in a feature class to compute the total area.
[Java]
public double calculateArea(IFeatureLayer featureLayer){
double totalArea = 0;
// Obtain the feature class.
IFeatureClass featureClass = featureLayer.getFeatureClass();
int numFeatures = featureClass.featureCount(null);
IFeatureCursor featureCursor = featureLayer.search(null, true);
IFeature feature = null;
Polygon polygon = null;
for (int i = 0; i < numFeatures; i++){
feature = featureCursor.nextFeature();
polygon = (Polygon)feature.getShape();
totalArea += polygon.getArea();
}
return totalArea;
}
Deploying the utility object
Once authored, the utility object needs to be exported to a .jar file, which is the deployment unit for ArcGIS Java extensions. At this time, any external dependencies or libraries needed by the utility object should be specified in a manifest file and bundled with the .jar file containing the extension. For details on how to create a manifest file to indicate jar file and class file dependencies, see Sun’s documentation on this subject.
Once exported to a .jar file, the utility object needs to be deployed to ArcGIS so clients can use it. The two methods of deployment are as follows:
- Copy the .jar file to the ARCGISHOME/java/lib/ext folder. This ensures that the extension gets automatically registered with ArcGIS the next time the application is started. This is a Java-friendly way and a recommended practice for deploying all ArcGIS extensions.
- Explicitly register the .jar file with ArcGIS either through the API exposed on the com.esri.arcgis.interop.extn.RegTool class or through the “regtool.bat”/”regtool.sh” script available under ARCGISHOME/java/tools.
Consuming a utility object
Once deployed, a utility object can be consumed from an Engine or Server application as shown in the following code snippets. The code snippets illustrate how to create an instance of a utility object and call the calculateArea method on it, passing in the second layer of the map document as its argument.
Engine:
[Java]
IFeatureLayer featureLayer = mapServer.getLayer(" ", 2);
ICalculateArea calArea = (ICalculateArea)
com.esri.arcgis.system.EngineContext.createObject(CalcAreaUtil.class);
double totalArea = calArea.calculateArea(featureLayer);
Server:
[Java]
IFeatureLayer featureLayer = mapServer.getLayer(" ", 2);
ICalculateArea calArea = (ICalculateArea)
com.esri.arcgis.server.ServerContext.createObject(CalcAreaUtil.class);
double totalArea = calArea.calculateArea(featureLayer);
A sample Engine application is available to illustrate the two approaches (a fine-grained ArcObjects or a utility object) to compute the total area of all features in a particular layer and shows a performance comparison between the two approaches.
See Also:
Development licensing | Deployment licensing |
---|---|
Engine Developer Kit | Engine |
Server | Server |