web application

When SFSBs should be used in web systems

Posted on Updated on

http://onjava.com/onjava/2001/10/02/ejb.html 

Systems that have JSP/servlet front-ends should use HttpSession objects to store session-oriented state on behalf of a client. Applications that manage an HttpSession object and an SFSB for a single client wind up duplicating effort that does not need to be duplicated. There are two reasons to use an SFSB in conjunction with an HttpSession object: 

  • Your application server does not provide cache management of HttpSession instances and your system is expected to have a large number of concurrent clients. Containers for SFSBs can activate and “passivate” the state of instances to and from a secondary store. This allows a container to create an upper limit to the number of instances that will exist in memory at any given point in time. The number of concurrent clients can exceed the limit of SFSB instances in memory because the container can swap idle instances to and from the secondary store. The container will never allow more than the limit of SFSB instances to exist in memory, subsequently placing all additional instances into the secondary store. This provides a greater level of scalability to the system through effective memory management.


  • Many application servers provide similar cache management of HttpSession objects. Because HttpSession objects are similar to SFSBs, they can also be made passive and active. Cache management behavior of HttpSession objects is not required as part of J2EE and is considered a vendor value-add. If your application server does not supportHttpSession cache management — and you need to control the total number of session-oriented instances in memory at any given time — you should place the bulk of your session-oriented data in an SFSB instead of an HttpSession object. You will still need to maintain an HttpSession for each client, but the only item in the HttpSession should be a reference to the SFSB for that client. If the only item in the HttpSession object is a reference to the SFSB, the amount of memory consumed by each HttpSession object is minimal and cache management of these instances is not needed. The bulk of memory consumption will occur within the SFSBs, which have a standardized strategy for allowing a container to perform cache management.


  • Your session-oriented objects need to receive notifications on the lifecycle of the transactions they participate in. SFSBs can implement the SessionSynchronization interface. The SessionSynchronization interface contains three methods that a container invokes as a transaction migrates through the lifecycle the SFSB is participating in. An SFSB might implement the SessionSynchronization interface as a way to return the data of the SFSB to its original state whenever there is a transaction rollback. HttpSessioninstances do not have a mechanism that allows them to receive transaction notifications. This means that any data that is modified in an HttpSession during a transaction will not be reverted if the current transaction is rolled back. All changes to data in an HttpSession object are always durable despite the outcome of any executing transactions. If this behavior is not appropriate for your system, placing all data into an SFSB instance that implements SessionSynchronization will give you the appropriate behavior.
  • Don’t use @PersistenceContext in a web app…

    Posted on Updated on

    source:http://weblogs.java.net/blog/ss141213/archive/2005/12/dont_use_persis_1.html 


    I wrote an example web application that uses Java Persistence API. My servlet code looked like this:

    public class RegistrationServlet extends HttpServlet {
    // inject default EntityManager
    @javax.persistence.PersistenceContext private EntityManager em;
    @Resource private UserTransaction utx;
    public void service ( HttpServletRequest req , HttpServletResponse resp)
    throws ServletException, IOException {
    ...
    utx.begin();
    em.persist(credential);
    utx.commit();
    ...
    }
    ...
    }
    This code worked, but only by chance. I did not realize that I have committed a horrible mistake in my servlet code. As the servlet spec suggests, unless explicitly mentioned in the deployment descriptor (web.xml) as SingleThreadModel, a single servlet instance by default can be shared to serve multiple requests concurrently. i.e. multiple threads can simultaneously enter the service() method of our servlet because we have not marked the service() assynchronized. As a result multiple threads will share the same PersistenceContext object via the instance variable em. A persistence context is not required to be thread safe as per the spec and is typically designed not to be used concurrently. Because the behavior is timing dependent and I had a tiny example, I did not see this issue during testing.
    What is the fix
    If we can’t use @PersistenceContext to inject an EntityManager, what is the fix? The fix is to either
    use @PersistenceUnit to inject an EntityManagerFactory and use it to get hold of an EntityManager,
    or
    declare a dependency on an EntityManager and use JNDI to look it up.
    The former one is called application managed entity manager because application manages the life cycle (by calling EntityManagerFactory.create & EntityManager.close) where as the later one is called container managed entity manager because container manages life cycle. More discussion on differences between container managed vs. application managed will be done in a later article. Let’s discuss the fix using both the approaches. Let’s discuss each approach using code samples.
    Container Managed Entity Manager
    There are a couple of ways to use JNDI lookup of entity manager:
    a) via annotation:
    @PersistenceContext(name="persistence/LogicalName", unitName="ActualPUNameAsItAppearsInPersistence.xml")
    public class RegistrationServlet extends HttpServlet {
    @Resource private UserTransaction utx;
    public void service ( HttpServletRequest req , HttpServletResponse resp)
    throws ServletException, IOException {
    Context envCtx = InitialContext().lookup("java:comp/env");
    EntityManager em = (EntityManager) envCtx.lookup("persistence/LogicalName");
    ...
    utx.begin();
    em.persist(credential);
    utx.commit();
    ...
    }
    ...
    }
    Note that there is no injection going on here since the annotation @PersistenceContext appears at the class level. This is an alternative to declaring the persistence context dependency via a persistence-context-ref in web.xml as discussed below (in option #b).
    b) via persistence-context-ref in web.xml
    In web.xml, add an element like this:
     < persistence-context-ref>
    < persistence-context-ref-name>
    persistence/LogicalName
    </persistence-context-ref>
    < persistence-unit-name>
    ActualPUNameAsItAppearsInPersistence.xml
    </persistence-unit-name>
    </persistence-context-ref>
    Now do a JNDI lookup in your code as shown below:
    public class RegistrationServlet extends HttpServlet {
    @Resource private UserTransaction utx;
    public void service ( HttpServletRequest req , HttpServletResponse resp)
    throws ServletException, IOException {
    Context envCtx = InitialContext().lookup("java:comp/env");
    EntityManager em = (EntityManager) envCtx.lookup("persistence/LogicalName");
    ...
    utx.begin();
    em.persist(credential);
    utx.commit();
    ...
    }
    ...
    }
    While using container managed entity manager (whether option #a or #b is used), we did not call em.close() because container is managing the life cycle of underlying persistence context. We also did not have to call utx.rollback() because web container would automatically rollback a transaction at the end of http request processing if servlet does not end the tx.
    Application Managed Entity Manager
    public class RegistrationServlet extends HttpServlet {
    // inject EntityManagerfactory
    @javax.persistence.PersistenceUnit private EntityManagerFactory emf;
    @Resource private UserTransaction utx;
    public void service ( HttpServletRequest req , HttpServletResponse resp)
    throws ServletException, IOException {
    EntityManager em = emf.createEntityManager();
    try {
    ...
    utx.begin();
    em.persist(credential);
    utx.commit();
    ...
    } catch (Exception e){
    try {
    utx.rollback();
    } catch (Exception e) {}
    } finally {
    em.close();
    }
    }
    ...
    }
    See we call close() to close the EntityManager. More over note the use of try catch finally block. Since em.close() can not be called as long as the associated transaction is complete either by calling commit() or rollback(), we have to write those try catch finally.
    Is it mentioned any where in the spec?
    In Transaction Management chapter, section #4.2.3 of Java EE 5 proposed final draft spec, it is mentioned that:
    In web components not implementing SingleThreadModel, transactional resource
    objects should not be stored in class instance fields, and should be acquired
    and released within the same invocation of the service method.
    If you want to draw an analogy with JDBC world then EntityManager is like a Connection, where as EntityManagerFactory is like a DataSource. So EntityManager (or a PersistenceContext) which is a transactional resource should not be stored in a instance field and hence should not be injecte into a web app that does not implement SingleThreadModel.EntityManagerFactory is thread safe, so it can be injected into the servlet.
    What is the performance over head?
    Creation of a EntityManagerFactory is typically a costly operation. But creation of EntityManager is not. So creating an EntityManager is inside service() does not have negative impact on performance.
    What about thread safety of UserTransaction?
    If you see the code above, it still injects a UserTransaction object and stores in an instance field. That is not issue because it is a stateless object and can be shared across multiple threads. Looking at the javadocs for UserTransaction, it is clear that it by itself does not represent the transaction object, instead it is an interface to the underlying transaction manager to begin a new transaction and associate that with current thread; and end a transaction associated with current thread.

    According to TLD or attribute directive in tag file, attribute value does not accept any expressions

    Posted on Updated on

    According to TLD or attribute directive in tag file, attribute value does not accept any expressions

    Keywords:
    Compile JSP tomcat JSTL error “According to TLD or attribute directive in tag file, attribute value does not accept any expressions”

    Problem:
    Compile error from tomcat when it encounters a JSP: “According to TLD or attribute directive in tag file, attribute value does not accept any expressions”

    Solution:
    For some reason the JSP is using the 1.2 JSP (and 1.0 JSTL) and EL expressions aren’t understood. There’s a lot of hits on the web for this but in summary there are 2 important things to do to ensure you’re getting the right version of the spec:

    1. Reference the correct servlet specification in your deployment descriptor:
      <?xml version="1.0"?>
      <web-app version="2.4"
      xmlns="http://java.sun.com/xml/ns/j2ee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    2. Reference the correct JSTL uri in your JSP:
      change
      <%@ taglib uri='http://java.sun.com/jstl/core' prefix='c'%>

      to

      <%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>

    Notes:

    What Specification goes with what?
    Web-app(deployment schema) 2.3 2.4 2.5
    http://java.sun.com/dtd/web-app_2_3.dtd http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
    Servlet 2.3 2.4 2.5
    JSP 1.2 2.0 2.1
    JSTL(core uri reference) 1.0 1.1 1.2
    http://java.sun.com/jstl/core http://java.sun.com/jsp/jstl/core http://java.sun.com/jsp/jstl/core
    Tomcat 4.x 5.x 6.x
    WebSphere 5.x 6.x 7.x (?)


    Invalid servlet mapping in tomcat

    Posted on Updated on

    A common exception ,”Invalid <url-pattern> servlet mapping” when deploying application server in tomcat. 
    The url-pattern specification:
    • A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for path mapping.
    • A string beginning with a ‘*.’ prefix is used as an extension mapping.
    • A string containing only the ’/’ character indicates the “default” servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.
    • All other strings are used for exact matches only.

    invalid web.xml:

    <servlet>    <servlet-name>remoteLoggingServlet</servlet-name>    <servlet-class>com.google.gwt.logging.server.RemoteLoggingServiceImpl</servlet-class>  </servlet>    <servlet-mapping>    <servlet-name>remoteLoggingServlet</servlet-name>    <url-pattern>mweb/remote_logging</url-pattern>  </servlet-mapping>   

    valid web.xml:

     <servlet>    <servlet-name>remoteLoggingServlet</servlet-name>    <servlet-class>com.google.gwt.logging.server.RemoteLoggingServiceImpl</servlet-class>  </servlet>    <servlet-mapping>    <servlet-name>remoteLoggingServlet</servlet-name>    <url-pattern>/mweb/remote_logging/*</url-pattern>  </servlet-mapping>   

    Changing maven-war-plugin output directory

    Posted on Updated on

    If you pack your project using maven war plugin, eg: using command: (
    mvn war:war

    The default output directory is:
    ./war

    Sometimes we want to change the output directory to:
    ./src/main/webapp

    Following are the pom.xml configuration examples:

     <plugins>
               
    <plugin>
                   
    <groupId>org.apache.maven.plugins</groupId>
                   
    <artifactId>maven-war-plugin</artifactId>
                   
    <version>2.0</version>
                   
    <configuration>
                       
    <warName>your-war-name</warName>
                       
    <outputDirectory>src/main/webapp</outputDirectory>
                   
    </configuration>
               
    </plugin>
           
    </plugins>

    Maven – Generate web project for eclipse with maven

    Posted on

    To generate an empty project from the scratch you just need 2 command line:

    1. generate a web project with maven
    2. generate eclipse project.

    1. Generate web project with maven:


    Generally, to generate a project from maven, we need to do the following command:


    mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

    Usage example:

    mvn archetype:generate -DgroupId=net.webanalytics -DartifactId=webapp -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false.

    2. Convert to  eclipse project:

    mvn eclipse:eclipse -Dwtpversion=2.0

    What version of Eclipse does WTP work with?

    • WTP 1.0.x runs on Eclipse 3.1.x.
    • WTP 1.5.x runs on Eclipse 3.2 (a.k.a. Callisto).
    • WTP 2.0.x runs on Eclipse 3.3 (a.k.a. Europa).
    • WTP 3.0.x runs on Eclipse 3.4 (a.k.a. Ganymede).
    • WTP 3.1 runs on Eclipse 3.5 (a.k.a. Galileo).
    • WTP 3.2 runs on Eclipse 3.6 (a.k.a. Helios).
    • WTP 3.3 runs on Eclipse 3.7/4.1. (a.k.a. Indigo)
    • WTP 3.4 is intended for Eclipse 3.8/4.2. (a.k.a. Juno)