Showing posts with label cheatsheet. Show all posts
Showing posts with label cheatsheet. Show all posts

Friday, March 12, 2010

JMS Security, Concurrency and Triggers

This is the 2nd in a series of posts around JMS 1.1, focusing on things that can guide design decisions when putting a JMS application together. In this writeup, I'll discuss security, concurrency and the use of triggers.


Security

JMS 1.1, section 2.7: JMS does not provide features for controlling or configuring message integrity or message privacy. It is expected that many JMS providers will provide such features. It is also expected that configuration of these services will be handled by provider specific administration tools. Clients will get the proper security configuration as part of the administered objects they use.

Decision: does the application need authentication, confidentiality, etc.?

Idioms: Any client authentication is handled by the Connection object. A JMSSecurityException is thrown when authentication credentials are rejected by the provider, or whenever any security restriction prevents a method from completing.

Caveat: Any security measures applied will not be portable across JMS providers. Remember that authentication and confidentiality exercises are relatively heavyweight; combined with the heavy lifting of setting up network connectivity, this motivates minimizing the number of connections in use (and, for that matter, of using connection caches).


Concurrency

Of the six top-level JMS objects, only Destination, ConnectionFactory and Connection are intended for multi-threaded access.  The Session, MessageProducer and MessageConsumer are intended for single-thread use only. See the JMS 1.1 spec, section 2.8 for an in-depth rationale around this restriction - bottom line, this makes it easier for the typical JMS client, with concurrency possible if needed by using multiple sessions.

JMS providers must prevent concurrent access to a given client's state that could result in messages being lost or processed redundantly - whether that's done by an exception being thrown, or blocking the offending client, or otherwise.

Idioms: Note that this doesn't mean multiple threads can't use a given Session object - it just means the developer must ensure the access is not concurrent. Using one thread only is the simplest way to ensure this; otherwise, explicit synchronization is called for. The standard approach to setting up asynchronous delivery is using a single thread for setup while the Connection is stopped, then use that same thread to start the Connection. Concurrent access to a session's producers and consumers is also not allowed. If a client uses one thread to produce messages and other threads to consume them, use of a separate session for the producing thread is called for. Once a connection has been started, do not use any Session method except close; using a separate thread of control to close a Session is allowed. This restriction applies in particular to setting up multiple message listeners - all of these must be established before the connection is started.

Caveat: While a client may have multiple sessions, JMS does not define the behavior around concurrent QueueReceivers for the same Queue; relying on a given provider's support for this is not portable. Note that the Session serializes execution of asynchronous deliveries, using a single thread to run all MessageListeners.  One consequence of this is that a session with asyncronous listeners cannot be used to also receive messages synchronously.

Recommendation: Consider the effect of the session's serial execution on your target throughput. For higher throughput via concurrency, use multiple sessions. However, note that it is not considered reliable to use a single consumer with application-level multi-threading logic to concurrently process messages from a topic (due to lack of adequate transaction facility in JMS). JMS does, however, provide a special facility for creating MessageConsumers that can consume messages concurrently, via application server support; see section 8 in the spec. The application developer presents a single-threaded program if using this facility.


Triggers

A trigger is e.g. a threshold of waiting messages, a length of time that has gone by, a time of day, etc., which is used to wake up a client so it will process any waiting messages. Keep in mind that any such mechanism, if available in the provider you use, is not specified by the JMS spec, and as such is not portable.

Caveat: any trigger mechanisms will not be portable across JMS providers.


In the next several posts in this series, I'll discuss things like request/reply, message ID, timestamp, message expiration and message priority.

JMS Common vs Domain-Specific Interfaces

Reading through the JMS 1.1. spec, I'm motivated to in fact re-read it, since certain concepts are referenced before being introduced. This isn't unusual for a spec, and that's not a critique; but bottom line, I decided to go through the spec a second time, this time collating related information around given concepts in one place, and ordering things in a way that doesn't assume prior knowledge.

This is the first in a series of posts in which I'll focus on concepts and facilities from the spec that call for some kind of design decision (as opposed to more general behaviorial issues, etc.) - since I'm in the process of making those kinds of decisions with my current development efforts.

I'll start with some introductory basics around use of JMS; listing decisions to be made with guidance around each, plus recommended practices, programming idioms and caveats. First I address only the use of "JMS Common" vs "Domain-Specific" interfaces, since that writeup is long enough for its own post.



JMS supports both queue-based (aka Point-to-Point, or PTP) and topic-based (aka Publish/Subscribe, or Pub/Sub) models (aka "domains"). As of JMS 1.1, so-called "common interfaces" are available that encapsulate this distinction (aka "unification of messaging domains") - while the legacy domain-specific APIs are preserved for backwards compatibillity.

As per JMS 1.1, section 2.5: The JMS common interfaces provide a domain-independent view of the PTP and Pub/Sub messaging domains. JMS client programmers are encouraged to use these interfaces to create their client programs.

Here's a table illustrating the difference:


JMS Common Interfaces
PTP-specific
Pub/Sub-specific
ConnectionFactory
QueueConnectionFactory
TopicConnectionFactory
Connection
QueueConnection
TopicConnection
Destination
Queue Topic
Session
QueueSession TopicSession
MessageProducer
QueueSender TopicPublisher
MessageConsumer
QueueReceiver, QueueBrowser
TopicSubscriber

And here are some definitions:

ConnectionFactory - an administered object used by a client to create a Connection
Connection - an active connection to a JMS provider
Destination - an administered object that encapsulates the identity of a message destination
Session - a single-threaded context for sending and receiving messages
MessageProducer - an object created by a Session that is used for sending messages to a destination
MessageConsumer - an object created by a Session that is used for receiving messages sent to a destination

Decision: which one to use?

Recommendation: use the JMS common interface, in particular if you wish to enclose send/receive of messages from both domains (i.e. queue and topic) within a single transaction. From section 11.4.1: (use of JMS Common API) simplifies the client programming model, so that the client programmer can use a simplified set of APIs to create an application...using (JMS Common) methods, a JMS client can create a transacted Session, and then receive messages from a Queue and send messages to a Topic within the same transaction. There are additional benefits to providers in terms of opportunities for certain optimizations in their implementations.

Caveat: Be aware that in future JMS releases, the domain-specific APIs may be deprecated. Keep in mind that PTP and Pub/Sub messaging system behaviors will of course be different, even though you're using the same API, since the semantics of each domain are different. An unpleasant side-effect of this is the fact that, since the common interface defines e.g. some queue-specific methods - and since the topic-specific classes inherit from that interface - there are some methods available that just aren't appropriate. If the application calls any of these methods, an IllegalStateException is thrown. Why this isn't an OperationUnsupportedException is another question.

Here is the list of those methods:

Interface Method
QueueConnection createDurableConnectionConsumer
QueueSession createDurableSubscriber
createTemporaryTopic
createTopic
unsubscribe
TopicSession createQueueBrowser
createQueue
createTemporaryQueue

Note that there are also JMS Common Interfaces available for JTS services, as described in section 8.6 of the spec. However, be aware that JMS providers are not required to support JTS, so use of this is not portable across providers.



