Wednesday, January 29, 2014

How to run JSF 1.2 Application in JBoss AS 7.1.1 Final

In one of my earlier post I have described how can we upgrade the JSF version. Yesterday, I was being asked that how can we downgrade the version. So I created a sample project to do this. It is true that many of you have applications developed in older version of Java Server Faces, JSF 1.2 and if you want to run those application in JBoss AS 7.1.1 maybe these post will help you.
JBoss AS 7.1.1 comes with the backward compatibility of JSF 1.2. The required jars can be found in the following path:
  • jsf-impl: <path_to_your_server>/modules/com/sun/jsf-impl/1.2
  • jsf-api: <path_to_your_server>/modules/javax/faces/api/1.2
But you need to inform the server that your application is a JSF 1.2 application. To do this you need to:
  • Declare your webapp version to Servlet 2.5. 
  • Define a context param which would tell JBoss to use JSF 1.2.
Here is my webapp declaration:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> 
</web-app>
And the context param is:
<context-param>
 <param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>
 <param-value>Mojarra-1.2</param-value>
</context-param>
You don't need to place JSF 1.2 jars in your WEB-INF/lib. When you run the application if you see:
12:15:34,896 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-9) Initializing Mojarra (1.2_15.jbossorg-1-20111019-SNAPSHOT) for context '/your-app'
in your console you are good to go.
Cheers.
Download.

Wednesday, January 1, 2014

Measuring Execution Time of ADF Faces Lifecycle

Happy New Year first of all to all of you.

Recently in one of my project, I have a requirement to measure the amount of time that my application takes to render the view. Googling not much reveals anything, except one solution[1] which is for applicable for JSF. Although ADF is built upon JSF Framework, the Lifecycle of ADF is much bigger than JSF so I can't really use that approach completely. But the building block of my solution starts from there.

In my solution I dealt with the class oracle.adf.controller.v2.lifecycle.PagePhaseListener. It is an interface implemented by the objects that wish to be notified before and after the processing of each of the ADF Page Lifecycle phase.

First you need to register your custom page phase listener through the adf-settings.xml. Follow the instruction given in the second link of the reference section[2]. Here is my adf-settings.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<adf-settings xmlns="http://xmlns.oracle.com/adf/settings">
 <adfc-controller-config xmlns="http://xmlns.oracle.com/adf/controller/config">
  <lifecycle>
   <phase-listener>
    <listener-id>PhaseProcessingTimeAnalyserListener</listener-id>
    <class>com.myproject.web.lifecycle.PhaseProcessingTimeAnalyserListener</class>
   </phase-listener>
  </lifecycle>
 </adfc-controller-config> 
</adf-settings>
The class PhaseProcessingTimeAnalyserListener pushes the phase which is currently executing into a collection from the method beforePhase and kind of pop it from that collection from the method afterPhase. The code is pretty much self explanatory.
import java.io.Serializable;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.Map;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

import oracle.adf.controller.v2.lifecycle.Lifecycle;
import oracle.adf.controller.v2.lifecycle.PagePhaseEvent;
import oracle.adf.controller.v2.lifecycle.PagePhaseListener;
import oracle.adf.share.ADFContext;

import com.mhis.posm.web.lifecycle.helper.PhaseProcessor;

/**
 * Class PhaseProcessingTimeAnalyserListener calculates the execution time of each Phase of ADF
 * @author TapasB
 */
public class PhaseProcessingTimeAnalyserListener implements PagePhaseListener, Serializable {

 private static final long serialVersionUID = 6814928970314659328L;

 /**
  * Method beforePhase notifies the listener before the execution of a specific phase of the ADF Page Lifecycle.
  * @author TapasB
  * @param phaseEvent
  * @see oracle.adf.controller.v2.lifecycle.PagePhaseListener#beforePhase(oracle.adf.controller.v2.lifecycle.PagePhaseEvent)
  */
 @Override
 public void beforePhase(PagePhaseEvent phaseEvent) {
  int phaseId = phaseEvent.getPhaseId();
  String phaseName = Lifecycle.getPhaseName(phaseId);
  PhaseProcessor.getInstance().process(getRequestId(), getURL(), phaseId, phaseName, PhaseProcessor.PhaseType.BEGIN);
 }

