Monday, 27 May 2013

Duplication - A bit between your teeth

I presume that pretty much everybody who has been in contact with the java programming language either in studies or professionally even for a little bit, knows that duplication is a code smell.
We all know that some consequences of duplication are: less maintainability, less readability, the code is more likely to contain bugs, performance issues... and many more.

I think there should not be need to explain what duplication is, but just in case let's write only one line to define it and also make sure that we understand it:
"Duplication is the existence of multiple copies of a single concept"


Are there any doubts until this point?...
Please go back and read once more the definition if you still are not sure about it.

So, how do we fix duplication?


But if it is so easy to understand what duplication is and also how simple it is to refactor, why do we find it all over the place, no matter what software we are looking at.

Well... there are many reasons why there is duplication all over the place:
  • sometimes we just rush to get things done and we don't care about it. 
  • maybe we think that refactoring is boring or is not profitable, so we have no patience to do it.
  • other times we think there are always more important things to do and duplication is not really affecting us.
  •  also sometimes when we want to do something about it, we just can't see it even if it is in front of us.             

 So, what do you think?... Any of this may be the reason why you are not fixing duplication?
If your reason is any of the first 3, I am sorry, but this blogpost will not be of any use to you and the best you can do is close this browser tab or surf somewhere else.

But if it is the 4th, the reason why you are not fixing the duplication, then you might find the following lines very interesting....

This is the secret why many programmers sometimes find it so difficult to deal with duplication...

There are different kinds of duplication, this are some of the most important:
  • Literal
  • Structural
  • Semantic

Literal duplication
This is a very easy to spot kind of duplication. It is basically literal values that are repeated in our code.

e.g
 public class RepeaterSpecification {  
      @Test  
      public void repeatsInput() {  
               assertThat("value",is(repeat("value")));  
      }  
      @Test  
      public void repeatsEmptyInput() {  
              assertThat("",is(repeat("")));  
      }  
     //...  
 }  

The most common way to fix this type of duplication is to create a local variable. Let's have a look at a possible refactor:

 public class RepeaterSpecification {  
      @Test  
      public void repeatsInput() {  
         String input = "value";  
         assertThat(input,is(repeat(input)));  
      }  
      @Test  
      public void repeatsEmptyInput() {  
         String input = "";  
         assertThat(input,is(repeat(input)));  
      }  
     //...  
 }  
It looks like we no longer have literal duplication. But unfortunately as you probably noticed, sometimes when fixing one type of duplication we generate another type of duplication. Keep reading to find out more...

Structural duplication
We can recognize this situation when the logic is duplicated but it operates on different data.
See this situation in the following example:

e.g
 public class RepeaterSpecification {  
      @Test  
      public void repeatsInput() {  
         String input = "value";  
         assertThat(input,is(repeat(input)));  
      }  
      @Test  
      public void repeatsEmptyInput() {  
         String input = "";  
         assertThat(input,is(repeat(input)));  
      }  
     //...  
 }  


As you can see I toke this code from the previous example. The assertThat() operation is identical, the only difference is the data that it uses. Let's have a little look at a way how to fix structural duplication:


public class RepeaterSpecification {  
      
      @Test  
      public void repeatsInput() {  
         assertThatInputIsRepeated("value");  
      }  

      @Test  
      public void repeatsEmptyInput() {  
         assertThatInputIsRepeated("");  
      }
 
      private void assertThatInputIsRepeated(String input) {  
            assertThat(input,is(repeat(input)));
      }
     //...  
 }


Now that we extracted the method that does the assertion we no longer have duplication.

Semantic duplication
This is  the situation where different code implementations represent the same functionality or concept.
The definition of semantic duplication teaches us that duplication can be invisible from the point of view of the code("The definition from the start of this post makes a way more sense now, uh? :)" ). This kind of duplication is probably one of the most difficult to spot.

e.g
public class TeamValidator {       
  
      public boolean isThereALeader(List<Members> team) {  
           Iterator<Member> iterator = team.getIterator();
           while(iterator.hasNext()) {
              Member member = iterator.next();
              String role = member.getRole();
              if(role.equals("Leader"))
                return true;
           }  
           return false;
      }  

