The Purpose of the Restrictions

   

The EJB 2.0 Restrictions

The list of restrictions is in no particular order and, although there can be some relationships between them, there are no implied dependencies. We'll take them one by one and state the restriction and provide a brief explanation for the restriction. In the cases where a legal workaround is known, we'll state one or more solutions to achieve the same results without violating the restriction.

Don't Use Read/Write Static Fields

The EJB 2.0 Specification states that an enterprise bean must not use read/write static fields. When you declare a static field, you are stating that all instances of the class will share the same instance. The problem is that you are not guaranteed that all instances of an EJB are run within the same JVM. Some EJB servers might decide to run multiple instances of the same EJB class in separate JVMs for performance, load balancing, or better fault-tolerance capabilities.

If you have an enterprise bean with a static field that can be modified, you can't assume that all instances of the bean are referencing the same static field and thus seeing the same state. The bean instances are likely to become inconsistent. If you are going to use static fields, the fields must be declared final . If they are declared final , they can't be modified after they are initialized , and instances that are in different JVMs would be consistent.

Many EJB developers ask, "What about non-EJB components?". You might reason that using writable static fields in non-EJB components must be acceptable because the container does not manage them. The problem with this is that the non-EJB components are still loaded by the container's class loader or the system class loader for a JVM and therefore are subject to inconsistencies if multiple JVMs are used. You are better off not using them at all or using the final keyword when declaring the static field. The following code fragment shows an example of using the final keyword to ensure that a static field can't be modified:

 import java.sql.Timestamp;  public class AuctionHelper{   // The loadTimestamp variable will be initialized    // only when this class is first loaded    public static final Timestamp loadTimestamp =                            new Timestamp( System.currentTimeMillis() );    // Constructor    public AuctionHelper(){     super();    }  }  

Because the field is declared final , you would get a compiler error if you attempted to set the loadTimestamp field to another value elsewhere in your application.

There's nothing wrong with accessing the Timestamp field; you just can't modify it after it has been initialized. Some EJB containers may search through the enterprise beans during deployment, looking for static fields that have not been declared final and will fail to deploy them.

Tip

The use of read-only static fields is allowed. As pointed out above, you just need to make sure to use the final keyword on the static reference to ensure that it can't be changed after initialization.


Using Threads and Synchronization

The EJB 2.0 Specification states that an enterprise bean must not use synchronization primitives to synchronize execution of multiple instances. This restriction prevents enterprise beans from using synchronization primitives from performing any kind of thread management. This also includes not creating any new threads or stopping any existing ones. An enterprise bean also may not suspend, resume, or change the name or priority of threads managed by the container.

One of the reasons for this restriction is that, as pointed out earlier, a container can use multiple JVMs instead of a single one. A container's role is to manage the lifecycle of the bean instances. There are three basic reasons that the container prevents enterprise beans from using synchronization or the thread management facilities: security, resource management, and thread-specific storage.

Security

Although there are ways for threads to manipulate a system in unauthorized and unauthenticated manners, the real issue with security has to do with creating too many threads and not cleaning them up appropriately. The system will eventually slow down and will not continue to service client requests , rendering the application useless. This is similar to the "denial of service" attacks that have become very popular lately by computer hackers.

Resource Management

Resource management is a way to say that the container demands the autonomy to manage resources as it sees fit. If the container wants to stop a thread, it should be able to without negatively affecting the bean instances. If your enterprise beans are creating and starting threads, the container is no longer in control and, from the container's perspective, this is a bad thing. Some EJB containers provide a general-purpose thread pool for enterprise beans to use. If an enterprise bean doesn't yield the thread back to the pool after a certain amount of time, the container could just take it back or cause it to cease execution. With this approach, the container can still maintain control, but also allow enterprise beans to have limited threading capabilities.

Thread-Specific Storage

Thread-specific storage (TSS) is a mechanism that many EJB containers use to associate client-specific data with specific threads. Although each vendor can use this technique differently, most use it to propagate security and/or transactional context on behalf of a client. The EJB container may associate client information with a particular thread and use that information to propagate to a remote component. If a bean provider is allowed to create threads at random, the proper information might not be propagated as needed by the remote component.

Caution

Regarding the main system thread, an enterprise bean must not attempt to stop the JVM. This means you can't call the System.exit method to stop the application. You will have to let the container shut down the application gracefully.


Restrictions on Using the java.io Package

The EJB 2.0 Specification states that an enterprise bean must not use the java.io package to attempt to access files and directories in the file system. This restriction is one that normally causes developers to say "bleagh!" and to experience a great deal of frustration.

The java.io package is a very rich library for accessing I/O and especially the file system. However, restrictions are in place to address both resource management and portability. For example, if you had several enterprise bean methods creating file descriptors, and all of a sudden your client load jumped up, you might run out of file descriptors and crash the system. Compared to resources such as relational databases, the file system is a questionable resource for a bean to depend on.

As far as portability, I once heard one EJB developer, who was obviously an advocate for this restriction, comment, "What if you deployed your application into a container running on a device that didn't have a file system?". Although this seems unlikely , the point is still valid. You should try to ensure portability wherever possible.

A common function for which EJB developers want to use java.io is to load property files. There are several legal ways to do this within enterprise beans. The first approach is to package the properties along with the enterprise bean's deployment descriptor. This is the preferred method for providing properties to your enterprise bean. When an enterprise bean is deployed with properties in the descriptor, you can use the bean's environment to get the properties and use them as normal.

To see an example of putting properties in a deployment descriptor and then referencing those properties from your enterprise bean, see "Building the E-Mail Service Message-Driven Bean," p. 554 .

Another approach to more directly reading resource files from your enterprise beans involves the class loader, which by the way has the complete permission of the container to use the java.io package. If you need to load a file, you can use either the getResource or getResourceAsStream method defined in java.lang.Class . These methods are executed by the class loader and returned as a URL or an InputStream , respectively. Your application can use these to get the information from the file as necessary.

A recommendation made by the specification is to use the concept of resource managers. You could create a resource manager in a way similar to how you acquire a JDBC connection from JNDI. You could create a resource manager that has permissions to access the file system and then acquire a connection to this resource manager to access files. This resource manager would be granted special doPrivilege security access that enterprise beans don't have. Using resource managers would help with portability and enable the clients to access the underlying file system in a more transparent manner. Many EJB servers have a file system resource manager or service that allows the enterprise beans limited access to the file system. You must be careful, however ”these are not clearly defined in the specification and might not be directly portable to other vendor containers.

Restrictions on Using Sockets

The EJB 2.0 Specification states that an enterprise bean must not attempt to listen on a socket, accept connections on a socket, or use a socket for multicasting. However, an enterprise bean is allowed to act as a network socket client, just not as network socket server.

This restriction stems from the fact that enterprise beans are designed to service a client using a particular remote protocol and based on a set of security permissions. By allowing clients to connect to the container using a possibly nonsecure connection, you are potentially opening up your application to intruders.

The enterprise bean must also not attempt to modify the socket factory used by the ServerSocket , Socket , or the stream factory used by URL . This could compromise the security of the application and remove control of the execution environment from the container.

Restrictions on Using the Reflection API

The EJB 2.0 Specification states that an enterprise bean must not attempt to query a class to obtain information about the declared members that are not otherwise accessible to the enterprise bean because of the security rules of the Java language.

This doesn't mean that you can't use the Reflection API that's part of the Java language. What it does mean, however, is that you should not use it to get around the security policies that have been programmatically and declaratively established.

Each enterprise bean can declare programmatic or declarative security roles that a client must have to invoke method calls on the enterprise bean. You are not allowed to use reflection and call a method on an enterprise bean to bypass these security permissions. For example, suppose an enterprise bean called AuctionHouseBean declares in its deployment descriptor that a client must have a role of admin to make any method calls on it. An enterprise bean should not use reflection on this enterprise bean and then make method calls on it to bypass the security mechanism.

Restrictions on Using Class Loaders and Security Managers

The Java 2 security mechanism and class loaders are the key to how Java helps prevent unauthorized access by classes and other runtime entities from causing bad things to happen to a Java application. The EJB container uses a certain set of class loaders and security policies to help maintain stability within the execution environment. If any bean could replace the class loader or security policies at will, there would be little hope for the container to maintain the sanity within the environment.

Therefore, an enterprise bean must not create a new class loader or modify the context of an existing one. It also must not create a new security manager or modify the existing one.

Restrictions on Using AWT Input/Output

The EJB 2.0 Specification states that an enterprise bean must not attempt to output information to a display or read information in from an input device, such as a keyboard, using the Abstract Window Toolkit (AWT).

Not many EJB servers will allow direct interaction between these input and output devices, and EJBs that attempt this might not be portable.

Restrictions on Using Native Libraries

The EJB 2.0 Specification states that an enterprise bean must not attempt to load a native library. If an enterprise bean loaded a native library, it could open up a security hole into the application and allow unauthorized access to the system.

Restrictions on Using the this Reference

The EJB 2.0 Specification states that an enterprise bean must not attempt to pass itself as an argument in a method or as a return value using the this reference. The reason is that all clients should access an enterprise bean through its EJBObject and not the bean instances directly. This allows the container to passivate and activate bean instances transparently to the client. A client may still be holding a reference to an EJBObject while the real bean instance has been passivated. Not until the client invokes a method call on the EJBObject does the container need to associate an enterprise bean instance with the EJBObject .

The client can be a remote client, but could also be another enterprise bean. Therefore, even when communicating between beans, the this reference should not be used because it would be passing the instance of the bean rather than the EJBObject . Instead, an enterprise bean should do something similar to the following code:

 public EJBObject getMe(){     { Some work here ...}      // Time to return myself, but return an      // instance of an EJBObject instead of "this"      return getEntityContext().getEJBObject();    } 


Special Edition Using Enterprise JavaBeans 2.0
Special Edition Using Enterprise JavaBeans 2.0
ISBN: 0789725673
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net