Posts

Showing posts from July, 2009

Multiple Log4J instances in a WebApp

Many times I've come across the classic problem of different logging instances in an web app server. Most of them involve classloader conflicts: The webapp has log4j.jar but the webapp has bundled log4j.jar as well and you get errors. OR you have the log4j.jar in the application server's shared library directory and you have 2 webapps but the configuration conflict - or even just a configuration for the application server itself and one for the webapp. I've finally come across a solution for log4j. It involves using a repository selector based on a context, this is fully described here - Supporting the log4j RepositorySelector in Servlet Containers . So the solution to stop conflicts and independently configure each application is this. First put ALL logging jars in the shared library directory including ( log4j.jar, slf4j-api.jar, slf4j-log4j.jar, commons-logging.jar, etc). This ensures that if they one of the libraries is loaded in the main classloader it can access the

Access Control in JSF using a PhaseListener

After doing a quick search of the web, I did not find any nice solutions to implementing access control in JSF. Using a servlet filter mapping seemed inadequate, and there wasn't any obvious place to start. I initially tried using a custom NavigationHandler, however that is only used after an action is performed (e.g. #{someBean.action} ), and not for directly accessing a URL (e.g. typing in /test.faces). Some more searching revealed that a PhaseListener was the place to do it. After checking the JSF lifecycles I determined that RESTORE_VIEW was the correct place to do it - ALL pages go through at least the RESTORE_VIEW and RENDER_VIEW phases. You can check the viewId in the afterPhase (as the view has been loaded in this phase, hence can't check in beforePhase) and redirect using the navigation handler as nesecary. Below is my implementation of it. I used a flexible inclusion/exclusion filter so I can make the rules as complex as I want. This implementation determines

JSF - Injecting Managed Beans into Managed Beans

Using Google Guice and JSF with something like GuiceSF to inject the JSF managed beans (backing beans) gives you a lot of power over the injection. However, by doing so JSF no longer resolves the EL expressions from faces-config.xml and injects them into the managed beans. An easy way around this, and somewhat cleaner, is to create an annotation that is 'bound' to an EL expression. To do so requires the use of GuiceyFruit's extensions to Guice. First create the annotation: import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; import com.google.inject.BindingAnnotation; /** * Injection by expression language. * @see com.google.inject.name.Named */ @BindingAnnotation @Target( { FIELD, PARAMETER, METHOD }) @Retention(RUNT

EJB3 Stateful Session Beans with ejbCreate

I had trouble obtaining a stateful session bean using the EJB3 pattern when trying to pass initial data to it. You can use injection to create instances of stateful beans by simply declaring an instance variable in a bean, for example: @EJB MyStatefulLocal mylocal; . But this doesn't allow you to pass any data on creation. The answer is to use a EJBLocalHome interface like in EJB2 but it's a bit complicated with all the annotations. The ejbCreate method from EJB2.1 is called create in the local home interface and called whatever you want in the bean itself (as long as it is annotated with @Init Below is an example. You can download the source here: download source . /** Local Interface. Dummy interface to enable us to return the Business interface. */ public interface MyStatefulLocalEjb2 extends EJBLocalObject, MyStatefulLocal {} /** Local Business Interface. Put business method definitions here */ public interface MyStatefulLocal {} /** Define method(s) which create the E

Reacquiring a Stateful Session Bean on NoSuchEJBException

In the current project I'm working on I'm using a Tomcat server connecting to a remote JBoss instance. We're using a Stateful Session Bean (SFSB) to hold the session information for the current user for authentication/access control purposes. The bean is stored in tomcat within the session (within a session-scoped managed bean actually) and generally it works fine. However, if the bean is destroyed on the server then, as per the EJB specification, an NoSuchEJBException is thrown. This could be handled individually by catching the exception, printing a user friendly message and getting a new instance of the session bean. However, it you've got several method calls across multiple classes, having this try/catch code throughout all the classes bloats the code and just plain looks ugly. I wanted a solution where I didn't need to touch the module variable that stored the EJB given to me by jboss - I wanted it to obtain a new instance itself. The reason being, if I hav