      public boolean areThereAtLeast2NewJoiners(List<Members> team) {  
            for(Member member:team) {
                DateTime aMonthAgo = DateTime.now().minusMonths(1);
                if(member.startingDate().isAfter(aMonthAgo))
                return true; 
            }
            return false;   
      }
     //...  
 }


At first glance, when we look at the two methods in the code above we cannot really see much duplication. No matter how much we look at it, we will not see it. Semantic duplication is invisible from the implementation point of view. To spot it what we need to do is spot the behavioral anti pattern that is hidden in the code. If we think about it, basically the repetition going on is that both methods iterate one list of the same type and then apply certain criteria(Completely different implementations but one same concept).
Semantic duplication is more difficult to fix than other types of duplication and often requires a bigger refactoring effort. Here is one possible solution that helps us get rid of it using Java generics:

 public class TeamValidator {      
    public boolean isThereALeader(List<Member> team) {   
         return new LeaderVerifier<Member>().evaluate(team);  
    }   
    public boolean areThereAtLeast2NewJoiners(List<Member> team) {   
         return new NewJoinersVerifier<Member>().evaluate(team);  
    }  
 }  


 public abstract class LoopEvaluator<T> {

 public boolean evaluate(List<T> list) {
  for (T element : list) {
   if(evaluateElement(element)) {
    return true;
   }
  }
  return false;
 }
 
 public abstract boolean evaluateElement(T element);
 
}


public class LeaderVerifier<T extends Member> extends LoopEvaluator<T> {

 @Override
 public boolean evaluateElement(T element) {
  return element.getRole().equals("leader");
 } 
}



public class NewJoinersVerifier<T extends Member> extends LoopEvaluator<T> {

 private int newJoiners;
 
 @Override
 public boolean evaluate(List<T> list) { 
  this.newJoiners = 0;
  return super.evaluate(list);
 }
 
 @Override
 public boolean evaluateElement(T element) {
  DateTime aMonthAgo = DateTime.now().minusMonths(1);
  if(element.startingDate().isAfter(aMonthAgo)) 
   this.newJoiners++;
  return newJoiners == 2;
 }
}


Duplication is not a little topic at all. The 3 types of duplication I mentioned in this post are from my point of view some of the most common but there are many more. Here a link where I found where at the bottom you can find a mention to other kinds of duplication: http://blogs.agilefaqs.com/tag/code-smells/


                                                                     
 I am the spaghetti monster, You cant get rid of me!!!! Hahahaha......

Just to conclude this post, I want to say that I have the impression that duplication many times is an  underestimated code smell that undetected grows and grows and ends up transforming systems into spaghetti monsters.

Lets get rid of it while it is just a bit between your teeth! ;)







Thursday, 23 May 2013

How to verify that void methods were called using Mockito

Mockito is one of the most popular mocking frameworks for java.
This post Is just little miscellaneous where I will show you how to mock and verify a void method call.

Sometimes when we test a call to a void method all we want to do is just make sure that at some point in its life cycle, another method will be called with certain parameters.
Let's see the following example:
 public class SomeClass {  
      private OtherClass otherClass;  
     
      public SomeClass(OtherClass otherClass) {  
           this.otherClass = otherClass;  
      }  
      protected void firstMethod(int value) {  
           if(value > 0) {  
                secondMethod("Yes!");  
           }  
           else {  
                secondMethod("No!");  
           }  
      }  
      private void secondMethod(String value) {  
           otherClass.someMethod(value);  
      }       
 }  

In the above piece of legacy code the most important part is a method called "someMethod()". We must make sure that it is called in a proper way, but unfortunately it belongs to a dependency to which we have no access and also to make it more complicated it is inside a private method.