 /**
  * Method afterPhase notifies the listener after the execution of a specific phase of the ADF Page Lifecycle.
  * @author TapasB
  * @param phaseEvent
  * @see oracle.adf.controller.v2.lifecycle.PagePhaseListener#afterPhase(oracle.adf.controller.v2.lifecycle.PagePhaseEvent)
  */
 @Override
 public void afterPhase(PagePhaseEvent phaseEvent) {
  int phaseId = phaseEvent.getPhaseId();
  String phaseName = Lifecycle.getPhaseName(phaseId);
  PhaseProcessor.getInstance().process(getRequestId(), getURL(), phaseId, phaseName, PhaseProcessor.PhaseType.END);
 }

 /**
  * Method getRequestId generates and returns an unique ID value for each Request
  * @author TapasB
  * @return requestId
  */
 private Integer getRequestId() {
  @SuppressWarnings("unchecked")
  Map<String, Object> requestScope = ADFContext.getCurrent().getRequestScope();
  Integer requestId = (Integer) requestScope.get("requestId");

  if (requestId == null) {
   requestId = PhaseProcessor.getInstance().getNextRequestId();
   requestScope.put("requestId", requestId);
  }

  return requestId;
 }

 /**
  * Method getURL returns the URL in which the application is requested
  * @author TapasB
  * @return a String URL
  */
 private String getURL() {
  Enumeration<String> parameterNames = null;
  String parameterName = null;
  StringBuilder urlBuilder = new StringBuilder();
  Object request = FacesContext.getCurrentInstance().getExternalContext().getRequest();

  try {
   if (request instanceof HttpServletRequest) {
    HttpServletRequest servletRequest = (HttpServletRequest) request;
    urlBuilder.append(servletRequest.getRequestURL().toString());
    parameterNames = servletRequest.getParameterNames();

    if (parameterNames.hasMoreElements()) {
     if (!urlBuilder.toString().contains("?")) {
      urlBuilder.append("?");
     } else {
      urlBuilder.append("&");
     }
    }

    while (parameterNames.hasMoreElements()) {
     parameterName = parameterNames.nextElement();

     urlBuilder.append(parameterName);
     urlBuilder.append("=");
     urlBuilder.append(URLEncoder.encode(servletRequest.getParameter(parameterName), "UTF-8"));

     if (parameterNames.hasMoreElements()) {
      urlBuilder.append("&");
     }
    }
   }
  } catch (Exception ex) {
  }

  return urlBuilder.toString();
 }
}
The class PhaseProcessor is Session Singleton.  One instance per session so it is kept in the session scope. Here it is:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import oracle.adf.share.ADFContext;

import com.edifixio.osrd.generic.log.Log;

/**
 * Class PhaseProcessor processes the Phase execution time
 * @author TapasB
 */
public class PhaseProcessor implements Serializable {

 private static final long serialVersionUID = 6658181867505616109L;

 private List<Phase> phases = new ArrayList<Phase>();
 private AtomicInteger nextRequestId = new AtomicInteger(1);

 /**
  * Constructor PhaseProcessor is private
  * @author TapasB
  */
 private PhaseProcessor() {

 }

 /**
  * Class PhaseType
  * @author TapasB
  */
 public static enum PhaseType {
  BEGIN,
  END;
 }

 /**
  * Method getInstance returns a Session Instance of this class 
  * @author TapasB
  * @return an PhaseProcessor instance
  */
 public static PhaseProcessor getInstance() {
  @SuppressWarnings("unchecked")
  Map<String, Object> sessionScope = ADFContext.getCurrent().getSessionScope();
  PhaseProcessor phaseProcessor = (PhaseProcessor) sessionScope.get("phases");

  if (phaseProcessor == null) {
   phaseProcessor = new PhaseProcessor();
   sessionScope.put("phases", phaseProcessor);
  }

  return phaseProcessor;
 }

