 |
August 2005 Archives
Using EJB Annotations Outside of EJB
Posted by edburns on August 29, 2005 at 01:05 PM | Permalink
| Comments (2)
The Common
Annotations and EJB 3 JSRs both
provide a number of annotations that are useful to enterprise Java
developers. This blog entry examines the use of two from EJB3 that I
feel really should be in Common Annotations: @PostConstruct
and @PreDestroy.
Let's review the purpose of these annotations.
@PostConstruct
-
* Designates a method to receive a callback during creation of a
* session bean or message driven bean instance.
@PreDestroy
-
* Designates a method to receive a callback before a session bean or
* message driven instance is destroyed.
These annotations are useful for any container managed instance, not
just session beans or message driven beans. This blog shows how I
leveraged the new ManagedBeanFactory SPI in Sun's
implementation of JSF technology to create a prototype that allows JSF
authors to use these annotations in their managed beans. I'm doing this
to make the case to move these two annotations out of EJB and into
Common Annotations. If this is done, it's easy to see that using this
feature will find its way into a future version of the JSF spec.
The running code for this example is checked into the "components"
jsf-demo in the JSF
project on java.net. You have to get a nightly build more recent
than 30 August 2005 to get a build with this code in it, though.
Details
The com.sun.faces.spi.ManagedBeanFactoryWrapper class in
the Sun JSF implementation allows the user to decorate the internal
implementation class used to instantiate managed beans such that the
creation process can be intercepted and methods annotated with
@PostConstruct can be called. The listeners for request,
session, and ServletContext classes in the Servlet API can
be used to intercept destruction events and call managed bean methods
annotated with @PreDestroy.
The following two classes leverage these hook points to implement the
feature. The classes are presented in the form of a JSF project change-bundle
To see the real code, please get
the source from java.net.
A
components/src/java/components/model/LifecycleManagedBeanFactory.java
This class leverages the decorator pattern provided by the
ManagedBeanFactory SPI to decorate the
newInstance() method and inject calling the
@PostConstruct method on the ManagedBean instance being
created, if present. It also establishes a contract with the
LifecycleManagedBeanListener to call the
@PreDestroy annotated methods, if present, when the time
comes.
A components/src/java/components/model/LifecycleManagedBeanListener.java
This class implements ServletRequestListener,
HttpSessionListener, and ServletContextListener and
uses the *Destroyed methods to look into the list
established by the LifecycleManagedBeanFactory for this
scope and call any appropriately annotated methods.
M components/src/java/demo/model/RepeaterBean.java
annotate some methods to be called.
M components/web/WEB-INF/web.xml
Declare the above LifecycleManagedBeanListener.
M components/build.xml
Declare a compile time dependency on jsf-impl.jar.
Summary
It could be said that using annotations in this way is just making up
for Java's lack of a proper destructor, as one has in Objective C and
C++. However, using annotations in this way is far more flexible than
constructors and destructors, while not adding any conceptual burden for
the new developer. New developers can simply avoid using annotations
until they feel ready to do so. Another factor to consider is that the
servlet API could be enhanced to automatically call methods annotated
with these or similar annotations when objects are added to the request,
session, or application scope. I hope I've demonstrated the usefulness
of these two annotations outside of EJB and made a good case for moving
them out to Common Annotations.
Technorati Tags: edburns
(Updated) JavaServer Faces 1.2 and JavaServer Pages 2.1 Proposed Final Draft Specifications available
Posted by edburns on August 25, 2005 at 05:57 PM | Permalink
| Comments (4)
I'm pleased to announce the availability of the Proposed Final Draft
revisions of the next release of the JavaServerTM Faces and
Pages specifications. The Faces spec may be downloaded from <http://www.jcp.org/en/jsr/detail?id=252>
and the Pages spec may be downloaded from <http://www.jcp.org/en/jsr/detail?id=245>
We really want feedback! Please use our Forum
to share your thoughts on the specs. Or you may send feedback to
the comments alias for Faces or JSP (jsr-252-comments@jcp.org and jsr-245-comments@jcp.org respectively) .
In this entry, I link to a comprehensive high level outline of the
changes to the spec since the 1.1 release of the Faces spec. I've
decided include changes present in the December
Early Draft Release, the April Public
Review Release and the current Proposed Final Draft release for
completeness. As such, this entry repeats some information from my
blog entry on the April Public Review Release. If you're looking
for what's new since that the Public Review release only, please consult
this
issue tracker query.
Keep in mind this is a high level outline, for details, I
encourage you to read the relevant sections of the spec itself.
Before we get to the outline, here is a brief summary of the main
changes:
Unified EL
The expression language used in Faces, which
was inspired by the expression language used in
JSTL and JSP, has been generalized and extracted
into its own top level javax.el
package. The EL is agnostic of the technology
hosting it, such as JSP or Faces, and is intended
to be generally useful in the same way one can use
OGNL in a variety of applications. Faces now has
deprecated its internal EL in favor of using the
Unified EL.
New Tree Creation and Content Interweaving
Model for Faces applications that use JSP
While it is perfectly acceptable to use Faces
without using JSP, many people find their
productivity increases when using these two
technologies together. Unfortunately, as amply
documented by Hans
Bergsten in his article at onjava.com, there
were some integration cases that didn't work as
expected. By changing the specification of the
implementation of the Faces ViewHandler for JSP,
as well as changing the JSP custom tag base class
used by all Faces component tags, these problems
have all been resolved.
Integration with JSTL
Another long standing problem was in using JSTL's
<c:forEach> tag to contain Faces input
components. Because JSP has no notion of a postback, it was
not possible to apply the values correctly to the nested input
components on postback. By introducing some new concepts into
the EL, it is now possible to fully use
<c:forEach> with any kind of Faces
component. This will require a new release of JSTL, which
will also be present in J2EE 5, along with Faces and JSP.
Back Button issues and Multi Frame or Multi Window
Faces Apps
Due to a deficiency in the State Management API using Faces
in Multi Frame or Multi Window applications presented some
problems. The browser back button also could cause
application state to become confused. These problems have now
been fixed.
Associating a message with a particular component in
the page.
Previous revisions of the spec didn't allow for
dynamically including the label of a component in an error
message for that component. New spec features now allow for
this to happen.
It is now possible to override the conversion or
validation message that is displayed to the user on a
per-instance basis. For example:
<h:inputText value="#{bean.value}"
requiredMessage="#{bundle.requiredMessage}"
converterMessage="#{bundle.converterMessage}"
validatorMessage="#{bundle.requiredMessage}">
<f:validateLongRange maximum="1" minimum="10"/>
</h:inputText>
AJAX support
As you should all know by know, AJAX is mainly a
component thing, but there are some things the basic JSF
framework can do to make things a little easier for those
writing AJAXian JSF components. Even without these features
(ie, in JSF 1.1), it's
very easy to write AJAX components for JSF and easier
still to use them.
Specify that the FacesServlet should look
for an init-param called
javax.faces.LIFECYCLE_ID to identify the Lifecycle to be
used for processing this request. This approach allows you
to map different instances of the FacesServlet
with different lifecycles. For example, one mapping for
standard JSF requests and another for AJAX JSF requests.
Specify the name of the state saving parameter so that
AJAX scripts can manually post back the state to the server
using XMLHttpRequest, therefore enabling the AJAX processing
code to have access to the full view. This approach was
used in the Progress
Bar JSF component. The name of the parameter is
javax.faces.ViewState.
Expose an application wide ResourceBundle to the EL.
We have added a new <resource-bundle> element to
the faces-config that allows you to list zero or more
resource bundles that should be exposed to the EL using the
new ELResolver chain. Doing this allows performance
optimizations that prevent the need to create a
ResourceBundle for every request.
API classes use generics
In response to strong Expert Group demand, we have
applied Java SE 5.0 Generics to the JSF api. Therefore, the
minimum JDK requirement for JSF 1.2 is Java SE 5.0. I'm
told that it's possible to retroweave a binary to make it
run under 1.4, but of course that configuration is not
supported or recommended by Sun.
All of these features and more are currently available in the JSF
implementation found in Sun's Open Source Appserver, glassfish.
Now, the outline of changes is available here.
Technorati Tags: edburns
|