Mockito framework could help us mock and verify that method call.
Here is how we can do it:
 package demo;
 import static org.mockito.Mockito.verify;  
 import org.junit.Before;  
 import org.junit.Test;  
 import org.mockito.Mock;  
 import org.mockito.MockitoAnnotations;  
 import code.OtherClass;  
 import code.SomeClass;  
 public class TestClass {  
      @Mock  
      private OtherClass otherClass;  
      //Class under test  
      private SomeClass someClass;  
      @Before  
      public void prepareDependencies() {  
           MockitoAnnotations.initMocks(this);       
           someClass = new SomeClass(otherClass);  
      }  
      @Test  
      public void is_the_value_greater_than_zero() {  
           someClass.firstMethod(8);  
           verify(otherClass).someMethod("Yes!");  
      }  
      @Test  
      public void is_the_value_smaller_than_zero() {  
           someClass.firstMethod(-1);  
           verify(otherClass).someMethod("No!");  
      }  
 }  

The most important things to highlight in this test class are:
  • The class under test is never mocked.
  • The dependencies of the class under test need to be mocked.
  • By calling a method on a mock object we will mock that method call
  • By using the verify() method we will test that at some point the method from the mock was called  with the exact same parameters.
  • The test class can access the protected method because the package name is the same.(But of course in your project structure test will be under src/test/java and production code under src/main/java)

Monday, 6 May 2013

Using transaction attributes in EJB 3.1 - Container Managed Transactions

When somebody refers to container managed transactions, what we understand is that the EJB container is responsible of managing transactionality for the methods inside EJB's deployed in the EJB container.

The theory behind transaction management in EJB 3.1 is not brief and probably my post would become to long if I tried to explain other important concepts. In this post I want to just focus on an important concept known as the transaction attribute.

To simplify this concept, I will refer to it, as a configuration given to a method/function within an EJB, that will tell the EJB container what to do with the incoming transaction when that method is called.

The thing that will determine what will occur with the transaction when a certain transaction attribute is used will be the transactional context from where the method was called. In other words, if the enterprise method annotated with a certain attribute was called from a non-transactional(e.g a web page) will manage the transaction differently than if it was called from a transactional context(e.g another EJB). And this is the reason why sometimes we have to choose wisely our transaction attributes.

To use transaction attributes in our EJB's its very simple, all you need to do is use an annotation:
 @Stateful  
 public class SomeBean implements SomeInterface {  
   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)  
   public void someMethod(){  
    //...  
   }  
   //...  
 }  

Now that we know how to annotate the methods, lets see what will occur when each of the transaction attributes is used:

REQUIRES_NEW
When the calling method is not in a transaction: Starts a new transaction.
When the calling method is in a transaction:  Suspends the existing transaction and creates a new one.

REQUIRED

When the calling method is not in a transaction: Starts a new transaction.
When the calling method is in a transaction:  Executes in existing transaction.

NEVER

When the calling method is not in a transaction: It will execute with no transaction.
When the calling method is in a transaction:  It will throw an exception.

NOT_SUPPORTED

When the calling method is not in a transaction: It will execute with no transaction
When the calling method is in a transaction: It will execute with no transaction(No exception will be thrown)  

SUPPORTS

When the calling method is not in a transaction: It will execute with no transaction.
When the calling method is in a transaction:  Executes in existing transaction.

MANDATORY

When the calling method is not in a transaction:  It will throw an exception.
When the calling method is in a transaction: Executes in existing transaction(Execution continues because the caller was already in a transaction).




Saturday, 13 April 2013

How to unzip a .zip file with Zip4j

3 days ago I discovered a  cool easy to use java tool for working with zip files.
It is called Zip4j.

Have a look at this super simple example that will allow you to unzip a file into a given path in your computer:

 String source = "folder/source.zip";  
 String destination = "folder/source/";    
   try {  
     ZipFile zipFile = new ZipFile(source);  
     zipFile.extractAll(destination);  
   } catch (ZipException e) {  
     e.printStackTrace();  
   }  

Use this if the unzip file has a password:

 String source = "folder/source.zip";  
 String destination = "folder/source/";  
 String password = "password";  
 try {  
   ZipFile zipFile = new ZipFile(source);  
   if (zipFile.isEncrypted()) {  
     zipFile.setPassword(password);  
   }  
   zipFile.extractAll(destination);  
 } catch (ZipException e) {  
   e.printStackTrace();  
 }  