 /**
  * Method process processes the {@link Phase} 
  * @author TapasB
  * @param requestId - the unique ID for each request
  * @param url - the url in which the application is requested
  * @param phaseId - ADF's Phase ID
  * @param phaseName - ADF's Phase Name
  * @param phaseType - BEGIN or END
  */
 public void process(int requestId, String url, int phaseId, String phaseName, PhaseType phaseType) {
  Phase phase;

  switch (phaseType) {
   case BEGIN:
    phase = new Phase();

    phase.setRequestId(requestId);
    phase.setUrl(url);
    phase.setPhaseId(phaseId);
    phase.setPhaseName(phaseName);
    phase.setStartTime(new Date());

    phases.add(phase);

    Log.info(this, "The Phase: " + phase.getPhaseName(phaseId) + " begins. Requested URL: " + phase.getUrl());
    break;

   case END:
    ListIterator<Phase> phaseIterator = phases.listIterator(phases.size());

    while (phaseIterator.hasPrevious()) {
     phase = phaseIterator.previous();

     if (phase.getRequestId() == requestId && phase.getPhaseId() == phaseId && phase.getPhaseName().equals(phaseName)) {
      phase.setEndTime(new Date());
      Log.info(this, "The Phase: " + phase.getPhaseName(phaseId) + " ends with execution time: '" + (phase.getEndTime().getTime() - phase.getStartTime().getTime()) + "' millisecondes. Requested URL: " + phase.getUrl());
      phaseIterator.remove();
      break;
     }

    }

    break;
  }
 }

 /**
  * Method getNextRequestId returns and increment the unique ID 
  * @author TapasB
  * @return the ID
  */
 public Integer getNextRequestId() {
  return nextRequestId.getAndIncrement();
 }
}
In the method process it switches the control between two cases. This switching is based on the enum value of the type PhaseType. The idea is, when the phase begins, it creates a new instance of Phase, add it into the List<Phase> phases and log it; and when the phase ends it traverse backward the list, matches the phase with the given requestId, phaseId and phaseName; and when the match is found, it set the endTime to that matched instance of Phase, log it and then remove that instance from the list.
Note that the nextRequestId is an AtomicInteger so the value get updated atomically.

Lastly the model class Phase:
import java.io.Serializable;
import java.util.Date;

import oracle.adf.controller.faces.lifecycle.JSFLifecycle;

/**
 * Class Phase represent a phase
 * @author TapasB
 */
public class Phase implements Serializable {

 private static final long serialVersionUID = -461595462579265128L;

 private int requestId;
 private String url;
 private Date startTime;
 private Date endTime;
 private int phaseId;
 private String phaseName;

 /**
  * Constructor Phase is default
  * @author TapasB
  */
 public Phase() {

 }

 /**
  * Method getRequestId returns requestId
  * @author TapasB
  * @return requestId
  */
 public int getRequestId() {
  return requestId;
 }

 /**
  * Method setRequestId sets the requestId
  * @author TapasB
  * @param requestId the requestId to set
  */
 public void setRequestId(int requestId) {
  this.requestId = requestId;
 }

 /**
  * Method getUrl returns url
  * @author TapasB
  * @return url
  */
 public String getUrl() {
  return url;
 }

 /**
  * Method setUrl sets the url
  * @author TapasB
  * @param url the url to set
  */
 public void setUrl(String url) {
  this.url = url;
 }

 /**
  * Method getStartTime returns startTime
  * @author TapasB
  * @return startTime
  */
 public Date getStartTime() {
  return startTime;
 }

 /**
  * Method setStartTime sets the startTime
  * @author TapasB
  * @param startTime the startTime to set
  */
 public void setStartTime(Date startTime) {
  this.startTime = startTime;
 }

 /**
  * Method getEndTime returns endTime
  * @author TapasB
  * @return endTime
  */
 public Date getEndTime() {
  return endTime;
 }