In the next post, I'll touch on more basics, to include security and concurrency.

Thursday, September 10, 2009

Spring 3.0 AOP: Cheatsheet

Continuing with insights and tips around Spring 3.0, here is a collection of code samples I've established "so far" with my (rather brief) prototyping using that framework. As with all of my cheatsheets, I'm not presenting these things as any kind of definitive reference; they are only from my own experience, done only in a "sandbox" so far -- we've not yet put these things into production. Your contributions and corrections to this cheatsheet, and any of my other ones, are welcome.


Dependencies

The following libraries are needed:

org.springframework.asm-3.0.0.M3.jar
org.springframework.beans-3.0.0.M3.jar
org.springframework.context-3.0.0.M3.jar
org.springframework.core-3.0.0.M3.jar
org.springframework.expression-3.0.0.M3.jar
org.springframework.aop-3.0.0.M3.jar
antlr-3.0.1.jar commons-logging.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.runtime-1.6.5.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.5.RELEASE.jar

Concepts

Some key terminology and concepts, pulled from the Spring 3.0 Reference doc - I'll just copy key pieces verbatim first and then paraphrase at the end:
  • Aspect: a modularization of a concern that cuts across multiple classes. Transaction management is a good example of a crosscutting concern in J2EE applications. In Spring AOP, aspects are implemented using regular classes (the schema-based approach) or regular classes annotated with the @Aspect annotation (the @AspectJstyle).
  • Join point: a point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution.
  • Advice: action taken by an aspect at a particular join point. Different types of advice include "around," "before" and "after" advice. Many AOP frameworks, including Spring, model an advice as an interceptor, maintaining a chain of interceptors around the join point.
  • Pointcut: a predicate that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut (for example, the execution of a method with a certain name). The concept of join points as matched by pointcut expressions is central to AOP, and Spring uses the AspectJ pointcut expression language by default.
  • Introduction: declaring additional methods or fields on behalf of a type. Spring AOP allows you to introduce new interfaces (and a corresponding implementation) to any advised object. For example, you could use an introduction to make a bean implement an IsModified interface, to simplify caching. (An introduction is known as an inter-type declaration in the AspectJ community.)
  • Target object: object being advised by one or more aspects. Also referred to as the advised object. Since Spring AOP is implemented using runtime proxies, this object will always be a proxied object.
  • AOP proxy: an object created by the AOP framework in order to implement the aspect contracts (advise method executions and so on). In the Spring Framework, an AOP proxy will be a JDK dynamic proxy or a CGLIB proxy.