That was easy and cool.
Are you now thinking the same as I am thinking?...
Let's go brute force zip passwords!!! :P

Hahaha.... I am just joking don't do that, this is not a hacking blog( yet! :p )  I hope you enjoyed this post. Use Zip4j with care.

Sunday, 7 April 2013

How do I add a project as a dependency of another project and why would I do so? (Maven)

When working in a Java EE distributed system many times we have to manage the dependencies of each of our nodes. Our system will be full of other projects, representing different aspects of the system.


In this post I want to explain how to include a project as a dependency of another project by using an example scenario that is very common in real life: "Sharing the domain model between nodes".

As we know the domain model is the representation of the data that our system works with. To avoid inconsistencies it is a good practice, that each of the projects in our system that are supposed to interact with the domain model do so in a safe way. By interacting safely, we mean look at the domain model as a provided service that the projects use, but without the possibility of corrupting it.

One of the most common ways of achieving our goal would be, to create the domain model, as a separate project, and reference it there where it is needed. Doing this none of the distributed projects of our system will have to be responsible for the domain model, their only responsibility will be to keep the dependency updated, to make sure that they are using the very latest version.


In the following image we can see an example of what could perfectly be a class, in the domain model of a distributed system(Just a trivial example):



This is the project that contains the model and if we want to make sure that it can be use as a dependency in another project, we need to make sure it is packed in a .jar (note the content of the packaging tag in the next image).



When this program is built using the mvn clean install command, it will generate a .jar file that will be stored in the local maven repository(~/.m2). If the build process is successful we should see a message similar to this in our console(Note the message that says that the .jar was installed in the repo):


 A very important thing to understand about this process, is that future versions of this project will need to be increased and also will not have the SNAPSHOT postfix when deployed as stable version. If this process is always done manually by the developer, it possible to make mistakes and that is why in real live, many companies use special tools for building and deploying such as Jenkins and Hudson. The set of tasks and tools that allows distributed software built and deployed automatically in a safe way, is known as Continuous Integration.


Now that we have built and deployed(In this example we just deployed it in the local maven repo) our new domain model, we can reference it in another project.
In this example I will use the model in a project that represents a data access layer for a distributed system, to do so, we will need to add the dependency to the correct version of the model inside the pom.xml file:





Once we build our project we will see that the .jar that contains the model is in the class path and we can use it with no problem in this project:



 When a change is done on those projects on which other projects depend, in order to avoid versions miss matches and inconsistencies, it is a good practice to update all the versions in the dependent projects, re-build and re-deploy.

Now that we know how to add the domain model as a dependency we can add it to other projects that are part of our system(e.g a web app).

Just as a little appendix and even if is not directly related to the post, there is an excellent text about why the Data Transfer Object pattern is no longer needed in JEE in the book: Enterprise JEE Patterns. Rethinking best practices(page 273).  There is a very interesting explanation of why DTO's became superfluous when the JPA entities were introduced. 

Friday, 22 March 2013

How do private methods affect our software testability?

 How many times did we hear the question:
“Should we test private methods?”
In this post I want to share with you my thoughts about this question and how I think we should proceed when having this doubt.
Methods with the access modifier private are code as the rest of the application, so this mean that they can potentially hide bugs.  So after a first impression my answer to that question is: “Yes, we should!”.  
Wait, a second… before you get mad at me. I want to rephrase my statement.
I think that question is completely not in place.  Instead of asking “Should we test private methods?”, we should ask: “How do private methods affect our software testability?”
Let’s consider different approaches to deal with private methods and see their pros and cons from the testability point of view:

Scenario 1 – Ok,ok you leave me no choice but reflection
This is what the official Java tutorials say about reflection: 
“Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine. This is a relatively advanced feature and should be used only by developers who have a strong grasp of the fundamentals of the language. With that caveat in mind, reflection is a powerful technique and can enable applications to perform operations which would otherwise be impossible.”
Ok, let’s  give it a try, imagine we have some private method, such as this one:



Hhmmm… So how to do this? Oh my god, do I really have to use reflection? Are you sure?
Let’s investigate a bit before making any decision.
Weeks ago I spent one full afternoon searching the internet looking for testability assurance pattern to test this in java. The only interesting discovery I did was that C# developers have a pattern for this called  “Internals Visible To Attribute”.  Unfortunately (Or maybe fortunately hehe…) that technique is not compatible with java.
There has to be an alternative, why can’t we just change the access modifier and test it normally?...
The common answer you get, when you ask that is:  You will compromise security, you will break encapsulation, you are lazy…
Ok,ok,you leave me no choice but reflection:

 Please don’t do this at your workplace J
Let’s see the Pros and Cons now.

Pros:
- The test is green and I tested the piece of code that I wanted to test
- I did not compromise the security of my software(:P Whatever….)
- I am an expert because the official java tutorials say that only cool dudes like me can use reflection.
Cons:
- A simple rename done by anybody to the method, return type or parameter will break the test and I will have to come back to rewrite the test. This type of test is very difficult to maintain.
- I broke the Security of my software. What am I talking about??? How is that possible if the method still private in the production code?? Hacking the internals of a class is a security.
- See how long that test is. Imagine you have to do this for a longer and more complex method.
More drawbacks(Taken from Java official tutorials website):



Scenario 2 – There is always a way out.
As mentioned in the previous scenario a design pattern that can help us testing private fields does not exist. But there are always ways out. Here I am going to suggest 2 and explain them:

- Protect your method: Just change the access modifier to protected. This will allow you to stub the method call and test using a pattern called Subclass & Override. Basically on your test package, you will be creating a fake that extends the class under test and then override using your expectations. You will then use that fake on your test.
This is a very common breaking dependency technique, since that private method will for sure be called somewhere else within the class and present a dependency inside other method/s(Must be broken in order to increase testability).
I don’t agree with this being a security risk because various reasons, one of them is that probably that method should not be private or, is too long to be tested indirectly, or probably that method should not even be there.
The only disadvantage I see is a decrease in the quality of the design, but I will justify that as the price we need to pay when we build software without using TDD or having testability in mind.

- Extract until you drop: Robert C. Martin in his book “Clean Code”, describes a refactoring methodology called “Extract until you drop”, the idea is refactor the code as much as possible until the point there the methods have not more than 4 lines of code. He says that a line with just a curly braces also count as a line.  If you think about it, your methods would be able to use an “if else” statement of just one line in each of the clauses.
If we want to unit test, we need to have units.  After doing this exhaustively on the method or class under test, we will probably see how that method was probably refactored into a new class, or maybe became so small that it can be tested indirectly via another method with no risk at all, since there are no longer inflection points(Places where logic of the software can potentially take a different path).
The main disadvantages of this approach will probably be that doing it probably would take too long, also on our way and specially if we are dealing with legacy code, we will need to use a lot of breaking dependency techniques and this will present a learning curve that will push us to break some of the design rules we were highly tight too in the past when the system was initially built.  But the benefit will be visible at short, mid and long term.

If you are concern about testability and you believe that testability is the path to quality in modern software, then the right question is How do private methods affect our software testability?

Sunday, 17 March 2013

PrimePush in Jboss AS 7

It toke me a while to make PrimePush work in JBoss AS 7.
In this post I will just paste the codes of a simple hello world like program that uses PrimePush libraries to submit an String to a web socket.

The requirement for this exercise, is that you know to create a new JSF project with maven and deploy it into the JBoss 7 AS application server. All the steps to do that can be found in one of my previous post:
http://javing.blogspot.ie/2013/01/how-to-create-new-jsf-21-project-and.html

Once you have your project ready, lets make the following changes in the configuration files:

pom.xml