 /**
  * Method setEndTime sets the endTime
  * @author TapasB
  * @param endTime the endTime to set
  */
 public void setEndTime(Date endTime) {
  this.endTime = endTime;
 }

 /**
  * Method getPhaseId returns phaseId
  * @author TapasB
  * @return phaseId
  */
 public int getPhaseId() {
  return phaseId;
 }

 /**
  * Method setPhaseId sets the phaseId
  * @author TapasB
  * @param phaseId the phaseId to set
  */
 public void setPhaseId(int phaseId) {
  this.phaseId = phaseId;
 }

 /**
  * Method getPhaseName returns phaseName
  * @author TapasB
  * @return phaseName
  */
 public String getPhaseName() {
  return phaseName;
 }

 /**
  * Method setPhaseName sets the phaseName
  * @author TapasB
  * @param phaseName the phaseName to set
  */
 public void setPhaseName(String phaseName) {
  this.phaseName = phaseName;
 }

 /**
  * Method getPhaseName returns the name of the Phase
  * @author TapasB
  * @param phaseId
  * @return the phase name
  */
 public String getPhaseName(int phaseId) {
  if (phaseId == JSFLifecycle.INIT_CONTEXT_ID) {
   return "INIT_CONTEXT";
  } else if (phaseId == JSFLifecycle.PREPARE_MODEL_ID) {
   return "PREPARE_MODEL";
  } else if (phaseId == JSFLifecycle.APPLY_INPUT_VALUES_ID) {
   return "APPLY_INPUT_VALUES";
  } else if (phaseId == JSFLifecycle.VALIDATE_INPUT_VALUES_ID) {
   return "VALIDATE_INPUT_VALUES";
  } else if (phaseId == JSFLifecycle.PROCESS_UPDATE_MODEL_ID) {
   return "PROCESS_UPDATE_MODEL";
  } else if (phaseId == JSFLifecycle.VALIDATE_MODEL_UPDATES_ID) {
   return "VALIDATE_MODEL_UPDATES";
  } else if (phaseId == JSFLifecycle.PROCESS_COMPONENT_EVENTS_ID) {
   return "PROCESS_COMPONENT_EVENTS";
  } else if (phaseId == JSFLifecycle.METADATA_COMMIT_ID) {
   return "METADATA_COMMIT";
  } else if (phaseId == JSFLifecycle.PREPARE_RENDER_ID) {
   return "PREPARE_RENDER";
  } else if (phaseId == JSFLifecycle.JSF_RESTORE_VIEW_ID) {
   return "RESTORE_VIEW";
  } else if (phaseId == JSFLifecycle.JSF_APPLY_REQUEST_VALUES_ID) {
   return "JSF_APPLY_REQUEST_VALUES";
  } else if (phaseId == JSFLifecycle.JSF_PROCESS_VALIDATIONS_ID) {
   return "JSF_PROCESS_VALIDATIONS";
  } else if (phaseId == JSFLifecycle.JSF_UPDATE_MODEL_VALUES_ID) {
   return "JSF_UPDATE_MODEL_VALUES";
  } else if (phaseId == JSFLifecycle.JSF_INVOKE_APPLICATION_ID) {
   return "JSF_INVOKE_APPLICATION";
  } else {
   return "JSF_RENDER_RESPONSE";
  }
 }
}
It is a simple POJO and pretty much self explanatory. Though I would like to explain the method public String getPhaseName(int phaseId). As you can see this method uses a class oracle.adf.controller.faces.lifecycle.JSFLifecycle; it is kind of constant class used by ADF Controllers define the phase ids for the set of phases of the ADF Page Lifecycle that match the JSF lifecycle.

I would greatly appreciate your comments and share.

References:
  1. Ideas on page load time measurements
  2. Understanding the Fusion Page Lifecycle
  3. How to configure an ADF Phase Listener and where to put the file

Monday, December 30, 2013

Detect AJAX Request or PPR Request in ADF Faces