So an aspect is a class that contains methods referred to as "advice". The advice is executed as specified by the annotation (before, after, etc.) and the "pointcut", or predicate (what classes/methods match the expression). The point in the application where the advice is applied is a "join point". The runtime object containing these join points (i.e., being advised by one or more aspects) is the "target" or "advised object". Spring uses proxying to accomplish the advising (see section 8.6.1 - really, read it, it's short and helpful), and will use JDK dynamic proxies if all advised objects implement at least one interface. Finally, "introductions" are a mechanism where advised objects can be transparently made to implement new interfaces (to retrofit things like caching, comparability, serialization, immutability, etc.), with the advice providing an implementation of the interface, and being handed a reference to the advised object that it can use to invoke the new interface methods.


Problem Space

Recommendations in the following discussions are in bold-face.

The proof-of-concept application is a trivial tongue-in-cheek model of a "family service", where my son Connor and my Siberian Husky Nika would each like to get my attention. It happens. Spring IoC is used to declaratively determine who wins; since that's a static configuration, it's for now the same answer every time.

So the basic idea is a shown in the UML: we have a FamilyService with a FamilyMember property, and two FamilyMembers, each with a name property.

Note that all classes implement an interface. This is in general a good idea for testability, etc. but in particular with Spring AOP, I'd favor this approach because it facilitates use of JDK dynamic proxies instead of CGLIB proxies. Use of CGLIB should consider these things: (1) more library dependencies, (2) final methods cannot participate in AOP, and (3) constructors are called twice due to CGLIB implementation details.

Short of other insights, I would for now recommend implementing at least one interface for any classes that participate in Spring AOP.

A detailed explanation of the above issue around CGLIB vs JDK dynamic proxying, as well as very clear presentation in general around Spring 3.0, can be found in the Spring Reference doc.



Enabling AOP

The injection of the family member getting my attention is done like this:

<bean id="family-service" class="spring.FamilyService">
 <property name="member">
     <ref local="nikadog"></ref>
 </property>
</bean>

This is typical Spring injection; nothing special here. The more interesting stuff is to now add some AOP. Do this by adding an "aop" namespace to the beans declaration tag and enabling what I would recommend as the preferred flavor of Spring AOP (AspectJ-style annotations plus Spring auto-proxying):
 
 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
 ....
   <aop:aspectj-autoproxy/>
 </beans>

The Spring reference doc again provides a clear, useful discussion around the various "flavors" you can use with Spring AOP. Given the tradeoffs described there, I recommend the AspectJ-style annotations with Spring auto-proxying for the following reasons:
  1. Their advice to "use the simplest thing that works" is IMO sound guidance
  2. So, for now, assume that AspectJ-annotations will suffice until you find otherwise
  3. If you need to gain more power, you can migrate easily from the AspectJ-annotations to full-blown AspectJ itself

The limitations to be aware of include these:

  1. AOP can only be applied to Spring-managed beans (therefore, Spring-declare any classes that will leverage AOP)
  2. AOP mechanisms can be applied only to public method-level executions (excluding constructors)
  3. Methods in AOP-enabled classes that have aspects declared will not see those aspects applied if invoked by other
    methods in that same class (i.e., do not use self-invocation within AOP-enabled classes)

Limitations #2 and #3 are a result of Spring's proxy approach to AOP. See section 8.6.1 in the reference doc for a detailed discussion. Note that a workaround for #3 is discussed in that section, but it involves a tight coupling to Spring and makes the application class acutely aware that it is being AOP-managed, neither of which is a recommended practice.


Simple AOP

To create an aspect with some advice that executes before all public methods in the spring package (see reference doc, section 8.2.3.4 for examples around expression syntax):

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect
public class MyAspect {
 /**
  * Log a message before entry to specified methods
  */
  @Before("execution(* spring..*(..))")
  private void logOnEntry(JoinPoint jp) {
     // JoinPoint argument is optional, but recommended as quite useful
     System.out.println("Before " + getSimpleName(jp));
  }
 /**
  * Returns the simple name of the class being advised, as per the given
  * join point.
  */
  private String getSimpleName(JoinPoint jp) {
     return jp.getTarget().getClass().getSimpleName();
  }
 }

The aspect must be managed by Spring to be put into play - add this entry to the configuration file:

<bean id="myAspect" class="spring.MyAspect"> </bean>

As you can see, you can also access the target object via the JoinPoint argument. As such, you can cast it to your application type and execute its public methods.

You can also execute advice after a method or around a method. The @After is analogous to the above example. The "execution" part of the expression is the "pointcut designator" or PCD; there are several others, but "execution" is probably what will be used the most. Since it's indicating a method-level execution, you can alter the method-portion of the expression to e.g. address only setters:

@Before("execution(* spring..set*(..))")

To address executions at a type level (i.e. all public methods in a given type), use the "within" PCD:

@After("within(*.*Service)")

You can also use the Spring bean ID declaration as an alias for a given type; so, given this bean declaration:

<bean id="family-service" class="spring.FamilyService"></bean>

...you can specify this join point using the "bean" PCD:

@After("bean(family-service)")


Reusable Pointcuts

Reusable pointcuts can be established:

/**
 * Establish a pointcut on execution of any and all public methods
 */
@Pointcut("execution(* *.*(..))")
public void anyMethod() {}

Pointcuts can be combined to form conditional expressions, using AND, OR and NOT operators (&&, ||, and !):

@Pointcut("within(com.xyz.service..*)")
private void inServiceModule() {}
@Pointcut("anyMethod() && inServiceModule()")
private void serviceOperation() {}

To intercept the throwing of an exception resulting in a method exit, using the "anyMethod" pointcut established above:

/**
 * Intercept execution when any method exits by throwing any exception
 */
 @AfterThrowing(pointcut = "anyMethod()", throwing = "ex")
 private void trackExceptions(JoinPoint jp, Exception ex) {
     System.out.println("Exception thrown from "           + getSimpleName(jp) + ": " + ex);
 }

To intercept the value returned from a specified pointcut:

 /**
  * Establish a pointcut on execution of specified method
  */
  @Pointcut("execution(* spring.Nika.getName())")
  public void getNikadogName() {}
 /**
  * Intercept the return from specified pointcut
  */
  @AfterReturning(pointcut = "getNikadogName()", returning = "name")
  private void getNikaName(String name) {
      System.out.println("after returning from nikadog, pointcut name: "
           + name + "...");
  }


Beyond the Simple

The @Around PCD is bit more sophisticated:

 /**
  * Establish a pointcut on execution of specified method
  */
  @Pointcut("execution(* FamilyService.getMember(..))")
  public void getMember() {}
 /**
  * Wrap specified method to get profiling information. Can also use this pattern
  * for tracing, caching, etc.
  */
  @Around("getMember()")
  private FamilyMember doProfiling(ProceedingJoinPoint pjp)  throws Throwable {
    long start = System.currentTimeMillis();
    FamilyMember member = (FamilyMember) pjp.proceed();
    System.out.println("Elapsed time to get member: " +        (System.currentTimeMillis() - start));
     return member;
 }

In the above snippet, the ProceedingJoinPoint facilitates setting things up before the advised object method is executed (i.e. start the stopwatch, check the cache for a hit, etc.), then supports (optionally!) executing the method, and finally returning the appropriate value - so you can see that this decorates the object execution with your own proxying code. Note that you can easily check a cache for a "hit", then simply return the cached value if it's there without executing the method, otherwise executing the method and stuffing it in the cache for subsequent requests. Using the "args" PCD, you can (e.g.) examine incoming argument values to qualify what specific object in the cache is being requested.

Note that this approach to caching relies on the aspect to manage the cache. An alternate approach will be presented in the "Introductions" section below.

Suppose our service class was throwing an exception, and we want to apply a retry strategy since the problem involves waiting for some remote resource to become available (e.g. the database is spinning up):

@Around("getMember()")
 private FamilyMember retry(ProceedingJoinPoint pjp) throws Throwable {
     int numAttempts = 0;
     int maxRetries = 5;
     Throwable t = null;
     do {
        numAttempts++;
        try {
            return (FamilyMember)pjp.proceed();
        } catch (DatabaseNotReadyException ex) {
            System.out.println("=========== Caught exception from "
                 + getSimpleName(pjp)
                + "; retry attempt #" + numAttempts + "==============");
            t = ex;
        }
     } while (numAttempts <= maxRetries);
              throw t;
   }

Introductions

A technique described above for caching relies on the aspect itself to manage the cache. An alternate approach is to implement an interface that prescribes caching functionality:

public interface Cacheable {
     public boolean isCached();
     public void save(Object obj);
     public Object fetch();
}
But we may be motivated to regard this cacheability as a cross-cutting concern, one that should be maintained and managed (enable/disable, track hits, monitor throughput gains, flush the cache, etc.) separately from the pure business logic (vs simply having FamilyService implement the interface explicitly, i.e. such that one's business classes are not responsible for determining their own "cacheability" - that's an orthogonal concern). If so, we can use AOP "introductions" to retrofit the caching.

An implementation supporting the FamilyService (and, for that matter, other services in general) might begin life like this:

public class CacheableImpl implements Cacheable {
      private boolean cached = false;
      private Object cachedObject = null;
      public boolean isCached() {
        return cached;
     }
      public void save(Object obj) {
        cachedObject = obj;
        cached = true;
     }
      public Object fetch() {
        return cachedObject;
     }
}
An "introduction" is a way of retrofitting an implementation of an interface onto the target object. Since it's AOP, the target object does not and need not know it's being decorated like this. The somewhat cryptic syntax to make it happen is encapsulated in the aspect:
@DeclareParents(value = "spring.FamilyService", defaultImpl = CacheableImpl.class)
 public static Cacheable mixin;
 .......
 @Around("getMember() && this(service)")
 public FamilyMember checkCache(ProceedingJoinPoint jp, Cacheable service) throws Throwable {
     if (service.isCached())  {
        System.out.println(" ---> Returning cached member");
        return (FamilyMember) service.fetch();
     }
     System.out.println(" ---> Member NOT cached; call service and save result...");
     FamilyMember member = (FamilyMember) jp.proceed();
     service.save(member);
     return member;
 }
Now, instead of relying on the aspect to manage caching - arguably a questionable responsibility - the details of caching are factored out to give us better cohesion. This is just one possible use of the AOP introduction.
Resources Spring 3.0.M3 Reference Documentation, by Rod Johnson et. al., 2009 Spring Framework

Wednesday, September 9, 2009

Spring Test Framework Cheatsheet

This documents some prototyping done with the Spring Test Framework (I'll refer to this as the STF). Effectively it is a paraphrase/summary of what's written up in the Chapter 10 of the Spring Framework Reference document, version 3.0.M3, with some example code snippets that I was able to get working. Consult that writeup for further detail.

Here are the high-level features of the STF that I'd consider most interesting:
  1. How to fetch the Spring application context object regardless of environment (web container, test environment, etc.)
  2. How to configure test-specific Spring contexts
  3. Simplified access to context beans
  4. Automatic rollback of test case transactions
  5. Auto-rollback without extending a superclass
  6. Odds-n-ends

How to fetch the Spring application context

This first tip is not directly related to the STF, but was discovered during my experiments with it, so I make note of it here.

 In a previous post, I presented a pattern for determining at runtime how to get a reference to the application context that would first look for a web context, and if that failed simply produce a classpath-based context. This pattern requires explicit knowledge not only of what environment is in play, but also knowledge of exactly what Spring context is appropriate for that environment. A simpler pattern can be used as follows - first, provide a class that implements ApplicationAwareContext:


public class ApplicationContextProvider 
    implements ApplicationContextAware { 
    private static ApplicationContext context;
    public static ApplicationContext getApplicationContext() {
        return context;
    }
    public void setApplicationContext(ApplicationContext context) {
        this.context = context;
    }
}

Declare that class as managed by Spring in the context file:

<bean id="appCtxProvider" 
    class="com.twc.registry.common.ApplicationContextProvider">
</bean>

Now, any class that wants a reference to the context instance can do so at runtime, whether in a web or a test/standalone environment:

ApplicationContext context = 
    ApplicationContextProvider.getApplicationContext();
MyBean myBean = (MyBean)context.getBean("my-bean");

That code snippet can of course be encapsulated and parameterized as needed, to facilitate keeping third-party framework specifics in a single point of change.

This precludes the need for a ServletContextListener as described in my previous post, simplifies the mechanics around fetching beans in the context, and eliminates the need for application awareness of explicit subclasses of the Spring ApplicationContext.

In what follows, I'll present an even simpler method for injecting dependencies directly into test classes, such that a reference to the application context is not needed.


How to configure test-specific Spring contexts

If you need to specify certain test fixtures or other test-specific dependencies, it'd be useful to both have these injected (to facilitate reuse and simplify test setup) but keep the configuration for this injection separate from production classes. Using the STF, a convenience idiom supports doing this.

First, to use the STF, add org.springframework.test-3.0.0.M3.jar to your classpath.

Configure a test-specific Spring context using the following annotation:

package com.mybiz;
@ContextConfiguration
public class MyTest {
   @Test
    public void testThis() {
          ApplicationContext ctx = 
              ApplicationContextProvider.getApplicationContext();
          MyBean myBean = (MyBean ) context.getBean("my-bean");
          // now do some tests with myBean...
    }
}

This presumes the existence of a Spring configuration file named com/mybiz/MyTest-context.xml. To otherwise specify the location:

@ContextConfiguration("/WEB-INF/MyTestConfig.xml")

Multiple resources can be specified using comma-separated lists. The default is for subclasses to inherit superclass' resource lists and optionally override bean entries; this inheritance behavior can also be disabled.


Simplified access to context beans

Now, instead of using the ApplicationContextProvider manually as in the above snippet, we can simply do this:

@Autowired  // or can annotate a setter instead of a field
private MyBean myBean;

If there are  multiple MyBean's defined in the Spring context, this type-based wiring will not suffice (without further qualification, which we ignore for now). Instead use injection by name:

@Resource
private MyBean myBean;

However, it appears (empirically...) that @Resource also wires by type, since in the above working example, I hadn't configured a bean with an ID of "myBean". It also "just works" this way:

private MyBean myBean;
@Resource  // also works with @Autowired!
private void setTheBean(MyBean theBean) {  
// notice the field and/or method are both private - but injection still works!
    myBean = theBean;
}


Automatic rollback of test case transactions

By far the most valuable feature of the STF is the ability to execute integration tests against a database without changing the database state - i.e., all transactions are automatically rolled back. Making this work is reasonably simple - first, we'll need Spring context entries to specify a data source and a transaction manager:

<bean id="dbcp-dataSource" 
    class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close">
    <property name="driverClassName" value="${database.driver}"/>
    <property name="url" value="${database.url}"/>
    <property name="username" value="${database.user}"/>
    <property name="password" value="${database.password}"/>
</bean>
<bean id="txnMgr" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dbcp-dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="txnMgr"/>
<aop:aspectj-autoproxy/>

This context configuration file must be loaded using @ContextConfiguration; we must declare @Transactional either at the class or method level; and since our transaction manager is not named "transactionManager" (the default) -- or if we would ever wish to disable auto-rollback at the class level -- we'll need to add a @TransactionConfiguration annotation:

@ContextConfiguration(locations = {"/WEB-INF/MyTestConfig.xml"})
@Transactional
@TransactionConfiguration(transactionManager="txnMgr", defaultRollback=true)
public class MyDaoTest extends AbstractTransactionalTestNGSpringContextTests {
.......
// override auto-rollback on per-method basis
    @Test
    @Rollback(false)
    public void keepThisTransactionInPlace() {
        ......
    }
    @BeforeTransaction  
// likewise, @AfterTransaction follows the transaction
    public void doBeforeTxn()
    {
// do whatever setup needed, if any, before the transaction executes
    }
}

To gain numerous conveniences, we've extended a Spring class specific to the TestNG framework (also available are Junit-specific superclasses). We could have instead added a handful of cruft to get around doing this extension, if e.g. you need to extend your own test superclass or for some other reason you're adverse to this. But the added cruft is so noisy that you'll be motivated to simply encapsulate it in your own superclass anyway, or if that's not feasible then reuse becomes a copy-paste headache. If possible, simply extending the Spring-provided convenience classes is probably the simplest thing to do.


Auto-rollback without extending a superclass

But if you must know, here's the cruft you'll need to avoid extending AbstractTransactionalTestNGSpringContextTests:

@ContextConfiguration(locations = {"/WEB-INF/MyTestConfig.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, 
    DirtiesContextTestExecutionListener.class,
    TransactionalTestExecutionListener.class})
@Transactional
@TransactionConfiguration(transactionManager="txnMgr")
public class MyDaoTest implements IHookable, ApplicationContextAware {
    private ApplicationContext applicationContext;
    private final TestContextManager testContextManager;
    private Throwable testException;
    public MyDaoTest() {
        this.testContextManager = new TestContextManager(getClass());
    }
    public final void setApplicationContext(
        ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
    @BeforeClass(alwaysRun = true)
    protected void springTestContextPrepareTestInstance() 
    throws Exception {
        this.testContextManager.prepareTestInstance(this);
    }
    @BeforeMethod(alwaysRun = true)
    protected void springTestContextBeforeTestMethod(Method testMethod) 
    throws Exception {
        this.testContextManager.beforeTestMethod(this, testMethod);
    }
    public void run(IHookCallBack callBack, ITestResult testResult) {
        callBack.runTestMethod(testResult);
        this.testException = testResult.getThrowable();
    }

    @AfterMethod(alwaysRun = true)
    protected void springTestContextAfterTestMethod(Method testMethod) 
    throws Exception {
        try {
            this.testContextManager.afterTestMethod(
                this, testMethod, this.testException);
        }
        finally {
            this.testException = null;
        }
    }

Ugly, ugly, ugly. Encapsulate!


Odds-n-Ends

There are numerous other facilities in the STF; consult Chapter 10 for the full discussion. Worth mentioning here are the following:
  1. automatic caching of loaded application contexts, to save startup time on per-method basis, once for each test fixture. Optionally instruct the framework to reload the context in case changes to state of beans in that context that are not meant to be preserved across all tests in a given fixture.
  2. JDBC utility class to facilitate querying database state.
  3. Mock objects ready-to-go for JNDI and Servlet API.
Overall, two thumbs up: this is definitely a new item in my toolbox.

Tuesday, August 4, 2009

Selenium IDE Tips

This is a quick cheatsheet for various Selenium (IDE-based) commands. There's nothing too jaw-dropping here; just a collection of tips that I've found useful.

General Usage

Here is a suggested development technique with caveats. There are lots of ways to accomplish the same thing; this is just my own approach:
  1. Start by creating a directory that is named by the use case you're testing.
  2. Create a test suite in that directory, naming it TestSuite.html. Using this convention will help distinguish the test suite from its test cases, all of which should use an HTML suffix.
  3. Create test cases one by one, immediately give the test case a title via the Properties menu item (right click over the test case object), copy that name onto your clipboard before hitting OK, and then immediately save it to the use case directory by pasting that name into the file-save dialog and appending .html.
  4. Do not expect to be able to re-use general purpose test cases from other use-case directories (e.g. a login sequence) - I've had to duplicate these in each use case that I use it in. This might be just me doing something wrong; I might need to revisit it to confirm. Obviously it sure would be nice if we could reuse things this way.
  5. Do not expect to "Add Test Case" using an existing test case which you then alter, without altering the other uses of it within your test suite. Using my techniques here, one test case == one HTML file; modifying it will modify all instances of it within that use case.
  6. Save often - ideally save test cases as soon you alter them, and save the test suite as soon as you add/delete test cases to/from it. If you change test suites, the IDE will not warn you that you have unsaved changes.
The following are some coding tips. Of course, consult the Selenium documentation for the definitive and exhaustive reference:


To confirm there's a DIV that contains an onClick handler with a given name and some template text of a given value:

<div onclick="doSomething()">foo</div>

...use this:

assertElementPresent
//div[@onclick[contains(., 'doSomething') ]][contains(., 'foo')]

The @onclick can be replaced with any attribute of the given DIV tag. The bracketed "contains" conditions can be chained, and are AND'd together.

To check/uncheck a checkbox in a table with a given ID that contains a cell with the given template text:

<table id="myID">
<tr>
    <td nowrap="nowrap">
        <input type="checkbox">check me</input>
    </td> 
</tr>
</table>

...use this:

click
//table[@id='myID']//td[contains(.,'check me')]//input


Avoid the annoying 30-second delay after clicking a link that use a JavaScript command as the HREF:

<a href="javascript:doSomething()">Do Something</a>

Set the timeout as needed:

setTimeout
1000

This will still get logged in the Selenium IDE as an ERROR, which unfortunately will result in the test being marked as failed. This of course makes it difficult to determine that your tests are in fact all green, since these failures show up as red. But I've just gotten into the habit of clearing the log before I start a test suite, and just ignoring the "[error] Timed out after 1000ms" log messages. If any other log messages are at ERROR level, these tell me there is something to look into; else, I consider my test suite to have passed.

To select an item from a menu:

select
menu
label=three

...use this:

select
menu
label=three


To enter a carriage-return character in an input field with a given ID:

keyPress
inputFieldID
13

So the number 13 is the HTML code for the carriage return character. Here's a reference of more character codes.


To click on a link with the given template text:

<a href="foobar">Click Me</a>

...use this:

click
//a[contains(text(),'Click Me')]


To consume an alert:

storeAlert



Thursday, July 9, 2009

Spring 3.0 Cheatsheet: Integration with iBatis

This is the next in a series of tips, insights and recommendations around Spring 3.0. This time, I offer our experiences to-date around use of Spring's ORM facility, or more accurately its integration with iBatis (which is not, strictly speaking, an OR mapper).

iBatis - General
  • Use iBatis "implicit result mapping", i.e. adding an alias to each column in the select field list, to match up with Java object properties so iBatis will automatically map them for you (and as such, there's no need for resultMap constructs). For example, the following maps database column names (that might need to follow database naming conventions) to the property names of the corresponding Java object:
<sql id="allFieldsFromWebapp">
      APP_ID as appID,
      DISPLAY_NAME as displayName,
      DESCRIPTION as description,
      URL as url
    from WEBAPP
</sql>

Now, instead of referring to resultMap id's, reference the class to be populated:

<typeAlias alias="WebApp" type="com.mybiz.model.WebApp"/>
....
<select id="selectAll" resultClass="WebApp">
    select  <include refid="allFieldsFromWebapp"/>
</select>
<select id="selectById" parameterClass="String"  resultClass="WebApp">
    select <include refid="allFieldsFromWebapp"/>
    where APPID = #id#
</select>

Using the <sql>, <include> and <typeAlias> tags, we gain opportunity for reuse in the SQL map file.
  • Add JDBC type as suffix to placeholder parameters in iBatis queries, as needed:

UPDATE person SET
title = #title#,
given_names = #givenNames#,
last_name = #lastName#,
date_of_birth = #dateOfBirth:DATE#
WHERE id = #id#

In the above statement, #dateOfBirth:DATE# specifies day, month and year only - since, in this case, there's no need for hours, minutes and seconds.

  • To monitor iBatis-generated SQL queries, add log4j.logger.java.sql=DEBUG to your log4j configuration file; however, this shows the precompiled statements only, without parameter substitution.
iBatis-Spring: General Database
  • Factor connection details out of the iBatis SQL map configuration and into Spring beans configuration instead, to simplify the iBatis configuration (since these details often vary between environments (eg development, test, production)) and to consolidate application-wide configuration information into a single place. Put these connection details into e.g. an Apache DBCP DataSource bean. Use the Spring PropertyPlaceholderConfigurer bean to support the externalization.
In the Spring beans file:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:database.properties"/>
    </bean>

    <bean id="dbcp-dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${database.driver}"/>
        <property name="url" value="${database.url}"/>
        <property name="username" value="${database.user}"/>
        <property name="password" value="${database.password}"/>
    </bean>

In database.properties, which exists in the default package of the classpath as per the above specification:


database.driver=oracle.jdbc.OracleDriver
database.url=jdbc:oracle:thin:@my-dev-host.mybiz.com:1521:XE
database.user=system
database.password=foobar


Now the SQL map configuration file is not concerned with connection details; it simply deals with SQL maps:

<sqlMapConfig>
  <sqlMap resource="com/mybiz/persistence/WebApp.xml"/>
</sqlMapConfig>

  • Initialize your DAO using Spring's SQL map client factory, handing it both the location of the iBatis SQL map configuration file and the DBCP data source bean as initialization parameters.
In the DAO, provide for setter-injection of an SQL map client, to be used elsewhere in your code to invoke iBatis queries:

package com.mybiz.persistence;

import com.ibatis.sqlmap.client.SqlMapClient;

public class MyDao implements DaoBase {

    private SqlMapClient sqlMapClient;

    public SqlMapClient getSqlMapClient() {
        return this.sqlMapClient;
    }

    public void setSqlMapClient(SqlMapClient sqlMapClient) {
        this.sqlMapClient = sqlMapClient;
    }

    .....

    public MyObjectCollection getAll() throws SQLException {
        MyObjectCollection coll= new MyObjectCollection ();
        coll.set((List) getSqlMapClient().queryForList("selectAll"));
        return coll;
    }
}

In the Spring beans configuration:

    <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation" value="classpath:com/twc/registry/persistence/WebAppDao.xml"/>
        <property name="dataSource" ref="dbcp-dataSource"/>
    </bean>

    <bean id="webapp-dao" class="com.twc.registry.persistence.WebAppDao">
        <property name="sqlMapClient" ref="sqlMapClient"/>
    </bean>


The SQL map client will automagically read in the SQL map configuration information.
Note that with the Spring XML beans file under ./WEB-INF, you must use the "classpath:" prefix to reference the iBatis SQL map configuration file.

Alternately, one can use the Spring SQL map client class instead of the iBatis version (see section 14.5 in the the Spring Reference Doc). The primary advantage here, as far as I can tell, is that formerly checked SQLExceptions are now wrapped in unchecked exceptions. However, I'd consider this optional, and for that matter undesirable in certain situations - e.g., in a RESTful web service where specific checked exceptions are caught so they can be mapped to corresponding HTTP response codes (and in just such a situation, I've chosen the iBatis SQL map client instead of the Spring version). The debate around documenting checked (and unchecked) exceptions as an important part of specifying program behavior is beyond the scope of this post; bottom line, sometimes wrapping exceptions that you can't do anything about with unchecked ones is useful, but sometimes your methods will intentionally throw their own checked exceptions that clients are meant to handle explicitly.

iBatis-Spring: Transactions
  • Use the Spring TransactionManager and annotation-driven transaction management to establish simple, declarative transactional behavior. Use the JDBC data source transaction manager unless you expect to be managing multiple resources in "global" transactions or want the application server to manager transactions (e.g. to take advantage of advanced features like transaction suspension, etc.), in which case use the JTA transaction manager. Downside of JTA transactions is lack of ability to test outside the container (since it requires JNDI and possibly other container functionality).You'll need to provide the AOP autoproxy tag and associated namespace attributes to get declarative transactions to work.
In the Spring beans file - note the transaction manager references the previously established DBCP data source:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       ">
    <bean id="txnMgr" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dbcp-dataSource"/>
    </bean>
    <tx:annotation-driven transaction-manager="txnMgr"/>
    <aop:aspectj-autoproxy/>

  • Annotate DAO methods as appropriate (i.e. non-read-only unless you care about non-repeatable reads, etc.) with @Transactional. This tells Spring that a transaction is required and to start one if it's not already executing within a transactional context (because the default propagation is REQUIRED). That method body will execute as one transactional unit and will auto-commit if it completes successfully. If a runtime exception is thrown, the transaction will be rolled back. This becomes increasingly important as your java method executes more than one operation (multiple updates, delete + insert, etc.)
    @Transactional
    public void delete(String objId) {
        getSqlMapClient().delete("deleteById", objId);
    }
  • Use of Spring AOP means use of proxies; so, if you want to use JDK dynamic proxying instead of CGLIB proxying, your DAOs should implement an interface that specifies its public methods (as implied above with MyDao implements DaoBase). Dynamic proxying is recommended for these reasons: with CGLIB,
    • there are more library dependencies
    • final methods cannot participate in AOP
    • constructors are called twice due to CGLIB implementation details (see the Spring Reference manual, section 9.5.5).
  • While using interfaces supports annotating methods in the interface only - i.e. you don't need to maintain these in the implementation - this is considered risky by the Spring team; so, at a minimum annotate concrete classes, and optionally annotate interfaces also (the former for the functionality, optionally the latter for documentation).
  • How do you know you're getting transactional behavior? You can monitor transaction activity by turning on a log4j appender to debug for TransactionInterceptor; then, add and remove @Transactional to various methods in your interface to observe the logging statements. In a log4j.properties file:

log4j.logger.org.springframework.transaction.interceptor.TransactionInterceptor=debug


  • While transaction behaviors can be configured programmatically, this couples the code to Spring Framework and as such is not preferred.
  • Beware of self-invocation where you expect transactional behavior - unless there's already a transactional context, a new one will not be created. Consider the use of so-called AspectJ mode if you expect self-invocations to be wrapped with transactions as well (set tx:annotation-driven mode attribute to "proxy" - but this will require use of CGLIB libraries).

Resources


Spring and iBatis Tutorial
http://www.cforcoding.com/2009/06/spring-and-ibatis-tutorial.html

iBatis Wiki
http://opensource.atlassian.com/confluence/oss/display/IBATIS/Converting+iBATIS+DAO+to+Spring+DAO

iBatis FAQ
http://opensource.atlassian.com/confluence/oss/display/IBATIS/How+do+I+reuse+SQL-fragments

Spring Reference Manual
http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/pdf/spring-framework-reference.pdf

Monday, July 6, 2009

Spring 3.0 Cheatsheet: Application Context

This is the first in a series of posts around patterns and recommendations for Spring 3.0.


Use a Facade to provide Application Context objects

We need to use a Spring ApplicationContext object to retrieve dependency-injected objects. But we want to encapsulate our use of Spring into a single point of change, so we use a facade to do this:

public class SpringFacade {

    private static FileSystemXmlApplicationContext applicationContext;

    public static ApplicationContext getApplicationContext(String fileName) {
        if (applicationContext == null) {
            applicationContext = FileSystemXmlApplicationContext(fileName);
        }
        return SpringFacade.applicationContext;
    }
}
.....
Service svc = (MyService)SpringFacade.getApplicationContext().getBean("myService");

Use a Factory to support both Standalone and Web Application Context objects

While we want a plain vanilla standalone Application Context in a test environment, we need a web-aware flavor in a web deployment. This has the following advantages:

  1. web-centric scopes (i.e. request and session - see Spring reference doc section 4.4.4)
  2. multiple lifecycle events after initial program startup (section 4.8.3)
  3. web-centric resources like the ServletContext (5.4)
  4. view resolvers (17.2.1)
  5. Spring-centric dependency injection in a JSF environment (19.3)
  6. and etcetera

So we need a factory mechanism to decide at runtime which way to go - assuming of course we want to test our web classes, which of course we do. After all, one of Spring's advantages is loose coupling to facilitate testability.

Now, while it's true that I could probably figure out a way (aka a hack) to convince a test class to use a web-aware Spring context, and not have to bother with this factory nonsense, I'd rather spend my time figuring out a way to do things that have good design sensibilities.

First, use a ServletContextListener to cache a web-aware implementation:

public class SpringInitializer implements ServletContextListener {

    private static WebApplicationContext springContext;
    private Logger logger = Logger.getLogger(getClass().getSimpleName());

    public void contextInitialized(ServletContextEvent event) {
       logger.info("In a web environment: get a Spring web application context");
       springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
    }

    public void contextDestroyed(ServletContextEvent event) {
        springContext = null; // facilitate garbage collection to support hot redeployments
    }

    public static ApplicationContext getApplicationContext() {
        return springContext;
    }
}

Next, configure the web deployment descriptor to (1) specify the location of the config file(s), (2) load the context listener that will access those locations and (3) load the listener (Spring reference manual, section 4.8.5):
<?xml version="1.0" encoding="UTF-8"?>
 <web-app version="2.5">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/myBeans.xml, /WEB-INF/yourBeans.xml, /WEB-INF/**/*Context.xml</param-value>
    </context-param>
.........
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>com.mybiz.SpringInitializer</listener-class>
    </listener>
.........
  </web-app>

Now the facade takes on factory-type responsibilities to decide dynamically which context to return:
public class SpringFacade {
    private static FileSystemXmlApplicationContext applicationContext;

    public static ApplicationContext getApplicationContext() {
       ApplicationContext context = SpringInitializer.getApplicationContext();
       if (context == null) {
           factory.logger.info("Returning class-path-XML app context");
           context = new ClassPathXmlApplicationContext("WEB-INF/beans.xml");
       } else {
          factory.logger.info("Returning web app context");
       }
    }
}



Next, I'll post an approach to using iBatis with Spring.

Wednesday, May 13, 2009

JSF Cheatsheet

Here's a collection of various idioms, patterns, tips, and etc. around JSF 1.2. It's a work in progress that I'll be adding to over time. So far, it's compiled by pulling stuff from the following websites - and I thank each of the authors for my reproduction of their content here:

Preso by Ed Burns:
https://javaserverfaces.dev.java.net/presentations/demystifyingjsf.pdf

Tutorial from IBM (requires registration but is worth the hassle):
https://www6.software.ibm.com/developerworks/education/j-jsf1/section7.html

JSF Anti-Patterns and Pitfalls
http://www.theserverside.com/tt/knowledgecenter-is/knowledgecenter-is.tss?l=JSFAnti-PatternsandPitfalls

Java EE 5 Tutorial
http://java.sun.com/javaee/5/docs/tutorial/doc/bnaph.html

Declare Faces Servlet in web.xml:
<servlet>
  <servlet-name>Faces Servlet</servlet-name>
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet> 
 
<servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>/faces/*</url-pattern>
</servlet-mapping>

JSF Configuration File

If you name your Faces configuration file faces-config.xml and place it in your Web application's WEB-INF directory, then the Faces Servlet picks it up and uses it automatically (because it's the default). Alternatively, you can load one or more application-configuration files through an initialization parameter — javax.faces.application.CONFIG_FILES — in your web.xml file with a comma-separated list of files as the body. You will likely use the second approach for all but the simplest JSF applications (but be sure to not list faces-config.xml in that initialization parameter, or any registered phase listeners will fire twice).

Sample JSF config file:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
  <managed-bean>
    <managed-bean-name>myBean</managed-bean-name>
    <managed-bean-class>com.mydomain.MyBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>
</faces-config>
JSF configuration files are specified via the javax.faces.CONFIG_FILES context parameter in web.xml:

<context-param>
  <description>comma separated list of JSF conf files</description>
  <param-name>javax.faces.CONFIG_FILES</param-name>
  <param-value>
    /WEB-INF/menu-config.xml,
    /WEB-INF/services-config.xml
  </param-value>
</context-param>
Again: do not specify faces-config.xml in this context-param -- if you do, any registered phases listeners will fire twice.


Declare standard JSF tags:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
The html taglib contains all the tags for dealing with forms and other HTML-specific items. The core taglib contains all the logic, validation, controller, and other tags specific to JSF.

An <h:panelGrid> can contain only components, whereas <h:form>, <f:view> and <h:panelgroup> can contain both HTML and components.

Import stylesheets:

<head>
  <title>My Application</title>
  <link rel="stylesheet" type="text/css"
    href="<%=request.getContextPath()%>/css/styles.css" />
</head>

User-Facing Messages

Customize messages (this approach does not scale, since it must be repeated for each section needing it):

<%-- case by case basis; message appears immediately to right of field --%>
<h:outputLabel value="Zip Code" for="zipcode" />
<h:inputText id="zipcode" label="Zip Code"
  value="#{myBean.zipcode}" required="true"
  requiredMessage="required" converterMessage="not a valid zip code"/>
<h:message for="zipcode" />
Change messages globally (this scales well, can be overridden as needed using case-by-case approach):

  • Add this tag to beginning of JSF config file(s):
<application>
  <message-bundle>mymessages</message-bundle>
</application>
  • Add entries to mymessages.properties resource bundle:
javax.faces.component.UIInput.REQUIRED_detail=value is required
javax.faces.converter.IntegerConverter.INTEGER_detail=that's not a valid integer
The complete list of default messages are found in the JSF 1.2 RI jarfile jsf-impl.jar, under javax.faces.Messages.properties.

In case the standard error messages don’t meet your needs, create new ones in resource bundles and configure the resource bundles in your application configuration resource file. For example, this message is stored in the resource bundle, MyMessages.properties:

invalidZipCode=The value you entered is not a zip code.

The resource bundle is configured in the application configuration file:

<application>
  <resource-bundle>
    <base-name>com.mydomain.MyMessages</base-name>
    <var>msgs</var>
  </resource-bundle>
</application>
The base-name element indicates the fully-qualified name of the resource bundle. The var element indicates the name by which page authors refer to the resource bundle with the expression language:

<h:inputText id="zipcode" label="Zip Code"
  value="#{myBean.zipcode}" converterMessage="#{msgs.invalidZipCode}">
...
</h:inputText>
Add messages to be displayed based on outcomes in server-side processing:

<h:messages infoClass="infoClass" errorClass="errorClass"
  layout="table" globalOnly="true"/>
....
<h:inputText id="minimum" label="Minimum"
  value="#{myBean.modelObject.minimum}" required="true"
  binding="#{myBean.minimum}" />
<h:message for="minimum" errorClass="errorClass"/>
....

acesContext facesContext = FacesContext.getCurrentInstance();
try {
...
  facesContext.addMessage(null, new FacesMessage(
    FacesMessage.SEVERITY_INFO, "Completed successfully", null));
...
} catch (Exception ex) {
  facesContext.addMessage(null,
    new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), null));
...
} 

Adjust styles dynamically

<h:outputLabel value="Minimum" for="minimum"
  styleClass="#{myBean.minimumStyleClass}"/>
......
public String getMinimumStyleClass() {
  if (minimum.isValid()) {
    return "labelClass";
  } else {
    return "errorClass";
  }
} 

Access Component from Java

Factor out logic from JSP into managed bean (bind component to managed bean; lets you manipulate the component's state programatically without traversing the component tree to get to the component):

<h:panelGroup binding="#{myBean.panel}" rendered="false">
.......
private UIPanel panel;
public UIPanel getPanel() {
  return panel;
}

public void setPanel(UIPanel panel) {
  this.panel = panel;
}

public String execute() {
...
  try {
    modelObject.doSomething();
    panel.setRendered(true);
...
  } catch (Exception ex) {
...
    panel.setRendered(false);
  }
  return null;
} 

Injection into managed beans:

Using standard JSF Inversion of Control configuration:

<managed-bean>
  <managed-bean-name>myBean</managed-bean-name>
  <managed-bean-class>
    com.myDomain.MyBean
  </managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
    <property-name>modelObject</property-name>
    <value>#{modelObject}</value>
  </managed-property>
</managed-bean>
<managed-bean>
  <managed-bean-name>modelObject</managed-bean-name>
  <managed-bean-class>
    com.myDomain.MyModel
  </managed-bean-class>
  <managed-bean-scope>none</managed-bean-scope>
</managed-bean>
If you need to explicitly manage the order in which properties are set:

  • The specification states that a JSF implementation must inject the dependencies of a managed bean in the order in which they are configured
  • Applications that are using JSF 1.2 can take advantage of the PostConstruct annotation. Below, the PostConstruct annotation instructs the JSF implementation to invoke the initialize method after the managed bean has been created.
private ModelAttrs min, max; // injected
    // no setters and getters for min, max
  @javax.annotation.PostConstruct
  public void initialize() {
    if(min == null || max == null) {
      throw new NullPointerException("init failed - min or max is null");
    }
    if(min > max)) {
      throw new IllegalStateException("min cannot be larger than max");
    }
  }
However, it's still possible to call the no-arg constructor from somewhere other than the JSF framework, so this is not bulletproof.


  • Use a full blown dependency injection framework. Using Spring is as easy as placing the following lines of code in your JSF deployment descriptor.
<application>
  <variable-resolver>
    org.springframework.web.jsf.DelegatingVariableResolver
  </variable-resolver>
</application>
A JSF implementation is not required to warn you about misspelled class names or cyclical references in managed bean declarations at startup, but both will result in a runtime exception. JSF 1.2 will warn you about duplicate managed bean declarations but 1.1 will not.

Use JSFUnit to help address these types of problems (although I've yet to try it, so I'm unclear about the status of JSFUnit static analysis features, but it appears that the runtime testing is GA). You can also avoid some of these problems with annotations libraries found in Seam or Shale.




Navigation

Navigate via comandLink and navigation rule -from *any* view - URL in browser doesn't change (can't bookmark):

<navigation-rule>
  <from-view-id>*</from-view-id>
  <navigation-case>
    <from-outcome>services</from-outcome>
    <to-view-id>/pages/services.jsp</to-view-id>
  </navigation-case>
</navigation-rule>
...
<h:commandLink action="services" value="Go To Services"/>
More specific but still a generic "from-view" configuration:

<navigation-rule>
  <from-view-id>/pages/*</from-view-id>
  <navigation-case>
    <from-outcome>services</from-outcome>
    <to-view-id>/pages/services.jsp</to-view-id>
  </navigation-case>
</navigation-rule>
Navigation with change to URL in browser address bar:

<navigation-rule>
  <navigation-case>
  <from-outcome>services</from-outcome>
    <to-view-id>/pages/services.jsp</to-view-id>
    <redirect/>
  </navigation-case>
</navigation-rule>
Navigate directly (considered an antipattern: does not go through controller, thus no opportunity to initialize the model, etc.)

<h:outputLink value="pages/services.jsp">
  <h:outputText value="Go To Services"/>
</h:outputLink>

EL implicit objects

These give access to web scopes and more: cookie, facesContext, header, headerValues, param, paramValues, request, requestScope, view, application, applicationScope, initParam, session, sessionScope.


Lifecycle

The Lifecycle dictates how an incoming request is handled and how a response is generated. Two "portions" of lifecycle are "execute" and "render", each of which has phases:

  • Execute
    • Finding the View on which to operate (Restore View - initialize new view or restore existing)
    • Allowing components to get their values (Apply Request Values; process events - if conversion errors (from request to local value of component), store message in FacesContext, goto Render Response; if immediate=true, then validation/conversion/event processing is done here)
    • Ensuring the values are converted and validated (Process Validations; if validation errors, store message in FacesContext and goto Render Response)
    • Updating the model (Update Model Values - apply component local values to corresponding server-side object properties; process events; if conversion errors, goto Render Response)
    • Invoke Application - handle application-level events, e.g. submit a form, link to a page, etc.
  • Render
    • process events from Invoke Application phase
    • Selecting and rendering the new view (Render Response)
process events: Ensure any event listeners are called - can declare Response Complete to short-circuit lifecycle. For example, an application might need to redirect to a different web application resource, such as a web service, or generate a response that does not contain JavaServer Faces components. In these situations, the developer must skip the rendering phase by calling FacesContext.responseComplete.

When the life cycle handles an initial request, it only executes the restore view and render response phases because there is no user input or actions to process. Conversely, when the life cycle handles a postback, it executes all of the phases.

You can install PhaseListeners into the Lifecycle to do whatever you want before or after each or every phase. PhaseListeners are registered in a JSF configuration file:

<lifecycle>
  <phase-listener>com.myDomain.MyPhaseListener</phase-listener>
</lifecycle>
Each PhaseListener is global to the application and it subscribes to at least one phase event for every request, thus it is NOT thread-safe.



Event Handlers
  • Action Listeners use the observer pattern - they listen for events on a component (clicked, scrolled, etc). Accept one ActionEvent arg, return void.
  • Value Change Listeners listen for events around component value being changed. Accept one ValueChangeEvent arg, return void.
  • Actions return navigation outcomes. Accept zero-args, return String.

Steps in developing a JSF application
  • Create development directory structure
    • typical webapp layout
    • need JSF 1.2 jars
  • Create config files
    • web.xml
      • add servlet/servlet mapping for Faces Servlet
      • add context-param elements as needed
    • JSF configuration file(s) (a single faces-config.xml by default)
      • nav rules, managed beans, etc.
      • declare custom message.properties file for user-facing messaging
      • create many smaller config files vs one large one, partitioned as appropriate
    • messages.properties
      • override standard JSF messages as needed
  • JSF-specific steps
    • create pages
    • JSF tags: event handlers, validators, converters, messaging, etc.
    • define navigation
    • develop managed beans
    • provide properties, handle events, delegate to business classes, navigation logic
    • Tip: aggregate multiple models into a single managed bean (via compose-and-delegate) to present a facade to JSP
  • Add managed bean declarations
  • Build, deploy, and test the application
  • Iterate on JSF-specific steps and build/deploy/test

Thread Safety
The component will get a new Converter instance each time it is needed when you register a Converter and use a converter tag, thus this is a thread-safe approach:

<converter>
  <converter-id>myConverter</converter-id>
  <converter-class>com.myDomain.myConverter</converter-class>
</converter>

<h:inputText value="#{managedBean.value}" >
  <f:converter converterId="myConverter" >
</h:inputText>  
Using the converter attribute however could introduce a race condition because it is possible the same Converter instance will be used simultaneously by more than one request.

<managed-bean>
  <managed-bean-name>myConverter</managed-bean-name>
  <managed-bean-class>com.myDomain.myConverter</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<h:inputText value="#{myBean.value}" converter="#{myConverter}" /> 
Custom Validators have the same thread safety constraints as custom Converters.


View-State Encryption

By default, view state will not be encrypted. However, there is a way to do this with Mojarra. Specify a environment entry like so:

<env-entry>
  <env-entry-name>ClientStateSavingPassword</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>[SOME VALUE]</env-entry-value>
</env-entry>
The presence of this JNDI entry will cause the state to be encrypted using the specified password...this isn't the most secure way of conveying a password, however, this cannot be accessed easily without having code executed on the server side.