1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
3:       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
4:       <modelVersion>4.0.0</modelVersion>  
5:       <groupId>my.test.project</groupId>  
6:       <artifactId>my.test.project</artifactId>  
7:       <version>0.0.1-SNAPSHOT</version>  
8:       <packaging>war</packaging>  
9:       <name>Java EE 6 webapp project</name>  
10:       <properties>  
11:            <jboss.bom.version>1.0.0.Final</jboss.bom.version>  
12:            <version.faces.mojarra>2.1.7</version.faces.mojarra>  
13:            <version.primefaces>3.4.2</version.primefaces>  
14:            <version.atmosphere>1.0.8</version.atmosphere>  
15:       </properties>  
16:       <dependencyManagement>  
17:            <dependencies>  
18:                 <dependency>  
19:                      <groupId>org.jboss.bom</groupId>  
20:                      <artifactId>jboss-javaee-6.0-with-tools</artifactId>  
21:                      <version>${jboss.bom.version}</version>  
22:                      <type>pom</type>  
23:                      <scope>import</scope>  
24:                 </dependency>  
25:                 <dependency>  
26:                      <groupId>junit</groupId>  
27:                      <artifactId>junit</artifactId>  
28:                      <version>4.10</version>  
29:                      <type>jar</type>  
30:                      <scope>test</scope>  
31:                 </dependency>  
32:            </dependencies>  
33:       </dependencyManagement>  
34:       <dependencies>  
35:            <dependency>  
36:                 <groupId>javax.enterprise</groupId>  
37:                 <artifactId>cdi-api</artifactId>  
38:                 <scope>provided</scope>  
39:            </dependency>  
40:            <dependency>  
41:                 <groupId>org.jboss.spec.javax.servlet</groupId>  
42:                 <artifactId>jboss-servlet-api_3.0_spec</artifactId>  
43:                 <scope>provided</scope>  
44:            </dependency>  
45:            <dependency>  
46:                 <groupId>org.jboss.spec.javax.faces</groupId>  
47:                 <artifactId>jboss-jsf-api_2.1_spec</artifactId>  
48:                 <scope>provided</scope>  
49:            </dependency>  
50:            <dependency>  
51:                 <groupId>org.jboss.spec.javax.el</groupId>  
52:                 <artifactId>jboss-el-api_2.2_spec</artifactId>  
53:                 <scope>provided</scope>  
54:            </dependency>  
55:            <dependency>  
56:                 <groupId>com.sun.faces</groupId>  
57:                 <artifactId>jsf-impl</artifactId>  
58:                 <version>${version.faces.mojarra}</version>  
59:                 <scope>provided</scope>  
60:            </dependency>  
61:            <dependency>  
62:                 <groupId>org.primefaces</groupId>  
63:                 <artifactId>primefaces</artifactId>  
64:                 <version>${version.primefaces}</version>  
65:            </dependency>  
66:            <dependency>  
67:                 <groupId>org.atmosphere</groupId>  
68:                 <artifactId>atmosphere-runtime</artifactId>  
69:                 <version>${version.atmosphere}</version>  
70:                 <exclusions>  
71:                      <exclusion>  
72:                           <artifactId>slf4j-api</artifactId>  
73:                           <groupId>org.slf4j</groupId>  
74:                      </exclusion>  
75:                 </exclusions>  
76:            </dependency>  
77:            <dependency>  
78:                 <groupId>junit</groupId>  
79:                 <artifactId>junit</artifactId>  
80:                 <scope>test</scope>  
81:            </dependency>  
82:       </dependencies>  
83:       <build>  
84:            <finalName>pushcomment</finalName>  
85:            <plugins>  
86:                 <plugin>  
87:                      <artifactId>maven-compiler-plugin</artifactId>  
88:                      <version>2.3.1</version>  
89:                      <configuration>  
90:                           <source>1.6</source>  
91:                           <target>1.6</target>  
92:                      </configuration>  
93:                 </plugin>  
94:                 <plugin>  
95:                      <artifactId>maven-war-plugin</artifactId>  
96:                      <version>2.1.1</version>  
97:                      <configuration>  
98:                           <failOnMissingWebXml>false</failOnMissingWebXml>  
99:                      </configuration>  
100:                 </plugin>  
101:            </plugins>  
102:       </build>  
103:       <repositories>  
104:            <repository>  
105:                 <id>prime-repo</id>  
106:                 <name>PrimeFaces Maven Repository</name>  
107:                 <url>http://repository.primefaces.org</url>  
108:                 <layout>default</layout>  
109:            </repository>  
110:       </repositories>  
111:  </project>  