I have a need to detect if the request generated is an AJAX request or Full request. In JSF 2.0 this is easy and you can find many blog posts and forum discussions which have dealt with it. But as I am using ADF 11.1.1.6.0 which uses JSF 1.2 so none of those methods of detecting an AJAX request wouldn't work for me.

So I tried to find a way to detect if the request generated is an AJAX or not and what I found I am sharing with you. You can use any one of the following methods from your Utility class:

public static boolean isPprRequest(FacesContext context) {
 return isPprRequest(context.getExternalContext());
}

public static boolean isPprRequest(ExternalContext ec) {
 return (("true".equals(ec.getRequestHeaderMap().get("Adf-Rich-Message"))) || ("true".equals(ec.getRequestParameterMap().get("Adf-Rich-Message"))));
}

public static boolean isPprRequest(HttpServletRequest req) {
 return (("true".equals(req.getHeader("Adf-Rich-Message"))) || ("true".equals(req.getParameter("Adf-Rich-Message"))));
}

Note this is applicable for ADF 11.1.1.6.0. I haven't tested with other ADF versions.

Happy coding :-)

Saturday, December 28, 2013

WildFly: EJB invocations from a remote client

Currently I am experimenting with Java EE7 and I have chosen WildFly as my application server. So far everything is working fine, the WebService, EJB 3.2 etc until today when I tried to access my EJB from a client application - jUnit Test.
To solve the issue initially I followed the instruction given in WildFly documentation EJB invocations from a remote client using JNDI, but it is not what I needed. After spending almost half a day at last I achieved what I wanted.

Prerequisite:

  • You need to have an Application User. Follow the instruction given in Add User Utility.
  • I am running my server with the parameter -b 0.0.0.0 --server-config standalone-full.xml
  • jboss-client.jar in your classpath, which can be found inside the /bin/client directory of the server.
Following is the piece of code which you need to access the EJB:

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.jboss.ejb.client.EJBClient;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.PropertiesBasedEJBClientConfiguration;
import org.jboss.ejb.client.StatelessEJBLocator;
import org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector;

/**
 * Class EJBLocator is the class to connect with EJB
 * 
 * @author Tapas Bose
 * @since 1.0
 */
public class EJBLocator {

 /**
  * Method locateEJB locates an EJB for the given jndi
  * 
  * @author Tapas Bose
  * @since 1.0
  * @param jndi
  *            - the jndi to lookup
  * @return an instance of EJB
  * @throws NamingException
  */
 @SuppressWarnings("unchecked")
 public static <T> T locateEJB(String jndi) throws NamingException {
  Properties clientProperties = new Properties();
  clientProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
  clientProperties.put("remote.connections", "default");
  clientProperties.put("remote.connection.default.port", myPort);
  clientProperties.put("remote.connection.default.host", myHost);
  clientProperties.put("remote.connection.default.username", myUser);
  clientProperties.put("remote.connection.default.password", myPassword);
  clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");

  EJBClientContext.setSelector(new ConfigBasedEJBClientContextSelector(new PropertiesBasedEJBClientConfiguration(clientProperties)));

  Properties properties = new Properties();
  properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
  Context context = new InitialContext(properties);
  return (T) context.lookup(jndi);
 }

 /**
  * Method locateEJBStateless locates an Stateless EJB for the given parameters
  * 
  * @author Tapas Bose
  * @since 1.0
  * @param viewType
  *            - the view type
  * @param appName
  *            - the application name
  * @param moduleName
  *            - the module name
  * @param beanName
  *            - the bean name
  * @param distinctName
  *            - the distinct name
  * @return an instance of EJB
  */
 public static <T> T locateEJBStateless(Class<T> viewType, String appName, String moduleName, String beanName, String distinctName) {
  Properties properties = new Properties();

  properties.put("endpoint.name", "client-endpoint");
  properties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
  properties.put("remote.connections", "default");
  properties.put("remote.connection.default.port", myPort);
  properties.put("remote.connection.default.host", myHost);
  properties.put("remote.connection.default.username", myUser);
  properties.put("remote.connection.default.password", myPassword);
  properties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");

  EJBClientContext.setSelector(new ConfigBasedEJBClientContextSelector(new PropertiesBasedEJBClientConfiguration(properties)));
  StatelessEJBLocator<T> locator = new StatelessEJBLocator<T>(viewType, appName, moduleName, beanName, distinctName);
  T ejb = EJBClient.createProxy(locator);
  return ejb;
 }
}

