Understanding parameter behavior and granularity

It is important to invoke the methods of a remote EJB in an efficient manner. This recipe illustrates how to return data from a remote EJB using a coarse-grained approach. This is then contrasted with a fine-grained approach to accessing the elements of an EJB which is less efficient.

The position of a satellite in orbit can be specified using a set of six orbital parameters. For the interested reader, a good discussion of these parameters is found in the Wikipedia article at http://en.wikipedia.org/wiki/Orbital_elements. We will create the class PositionBean to hold these parameters. We will also use an OrbitalElements EJB to return an instance of the PositionBean using a remote interface. A client can directly access the PositionBean in a fine-grained manner or access the PositionBean from the OrbitalElements bean in a coarse-grained manner.

Getting ready

This technique is about how to organize your code. You can return information as a single object or you provide methods to return individual elements one at a time. Either approach is valid. However, the latter approach will not be as efficient.

The approach illustrated here uses an interface to define methods to access elements of an object. The object is returned as a single object and its methods permit access to the information of interest.

How to do it...

Let's begin by creating a Java Web application called ParameterExample. Add a packt package with the following EJBs and interfaces:

  • OrbitalElements A singleton EJB
  • OrbitalElementsRemote An interface
  • PositionBean A stateless EJB
  • PositionBeanRemote An interface

Also create a second package called servlet and add a servlet called PositionServlet.

Beginning with the PositionBeanRemote interface, this simple interface has only get type methods.

package packt;
public interface PositionBeanRemote {
public double getArgumentOfPeriapsis();
public double getEccentricity();
public double getInclination();
public double getLongitudeOfTheAscendingNode();
public double getMeanAnomaly();
public double getSemimajorAxis();
}

Next, the PositionBean implements the remote interface methods and in this example only initializes the eccentricity instance variable. In a more sophisticated version of the application, other fields of the PositionBean would be initialized.

@Stateless
@Remote
@Startup
public class PositionBean implements PositionBeanRemote{
private double eccentricity;
private double semimajorAxis;
private double inclination;
private double longitudeOfTheAscendingNode;
private double argumentOfPeriapsis;
private double meanAnomaly;
//@PostConstruct
public PositionBean() {
eccentricity = 1.0;
}
public double getArgumentOfPeriapsis() {
return argumentOfPeriapsis;
}
public double getEccentricity() {
System.out.println("--- Return eccentricity");
return eccentricity;
}
public double getInclination() {
return inclination;
}
public double getLongitudeOfTheAscendingNode() {
return longitudeOfTheAscendingNode;
}
public double getMeanAnomaly() {
return meanAnomaly;
}
public double getSemimajorAxis() {
return semimajorAxis;
}
}

To illustrate the use of the PositionBean the PostionServlet declares an instance of the bean and uses the getEccentricity method. This technique illustrates a fine-grained approach.

public class PositionServlet extends HttpServlet {
@EJB
PositionBeanRemote position;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet PositionServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h3>Eccentricity: " + position.getEccentricity() + "</h3>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}

The OrbitalElements EJB implements the OrbitalElementsRemote interface with a single method, getPosition, returning a PositionBean. This technique illustrates a coarse-grained approach.

@Remote
public interface OrbitalElementsRemote {
public PositionBean getPosition();
}

The OrbitalElements EJB creates an instance of the PositionBean and then returns the bean. This example did not provide a means of initializing the PositionBean to unique values or perhaps treating the bean as a singleton. Its actual type and creation will depend on the needs of the application.

@Singleton
public class OrbitalElements implements OrbitalElementsRemote {
public PositionBean getPosition() {
return new PositionBean();
}
}

In the PostionServlet declare a reference to the OrbitalElementsRemote interface and use the getPosition method to return an instance of the PositionBean.

public class PositionServlet extends HttpServlet {
@EJB
PositionBeanRemote position;
@EJB
OrbitalElementsRemote orbitalElements;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet PositionServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h3>Eccentricity: " + position.getEccentricity() + "</h3>");
out.println("<h3>Eccentricity: " + orbitalElements.getPosition().getEccentricity() + "</h3>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}

Execute the servlet using the URL shown in the following screenshot:

How to do it...

How it works...

Notice the creation of the PositionBean using the new keyword in the OrbitalElements EJB. This illustrates an easily made potential problem. The object created is not managed by the EJB container. As a result, the benefits of an EJB such as security and transaction management are not supported. This may not be a problem depending on the intended use of the object. Use dependency injection if the object needs to be managed by the EJB container.

There's more...

Local beans execute in the same JVM as the client. This type of access is typically faster than using remote access which occurs when the client is in a different JVM. There is less communication overhead required to execute a method and to pass parameters. However, there are times when it is necessary to access an EJB in a remote fashion. Be aware that some servers are able to optimize such access and avoid the overhead costs.

Consider a class with several private instance variables. If individual calls are made to access each variable one at a time, then this requires repeated method invocations. This type of access is referred to as fine-grained access.

In contrast, when the entire object is passed, only a single remote method invocation is needed. This is called coarse-grained access. It will still be necessary to invoke the individual methods, but these are local to the client. Fine-grained access becomes more of a problem when the client resides on a different JVM.

One coarse-grained remote procedure call followed by multiple "local" method calls in the client is more efficient than multiple fine-grained remote procedure calls. If it is necessary to modify the original object, then fine-grained access for the setter type methods is required along with its performance penalties.

When passing or returning an object in a different JVM, the object is passed by value. That is, a copy of the object is passed to the client. Should the client attempt to modify the object, only the copy of the object is modified. The original object is not touched.

When passing an object by value it is a good idea to pass an immutable object so as to make it clear that it cannot be modified. The creation of an immutable object means at minimum the class should not have setter type methods.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.107.152