adam bien's blog

Why you should follow the EJB 2 programming restrictions in EJB 3 environment 📎

J2EE and especially EJB 2 prescribe some programming restrictions:
"...
An enterprise bean must not use read/write static fields. Using read-only static fields is
allowed. Therefore, it is recommended that all static fields in the enterprise bean class be
declared as final.

An enterprise bean must not use thread synchronization primitives to synchronize execution of
multiple instances.

An enterprise bean must not use the AWT functionality to attempt to output information to a
display, or to input information from a keyboard. :-)

An enterprise bean must not use the java.io package to attempt to access files and directories
in the file system.

An enterprise bean must not attempt to listen on a socket, accept connections on a socket, or
use a socket for multicast.

The 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. The enterprise bean must not attempt to use the Reflection API to access
information that the security rules of the Java programming language make unavailable.

The enterprise bean must not attempt to create a class loader; obtain the current class loader;
set the context class loader; set security manager; create a new security manager; stop the
JVM; or change the input, output, and error streams.

The enterprise bean must not attempt to set the socket factory used by ServerSocket, Socket, or
the stream handler factory used by URL.

The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt
to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise
bean must not attempt to manage thread groups.

The enterprise bean must not attempt to directly read or write a file descriptor.

The enterprise bean must not attempt to obtain the security policy information for a particular
code source.

The enterprise bean must not attempt to load a native library.

The enterprise bean must not attempt to gain access to packages and classes that the usual rules
of the Java programming language make unavailable to the enterprise bean.

The enterprise bean must not attempt to define a class in a package.

The enterprise bean must not attempt to access or modify the security configuration objects
(Policy, Security, Provider, Signer, and Identity).

The enterprise bean must not attempt to use the subclass and object substitution features of the
Java Serialization Protocol.

The enterprise bean must not attempt to pass this as an argument or method result. The
enterprise bean must pass the result of SessionContext.getBusinessObject, SessionContext.
getEJBObject, SessionContext.getEJBLocalObject, EntityContext.
getEJBObject, or EntityContext.getEJBLocalObject instead.
..."

Most of the restrictions mentioned above are really useful if you consider the applications server environment which is distributed and often redundant (clustering). Most of the J2EE appservers do not really enforce these restrictions - so you can violate them. Actually if you know what your are doing it will still work on J2EE environment. The problem is - this can change on every application server upgrade. The appservers also become more restrictive. E.g. if you try to deploy an EJB 3 with synchronized method to WLS 10, you will get the following exception:

"...weblogic.ejb.container.compliance.ComplianceException: In EJB StatisticsProviderBean, Enterprise Bean methods
must not use thread synchronization primitives. The method named getInstance() is synchronized.
        at weblogic.ejb.container.compliance.BeanClassChecker.checkBeanMethodsAreSynchronized(BeanClassChecker
.java:360)
        at sun.reflect.GeneratedMethodAccessor144.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at weblogic.ejb.container.compliance.EJBComplianceChecker.check(EJBComplianceChecker.java:338)
..."
However it was not a problem to deploy synchronized code on the WLS 8.1...
The problem here: the violation of the "bold" restriction. So even if your application is working in J2EE environment with violated programming restrictions, it can break on every appserver update or even patch. So following the rules makes not only your application better working in distributed environment, but it makes it also more portable across servers.