Use this class as:
YourService service = EJBLocator.locateEJB(jndi);
//where the jndi is of the form ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>
Or by:
YourServic service = EJBLocator.locateEJBStateless(YourServic.class, "appName", "moduleName", "YourServicImpl", "distinctName");
Hope it will help.

Friday, May 17, 2013

Java SE 8: Lambda

Introduction
Lambda expressions are a new and important feature included in Java Platform Standard Edition 8. They provide a clear and concise way to represent one method interface using an expression. Lambda expressions also improve the Collection libraries making it easier to iterate through, filter, and extract data from a Collection. In addition, new concurrency features improve performance in multicore environments.

JSR 335 - Project Lambda
Lambda Expressions are part of Java Specification Request (JSR 335) which is lead by Brian Goetz. JSR 335 is a coordinated co-evolution of the Java platform. It is going to change the language, libraries and VM.
  • Language - lambda expressions (closures), interface evolution, better type inference.
  • Libraries - Bulk parallel operations on collections.
  • VM - Support for default methods and lambda conversion.
This is a major step forward for the Java programming model:
  • More parallel-friendly.
  • Enable delivery of more powerful libraries.
  • Enable developers to write more concise, less error-prone code.
History - Closures for Java
When Java was first introduced in 1995 not many languages had closures, but they are present in pretty much every major language today, even C++.
In 1997 Java 1.1 added inner classes - a weak form of closures, which has many limitations as it is too bulky and the rule of name resolutions are too complex.
In 2006-2008, a vigorous community debate started about closures and multiple proposal arose including BGGA and CICE. Each had a different principle:
  • BGGA(Bracha Gafter Gosling Ahé) - Creating control abstraction in libraries and full closure support by Gilad Bracha, Neal Gafter, James Gosling and Peter von der Ahé.
  • CICE (Concise Instance Creation Expressions) - Simplified inner classes to reduce syntactic overhead by Bob Lee, Doug Lea and Josh Bloch.
Evaluation started from Java SE 5, 200, progress made by Project Coin (Small Language Changes) in Java SE 7. So for Java, it has been a long and winding road to get support for closures, until Project Lambda finally started in Dec 2009. In November 2010 the JSR 335 filled.
Currently the EDR (Early Draft Review) completed, prototype (source and binaries) available in OpenJDK and it is going to be a part of Java SE 8.

Why Lambda?
Java is the lone holdout among mainstream OO languages at this point to not have closures, and Lambda is no longer a radical idea, it was 10 years ago, times change and it is not anymore.
It provides libraries a path to multicore. Parallel-friendly APIs needs to have internal iteration and internal iteration needs a concise code-as-data mechanism.
It empower library developers by providing more powerful and flexible libraries and by providing higher degree of cooperation between libraries and client code which makes everybody's life better.

What is Lambda Expression?
A Lambda Expression is simply an anonymous method. Like a method it has an argument list, parameters, return type and has a set of thrown exception and a body. It has all the things that a method has except a name and it is not a member of a class, rather it is just an free floating expression.
Argument List Arrow Token Body
(int x, int y) -> x + y

Example:
(Object obj) -> obj.toString()
In this example it takes an Object as an argument, and in its body it calls Object.toString() and returns that. By this it removes a lots of syntactical overhead, there is no return statement, no braces etcetera.
It also can refer to values from the enclosing lexical scope:
(Shape shape) -> shape.getColor().equals(color)
Compiler can also infer parameter types from context, so in that case following statement is completely valid:
shape -> shape.getColor().equals(color)
There is also a feature added to the Lambda Expression is called Method References, which behave just like a Lambda Expression. If you already have a method and if you want to use that method behaviour as Lambda Expression, you can directly use that Method Reference as:
Object::toString
This is identical to the first example.