faces-config.xml


1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <!-- This file is not required if you don't need any extra configuration. -->  
3:  <faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"  
4:    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
5:    xsi:schemaLocation="  
6:      http://java.sun.com/xml/ns/javaee  
7:      http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">  
8:  </faces-config>  

web.xml

1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
3:       xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
4:       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
5:       version="3.0">  
6:       <display-name>push-comment</display-name>  
7:       <welcome-file-list>  
8:            <welcome-file>index.html</welcome-file>  
9:       </welcome-file-list>  
10:       <context-param>  
11:            <param-name>javax.faces.PROJECT_STAGE</param-name>  
12:            <param-value>Development</param-value>  
13:       </context-param>  
14:       <context-param>  
15:            <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>  
16:            <param-value>2</param-value>  
17:       </context-param>  
18:       <context-param>  
19:            <param-name>javax.faces.DEFAULT_SUFFIX</param-name>  
20:            <param-value>.xhtml</param-value>  
21:       </context-param>  
22:       <context-param>  
23:            <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>  
24:            <param-value>true</param-value>  
25:       </context-param>  
26:       <context-param>  
27:            <param-name>javax.faces.STATE_SAVING_METHOD</param-name>  
28:            <param-value>server</param-value>  
29:       </context-param>  
30:       <context-param>  
31:            <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>  
32:            <param-value>true</param-value>  
33:       </context-param>  
34:       <context-param>  
35:            <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>  
36:            <param-value>true</param-value>  
37:       </context-param>  
38:       <context-param>  
39:            <param-name>com.sun.faces.numberOfLogicalViews</param-name>  
40:            <param-value>5</param-value>  
41:       </context-param>  
42:       <context-param>  
43:            <param-name>com.sun.faces.numberOfViewsInSession</param-name>  
44:            <param-value>3</param-value>  
45:       </context-param>  
46:       <context-param>  
47:            <param-name>com.sun.faces.compressViewState</param-name>  
48:            <param-value>true</param-value>  
49:       </context-param>  
50:       <context-param>  
51:            <param-name>com.sun.faces.serializeServerState</param-name>  
52:            <param-value>false</param-value>  
53:       </context-param>  
54:       <context-param>  
55:            <param-name>com.sun.faces.preferXHTML</param-name>  
56:            <param-value>true</param-value>  
57:       </context-param>  
58:       <context-param>  
59:            <param-name>com.sun.faces.disableVersionTracking</param-name>  
60:            <param-value>true</param-value>  
61:       </context-param>  
62:       <context-param>  
63:            <param-name>primefaces.THEME</param-name>  
64:            <param-value>aristo</param-value>  
65:       </context-param>  
66:       <security-constraint>  
67:            <display-name>Restrict direct access to XHTML documents.</display-name>  
68:            <web-resource-collection>  
69:                 <web-resource-name>XHTML</web-resource-name>  
70:                 <url-pattern>*.xhtml</url-pattern>  
71:            </web-resource-collection>  
72:            <auth-constraint>  
73:                 <description>No roles defined for direct access to XHTML documents.</description>  
74:            </auth-constraint>  
75:       </security-constraint>  
76:       <session-config>  
77:            <session-timeout>20</session-timeout>  
78:       </session-config>  
79:       <error-page>  
80:            <exception-type>javax.faces.application.ViewExpiredException</exception-type>  
81:            <location>/index.jsf</location>  
82:       </error-page>  
83:       <servlet>  
84:            <servlet-name>Faces Servlet</servlet-name>  
85:            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>  
86:            <load-on-startup>1</load-on-startup>  
87:            <async-supported>true</async-supported>  
88:       </servlet>  
89:       <servlet-mapping>  
90:            <servlet-name>Faces Servlet</servlet-name>  
91:            <url-pattern>/faces/*</url-pattern>  
92:       </servlet-mapping>  
93:       <servlet-mapping>  
94:            <servlet-name>Faces Servlet</servlet-name>  
95:            <url-pattern>*.jsf</url-pattern>  
96:       </servlet-mapping>  
97:       <servlet>  
98:            <servlet-name>Push Servlet</servlet-name>  
99:            <servlet-class>org.primefaces.push.PushServlet</servlet-class>  
100:            <init-param>  
101:                 <param-name>org.atmosphere.useWebSocket</param-name>  
102:                 <param-value>false</param-value>  
103:            </init-param>  
104:            <init-param>  
105:                 <param-name>org.atmosphere.cpr.sessionSupport</param-name>  
106:                 <param-value>true</param-value>  
107:            </init-param>  
108:            <init-param>  
109:                 <param-name>org.atmosphere.useNative</param-name>  
110:                 <param-value>true</param-value>  
111:            </init-param>  
112:            <init-param>  
113:                 <param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>  
114:                 <param-value>org.atmosphere.cache.HeaderBroadcasterCache</param-value>  
115:            </init-param>  
116:            <init-param>  
117:                 <param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>  
118:                 <param-value>org.atmosphere.client.TrackMessageSizeFilter</param-value>  
119:            </init-param>  
120:            <init-param>  
121:                 <param-name>org.atmosphere.resumeOnBroadcast</param-name>  
122:                 <param-value>true</param-value>  
123:            </init-param>  
124:            <load-on-startup>1</load-on-startup>  
125:            <async-supported>true</async-supported>  
126:       </servlet>  
127:       <servlet-mapping>  
128:            <servlet-name>Push Servlet</servlet-name>  
129:            <url-pattern>/primepush/*</url-pattern>  
130:       </servlet-mapping>  
131:  </web-app>  

Now that everything should be configured, lets write a very simple JSF 2 program to show a primepush.

index.xhtml


1:  <!DOCTYPE html>  
2:  <html xmlns="http://www.w3.org/1999/xhtml"  
3:       xmlns:h="http://java.sun.com/jsf/html"  
4:       xmlns:f="http://java.sun.com/jsf/core"  
5:       xmlns:c="http://java.sun.com/jsp/jstl/core"  
6:       xmlns:ui="http://java.sun.com/jsf/facelets"  
7:       xmlns:p="http://primefaces.org/ui">  
8:  <f:view contentType="text/html" encoding="UTF-8">  
9:       <h:head>  
10:            <meta charset="utf-8" />  
11:       </h:head>  
12:       <h:body>  
13:            <h:form prependId="false">  
14:                 <p:inputTextarea id="cmt" value="#{myCommentBean.comment}"></p:inputTextarea>  
15:                 <p:commandButton actionListener="#{myCommentBean.publish}"  
16:                      process="cmt @this" update="cmt" value="publish"></p:commandButton>  
17:            </h:form>  
18:            <span id="pushComment" />  
19:            <p:socket channel="/comment" onMessage="handleMessage"></p:socket>  
20:            <script type="text/javascript">  
21:       function handleMessage(data)  
22:        {   
23:        jQuery('#pushComment').text(data);  
24:               }  
25:      </script>  
26:       </h:body>  
27:  </f:view>  
28:  </html>  

MyCommentBean.java



1:  /**  
2:   * The JSF Backing bean that will push the messages into the socket.  
3:   */  
4:  package my.first.push.project;  
5:  import javax.faces.bean.ManagedBean;  
6:  import javax.faces.bean.RequestScoped;  
7:  import org.primefaces.push.PushContextFactory;  
8:  @ManagedBean(name = "myCommentBean")  
9:  @RequestScoped  
10:  public class MyCommentBean {  
11:    public static final String BROADCAST_CHANNEL = "/comment";  
12:    private String comment;  
13:    public String getComment() {return comment;}  
14:    public void setComment(String comment) {this.comment = comment;}  
15:    public void publish() {  
16:     PushContextFactory.getDefault().getPushContext().push(BROADCAST_CHANNEL, this.comment);  
17:     this.comment = "";  
18:    }  
19:  }  

So now that we have the application, compile and deploy it in JBoss.
Run it on your browser by just accessing the URL:
http://localhost:8080/pushcomment/

Open a few browsers and see how all the clients listening to the socket will get the updates:



Download this project from:

http://www.2shared.com/file/Vy8ZSkUQ/pushcomment.html