More to come...

Friday, May 10, 2013

Java EE 7: Specification, Services, Key features

Java EE Standard Services
The Java EE standard services include the following. Some of these standard services are actually provided by Java SE.
  1. HTTP
  2. HTTPS
  3. Java Transaction API (JTA)
  4. RMI-IIOP
  5. Java IDL
  6. JDBC API
  7. Java Persistence API (JPA)
  8. Java Message Service (JMS)
  9. Java Naming and Directory Interface (JNDI)
  10. JavaMail
  11. JavaBeans Activation Framework (JAF)
  12. XML Processing
  13. Java EE Connector Architecture
  14. Security Services
  15. Web Services
  16. Concurrency Utilities
  17. Batch
  18. Management
  19. Deployment
Interoperability 
Many of the APIs described above provide interoperability with components that are not a part of the Java EE platform, such as external web or CORBA services.
Following figure illustrates the interoperability facilities of the Java EE platform. (The directions of the arrows indicate the client/server relationships of the components.)
Java EE Interoperability
Key features:
Summary of the key features of different specifications in the Java EE 7 platform:
  1. Java EE 7 (JSR 342):
    • The main theme is to easily run applications on private or public clouds
    • The platform will define application metadata descriptor to describe PaaS execution environment such as multi-tenancy, resources sharing, quality-of-service, and dependencies between applications
    • Embrace latest standards like HTML5, WebSocket, JSON and have a standards-based API for each one of them
    • Remove inconsistencies between Managed Beans, EJB, Servlets, JSF, CDI, and JAX-RS
    • Possible inclusion of JAX-RS 2.0 in the Web Profile, revised JMS 2.0 API
    • Technology Refresh for several existing technologies (more on this below) and possible inclusion of Concurrency Utilities for Java EE (JSR 236) and JCache (JSR 107)
    • Status
  2. JPA 2.1 (JSR 338):
    • Support for multi-tenancy
    • Support for stored procedures and vendor function
    • Update and Delete Critieria queries
    • Support for schema generation
    • Persistence Context synchronization
    • CDI injection into listeners
    • Status
  3. JAX-RS 2.0 (JSR 339):
    • Client API - low level using builder pattern and possibly a higher level on top of that
    • Hypermedia - easily create and process links associated with resources
    • Form or Query parameter validation using Bean Validation
    • Closer integration with @Inject, etc
    • Server-side asynchronous request processing
    • Server-side content negotiation using "qs"
    • Status
  4. Servlets 3.1 (JSR 340):
    • Optimize the PaaS model for Web applications
    • Multi tenancy for security, session, resources, etc.
    • Asynchronous IO based on NIO2
    • Simplfiied asynchronous Servlets
    • Utilize Java EE concurrency utilities
    • Enable support for WebSockets
    • Status:
  5. Expression Language 3.0 (JSR 341):
    • Separate ELContext into parsing and evaluation contexts
    • Customizable EL coercion rules
    • Reference static methods and members directly in EL expressions
    • Adding operators like equality, string concatenation, and sizeof etc.
    • Integration with CDI such as generating events before/during/after the expressions are evaluated
    • Status
  6. Java Message Server 2.0 (JSR 343):
    • Ease of development - changes to the JMS programming model to make the application development simpler and easier
    • Remove/Clarify ambiguities in the existing specification
    • Integration with CDI
    • Clarification of the relationship between JMS and other Java EE specs
    • A new mandatory API to allow any JMS provider to be integrated with any Java EE container
    • Multi-tenancy and other cloud-related features from the platform
    • Status
  7. Java Server Faces 2.2 (JSR 344):
    • Ease of Development - making configuration options dynamic, make cc:interface in composite components optional, shorthand URLs for Facelet tag libraries, integration with CDI, OSGi support for JSF artifacts
    • Support implementation of Portlet Bridge 2.0 (JSR 329)
    • Support for HTML5 features like HTML5 Forms, Metadata, Heading and Section content model
    • Flow management, Listener for page navigation events, and new components like FileUpload and BackButton
    • Status
  8. EJB 3.2 (JSR 345):
    • Enhancements to the EJB architecture to enable PaaS, such as multi-tenancy
    • Factorization of container-managed transactions to use outside EJB
    • Further use of annotations
    • Alilgnment and integration with other specifications in the platform
    • Status
  9. CDI 1.1 (JSR 346, more details):
    • Global ordering of interceptors and decorators
    • API for managing built-in contexts
    • Embedded mode to allow startup outside Java EE container
    • Declarative control over which packages/beans are scanned in an archive
    • Injection for static members such as loggers
    • Send Servlet events as CDI event
    • Status
  10. Bean Validation 1.1 (JSR 349):
    • Integration with other Java EE specs
      • JAX-RS: Validate parameters and return values on HTTP calls
      • JAXB: Convert constraints into XML schema descriptor
    • Method level validation
    • Apply constraints on group collection
    • Extend the model to support AND and OR style composition
    • Status
  11. JCache (JSR 107)
    • API and semantics for temporary, in-memory caching of Java objects, including object creation, shared access, spooling, invalidation, and consistency across JVMs
    • Package: javax.cache
    • Status
      • Approved by the JCP
      • Spec lead: Yannis Cosmadopoulos, Cameron Purdy (Oracle) and Gregory Luck (Software AG)
      • Project page: jsr107spec
      • Mailing List Archive: jsr107@googlegroups.com
  12. State Management (JSR 350):
    • API that can be used by applications and Java EE containers to offload the responsibility of statement management into third party providers with different QoS characteristics
    • Java SE-based callers can access the state data by querying the state providers
    • Providers with different QoS can be added and API callers can query to meet their criteria
    • Package: javax.state and javax.state.provider
    • Status
  13. Batch Application for the Java Platform (JSR 352):
    • Programming model for batch applications and a runtime for scheduling and executing jobs
    • Defines Batch Job, Batch Job Step, Batch Application, Batch Executor, and Batch Job Manager for the standard programming model
    • Package: javax.batch
    • Status
  14. Concurrency Utilities for Java EE (JSR 236):
    • Provides a clean, simple, independent API by building on JSR 166, making it appropriate for use within any Java EE contianer.
    • Package: javax.util.concurrent
    • Status
      • Approved by the JCP
      • Spec lead: Anthony Lai, Naresh Revanuru (Oracle)
      • Project page:
      • Mailing List Archive:
  15. Java API for JSON Processing (JSR 353):
Reference:

Sunday, March 17, 2013

Upgrade JSF version in JBoss AS 7.1.1.Final

The JBoss AS 7.1.1 Final ships with Mojarra implementation of JSF versions 1.2 and 2.1.7. However sometimes developers need to change or upgrade the JSF version.
Prior to this JBoss version web applications could load their own JSF by placing the jar in WEB-INF/lib and adding the following context-param in web.xml.

   org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL
   true

But this doesn't work anymore for 7.1.1. Following is how you can do it.
At the time of this writing I have used version 2.1.19.
  • First you need to download the jsf-impl and jsf-api jars that you want. Here are the MVN Repository for jsf-impl and jsf-api.
  • Place the jsf-impl jar in the path modules/com/sun/jsf-impl/main.
  • Open the module.xml of that directory and change the value of path of resource-root as

  • Now place the jsf-api jar in the path modules/javax/faces/api/main.
  • Open the module.xml of that directory and change the value of path of resource-root as

  • Because jsf-api depends on jsf-impl you need to add the dependency in the module of jsf-api as

Now you are good to run you server. While running the server if you see the following line:
14:14:08,379 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-4) Initializing Mojarra 2.1.19 ( 20130213-1512 https://svn.java.net/svn/mojarra~svn/tags/2.1.19@11614) for context '/your-app'
Then everything is fine.
Good luck.