Friday, October 7, 2011

How to test primefaces component with JSFUnit2

As you may know JSFUnit 2.0.0.Beta 2 is Out!

After successfully execute the JSFUnit2 getting started example on jboss as7, i've triyed the the integration between JSFUnit and primefaces (since it's my favorite JSF components library ;-)
First i've included the primefaces library into my test war archive in the deployement method using MavenDependencyResolver (for further details see this blog entry)

.addAsLibraries(DependencyResolvers.use(MavenDependencyResolver.class)
.configureFrom("src/test/resources/mvn_settings/settings.xml")
.artifact("org.primefaces:primefaces:jar:2.2")
.resolveAs(GenericArchive.class))
If you do not use Maven you can just put the primefaces librairy in a lib folder under WEB-INF folder and add this line to the deployement method :


.addAsWebInfResource(new File("src/main/webapp/WEB-INF/lib/primefaces-2.2.jar"),"lib/primefaces-2.2.jar")

Second, i've modifed the index.xhtml as bellow:











After that i executed my mvn install but i got the error "PrimeFaces" is not defined... humm... may be primefaces resources wasn't injected ...

I've just added the "h:head" tag to the index.xhtml file and my test succed !!!!! witch means that the primefaces resources was included automatically and JSFUnit recognize it now ...

Note that the component test is based on components client ID, so be prudent on your component testing !!

For example if you want to test the calendar component by trying the the setValue method on your test class with the id you have gave to your p:calendar (), you get the error :

java.lang.IllegalArgumentException: This method can not be used on components of type com.gargoylesoftware.htmlunit.html.HtmlSpan

it's normal because the setValue is used for input field not for span ;-) so you should use setValue ("date_input", VALUE) instead of setValue("date",VALUE)
[Tips: you can use Firebug to inspect elements and see their client id]

I'm adding the full example for p:calendar here based on the getting starded example

Test page:










Test method:
public void testInitialPage(JSFServerSession server, JSFClientSession client)
throws IOException {

// Set the param and submit
String sDate = new Date().toString();
client.setValue("date_input", sDate);
client.click("submit_button");

// Assert that the greeting component is in the component tree and rendered
UIComponent greeting = server.findComponent("greeting");
Assert.assertTrue(greeting.isRendered());

// Test a managed bean using EL. We cheat and use the request object.
Assert.assertEquals(sDate,
server.getManagedBeanValue("#{request.getParameter('form1:date_input')}"));
}

you can download the full example here

The test was done using primefaces2.2,JSF 2.0, JSFUnit2Beta2, Maven3, Jboss as7

Saturday, October 1, 2011

How to use Hibernate 3 as JPA provider in JBoss AS7


Jboss AS7 come with Hibernate 4 (even if it still in beta :-)! if you still use hibernate 3 as JPA provider in your application and you want to deploy it in Jboss AS7 ... you may know it's possible ... Humm yes you can do it just by creating a module for hibernate3 under your Jboss AS7 (how powerful server is !). So you just need to:

* Create a folder in AS7_HOME\modules\org\hibernate\3 for slot 3 to hold your hibernate 3 jars.

* Copy the hibernate 3 associated jars into this folder. For example:

•antlr-3.2.jar
•asm-3.3.jar
•btm-1.3.3.jar
•hibernate-commons-annotations-3.2.0.Final.jar
•hibernate-core-3.6.1.Final.jar
•hibernate-entitymanager-3.6.1.Final.jar

* Create the AS7_HOME/modules/org/hibernate/3/module.xml file with contents :































That's it, your module now is available on your jboss 7 server, all you nedd to link it with your application is to add the followed property to your persistence unit :

Note the org.hibernate:3 on your jboss.as.jpa.providerModule property ;-)

Tuesday, September 27, 2011

How to use Shrinkwrap MavenDependencyResolver

If you use Maven to build your application and you want to test it with Arquillian, Be sure that you will be looking for a way to include some of your libraries (artifact) from Maven into your archive file (war, ear...).

In this article we show you how to use the Shrinkwrap MavenDependencyResolver to read artifact from pom file using the maven setting file.

For this purpose you just need to add your maven setting file in a folder mvn_settings under src/test/ressources and add this entry in your @Deployment method !

.addAsLibraries(DependencyResolvers.use(MavenDependencyResolver.class)
.configureFrom("src/test/resources/mvn_settings/settings.xml")
.artifact("GROUPID:ARTIFACTID:TYPE:VERSION")
.resolveAs(GenericArchive.class))


For further details about Resolver extension in ShrinkWrap, refer to: https://github.com/shrinkwrap/resolver

Saturday, September 24, 2011

JSFUnit 2.0.0.Beta 2 is Out


The Beta 2 version for JSFUnit2 is available from the middle of this month (September) with a fully support for junit 4, JSF2 and Arquillian , for more details check this blog entry and the release note

Have a look at this related getting started example and enjoy it!!

Friday, September 23, 2011

How to configure Arquillian with a remote Jboss AS7


If you want to use Arquillian to connect and run against a remote(different JVM, different machine) running previous version of Jboss server, you need to use JNDI properties for that !

In Jboss AS 7, the jndi.properties file is not used... So If you have set the managementAddress configuration option to where the management api is bound, Arquillian should read out from the server (remote or local jvm/machine) where the ip_adress/port_number are bound.

All this configuration is done in the arquillian.xml file as bellow:
 

IP_ADR
PORT_NUM


For JBoss AS 7.0.0.Final, you need to configure the jmx protocol used by adding:

REMOTE

under the container tag ...

Monday, August 29, 2011

How it's easy to configure ports in Jboss AS7

If you want to change/configure your ports server on Jboss AS7, all you need is to modify entries under socket-binding-group for standalone.xml and socket-binding-groups for domain.xml, for example in standalone.xml:















Very easiest way! doens't it ?

Sunday, August 28, 2011

Ldap Realm configuration on Jboss AS7

In Jboss 6 and lower the ldap Realm was configured in the login-config.xml file like :
 


com.sun.jndi.ldap.LdapCtxFactory
simple
....



On jboss 7 the ldap Realm configuration has a little changed, it become on the standalone.xml (or in domain.xml) as a security domain under :
 
As bellow:







...




Note that the xml parser has changed in Jboss 7, so you should convert every module-option tag so that the lowest level data element for the module-option tag was replaced by the attribute value= and the tag was converted to a self-closing tag, for example:


com.sun.jndi.ldap.LdapCtxFactory

Become:




For our blog ldap directory, the wall configuration become :



















also,




needs to be changed to:







else ModuleClassLoader won't load the com.sun.jndi.ldap.LdapCtxFactory which is needed in ldap authentication modules, and obviously you ll need org.jboss.security.auth.spi.LdapLoginModule on classpath.

Saturday, August 20, 2011

Configure your Jboss AS7 to be accessible from the network

If you want to have the web console as well as your web application accessible from the network, you have to change the default configuration of JBoss.

1) go to standalone/configuration
2) Open the file standalone.xml (or domain.xml)
3) Look for the lines :








4) Change both IP address from 127.0.0.1 to the ip address of your network interface. Note that your complex deployment the server may have 2 ip adresses 1 for business flows and 1 for management flows.
5) Kill JBossAS and restart

The Admin console should be accessible now from your desktop computer at http://:9990/console ;-)

Sunday, August 7, 2011

Spring3 and JSF2 integration using CDI annotations

In this blog i show you how to use @Inject in your JSF managed beans to directly inject the Spring beans instead of instantiating a Spring application context and using the getBean methode from that context and also how Spring will manage your JSF beans ;-)


In order to inject Spring beans into JSF managed beans using @Inject, the following needs to be done:


1)web.xml

 
org.springframework.web.context.ContextLoaderListener


contextConfigLocation

classpath:/applicationContext.xml


org.springframework.web.context.request.RequestContextListener


2) faces-config.xml

 
org.springframework.web.jsf.el.SpringBeanFacesELResolver

3) applicationContext.xml





4) JSF Managed bean

 @ManagedBean(name="blogJSFBean")
@Controller
@ViewScoped
public class MainBean implements Serializable {
private static final long serialVersionUID = -5012655116147710604L;
@Inject
private SpringBean myBlogBean;


To keep it standard i have changed @Managedean to @Named witch is a CDI standard annotation suported by Spring also (as an alternate to @Service and @Controller)

The big problem i have found that the scope view (@ViewScoped) isn't supported by Spring (also Flash scope …) so i have developped the view scope as Spring custom scope following this article: http://cagataycivici.wordpress.com/2010/02/17/port-jsf-2-0s-viewscope-to-spring-3-0/


my bean become:

 @Named("blogJSFBean")
@Scope (value="view")
public class MainBean implements Serializable {
private static final long serialVersionUID = -5012655116147710604L;
@Inject
private SpringBean myBlogBean;


In general the big difference i have found is that Spring and JSF bean from Java EE 6 use a different scoping! Spring do not support standard scope annotation used in JSF and CDI. To get it work i have followed a workaround to import JSF/CDI bean into Spring:

http://matthiaswessendorf.wordpress.com/2010/05/06/using-cdi-scopes-with-spring-3/

Finaly with all this configuration and workarounds, i have been able to inject Spring beans into JSF using @Inject and @Named Java EE standard annotaion and a custom Spring scope to import JSF/CDI scope


Saturday, July 23, 2011

How to use JAAS to authenticate users on an LDAP directory


This article cover all JAAS authentication concept by describing a sample JAVA application "SampleLDAPLogin.java" to authenticate a user on an LDAP directory using JAAS.

So to authenticate your LDAP users using the SampleLDAPLogin application, the following steps are performed:
  1. The application instantiates a LoginContext.
  2. The LoginContext consults a Configuration (described in the sample_jaas_ldap.config login configuration file) to load the LdapLoginModule which is a LoginModule performing LDAP-based authentication.
  3. The application invokes the LoginContext's login method.
  4. The login method invokes the loaded LoginModule (LdapLoginModule) which attempt to authenticate the user against the corresponding user credentials stored in the openLDAP directory. The LdapLoginModule module requires the supplied CallbackHandler (SampleCallbackHandler.java) to support a NameCallback and a PasswordCallback.
  5. The LoginContext returns the authentication status to the application.
  6. If authentication is successful then a new LdapPrincipal is created using the user's distinguished name and a new UserPrincipal is created using the user's username and both are associated with the current Subject.

This example consists of three files: SampleLDAPLogin.java, SampleCallbackHandler.java, sample_jaas_ldap.config

The SampleLDAPLogin Class

public class SampleLDAPLogin {
public static void main(String[] args) {
LoginContext lc = null;
try {
lc = new LoginContext("SampleLDAPConfiguration", new SampleCallbackHandler());
} catch (LoginException le) {
System.err.println("Cannot create LoginContext. " + le.getMessage());
System.exit(-1);
} catch (SecurityException se) {
System.err.println("Cannot create LoginContext. " + se.getMessage());
System.exit(-1);
}
try {
// attempt authentication
lc.login();
System.out.println("Authentication succeeded!");
} catch (LoginException le) {
System.err.println("Authentication failed:\n" + le.getMessage());
}
}
}

The code for authenticating consist of just two steps:
  • Instantiate a LoginContext with two arguments :

    lc = new LoginContext("SampleLDAPConfiguration", new SampleCallbackHandler());
  1. SampleLDAPConfiguration: The name of the entry in the JAAS login configuration file (sample_jaas_ldap.config)
  2. new SampleCallbackHandler(): A CallbackHandler instance
  • Call the LoginContext's login method: lc.login();

The SampleCallbackHandler Class

public class SampleCallbackHandler implements CallbackHandler {
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
// prompt the user for a username
NameCallback nc = (NameCallback)callbacks[i];
System.err.print(nc.getPrompt());
System.err.flush();
nc.setName((new BufferedReader
(new InputStreamReader(System.in))).readLine());
} else if (callbacks[i] instanceof PasswordCallback) {
// prompt the user for sensitive information
PasswordCallback pc = (PasswordCallback)callbacks[i];
System.err.print(pc.getPrompt());
System.err.flush();
pc.setPassword(readPassword(System.in));
} else {
throw new UnsupportedCallbackException
(callbacks[i], "Unrecognized Callback");
}
}
}
// Reads user password from given input stream.
private char[] readPassword(InputStream in) throws IOException {
char[] lineBuffer;
char[] buf;
int i;
buf = lineBuffer = new char[128];
int room = buf.length;
int offset = 0;
int c;
loop: while (true) {
switch (c = in.read()) {
case -1:
case '\n':
break loop;
case '\r':
int c2 = in.read();
if ((c2 != '\n') && (c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
} else
break loop;
default:
if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
Arrays.fill(lineBuffer, ' ');
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}
if (offset == 0) {
return null;
}
char[] ret = new char[offset];
System.arraycopy(buf, 0, ret, 0, offset);
Arrays.fill(buf, ' ');
return ret;
}
}

In some cases a LoginModule (in our case:LdapLoginModule) must communicate with the user to obtain authentication information.

SampleCallbackHandler handles two types of Callbacks: NameCallback to prompt the user for a user name and PasswordCallback to prompt the user for a password.

The sample_jaas_ldap.config (login configuration file)

SampleLDAPConfiguration{

com.sun.security.auth.module.LdapLoginModule REQUIRED

userProvider="ldap://ip_adress:ldap_port/ou=users,

dc=blogDomain,dc=badr,dc=org"

userFilter="uid={USERNAME}"

useSSL=false

debug=true;

};

This entry is named "SampleLDAPConfiguration" and that is the name that our sample application, SampleLDAPLogin, uses to refer to this entry. The entry specifies that the LoginModule to be used to do the user authentication is the "com.sun.security.auth.module.LdapLoginModule" and that this LdapLoginModule is required to "succeed" in order for authentication to be considered successful. The LdapLoginModule succeeds only if the name and password supplied by the user are the one it expects in the DN (Distinguished Name) openLDAP directory "ldap://ip_adress:ldap_port/ou=users,dc=blogDomain,dc=badr,dc=org"

Depending on ther user/password entred You wil get different message in your console from LdapLoginModule using the TextOutputCallback !

Saturday, July 9, 2011

How to read arabic message from ressource bundles with JSF


In this article we assume that you already have an idea about configuring ressource bundles in JSF, how to use it in your pages and also how to configure jsf pages encoding ...

This blog entry is realy independante from JSF version, and it works for both JSF1 and JSF2 ;-)

We suppose that you want to write "Arabic" like "loginBean.username.label = اسم المستخدم " in the message resource bundle (properties) file and you try to save it you will get this error:
"Save couldn't be completed Some characters cannot be mapped using "ISO-85591-1" character encoding. Either change encoding or remove the character ..." because the default mechanism loading of properties files is in "ISO-8559-1-1".

If you change the file encoding to UTF-8, you will be able to save the file but you can not print your messages correctly in JSF !!

To get it work you have to change the default mechanism loading to UTF-8 by implementing a custom ressource bundle class using UTF-8 Control

public class I18nRessourceBundle extends ResourceBundle {

protected static final String BUNDLE_EXTENSION = "properties";
protected static final String CHARSET = "UTF-8";
public static final Control UTF8_CONTROL = new UTF8Control();

public I18nRessourceBundle() {
setParent(ResourceBundle.getBundle("Propety_File_Ressource",
FacesContext.getCurrentInstance().getViewRoot().getLocale(), UTF8_CONTROL));
}

@Override
protected Object handleGetObject(String key) {
return parent.getObject(key);
}

@Override
public Enumeration getKeys() {
return parent.getKeys();
}

public static class UTF8Control extends Control {
public ResourceBundle newBundle
(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
// The below code is copied from default Control#newBundle() implementation.
// Only the PropertyResourceBundle line is changed to read the file as UTF-8.

String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, BUNDLE_EXTENSION);
ResourceBundle bundle = null;
InputStream stream = null;
if (reload) {
URL url = loader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
} else {
stream = loader.getResourceAsStream(resourceName);
}
if (stream != null) {
try {
bundle = new PropertyResourceBundle(new InputStreamReader(stream, CHARSET));
} finally {
stream.close();
}
}
return bundle;
}
}
}


We assume that you have a properties file Propety_File_Ressource in your ressource folder

So in JSF configuration you should use:



...


package_name.I18nRessourceBundle
msgBlog

Insted of


...


Propety_File_Ressource
msgBlog




Enjoy it!

Sunday, June 26, 2011

Getting Started with JSF 2 and Primefaces

In this entry we show you how you can start using primefaces with the JSF Mojara reference implementation !

So After setting up your web project with maven and eclipse you just need to import the JSF and Primefaces namespaces into your pages to test the first integration and display some components.

PS:You also need to add primefaces maven dependencies ...

JSF Namespace
JSF namespace is necessary to add JSF tags and components to your pages.

xmlns:f="http://java.sun.com/jsf/core"

xmlns:h="http://java.sun.com/jsf/html"

Primefaces Namespace
PrimeFaces namespace is necessary to add PrimeFaces components to your pages.

xmlns:p="http://primefaces.prime.com.tr/ui"

Test Run

That's it, now you can add a test for JSF and Primefaces component to see if everything is ok.











Congratulation !! executing the application and getting the correct display means JSF and Primefaces are working fine in your web application ...

If you want to deepen your JSF integration test, you can add a JSF managed bean and call it from your page !

Create a managed bean

Briefly a managed bean is a regular Java bean (simple pojo) with a fancy name. When we register the bean with JSF it becomes a managed bean, in other words, it’s now managed by the framework (JSF). For further information see learning-jsf2-managed-beans and whats-new-in-jsf-2

Now, let's create HelloMyBlog our own managed bean !

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name = "helloMyBlog")//or just @Named only from CDI
@RequestScoped
public class HelloMyBlog {
private String webFramework;

public HelloMyBlog(){
webFramework = "JSF 2 and Primefaces";
}

public String getWebFramework() {
return webFramework;
}

public void setWebFramework(String webFramework) {
this.webFramework = webFramework;
}
}

After, we create our view helloMyBlog.xhtml witch use the managed bean HelloMyBlog by name "helloMyBlog" ( @ManagedBean(name = "helloMyBlog"), or just @Named from CDI )












Finaly, Run your application ...

Your web browser should now display the same result as our first test !

Conclusion

We covered in this article the basic test and integration for a simple JSF application with Primefaces component libraries.

Befor going ahead with JSF developpement it's highly recomended to understand the life cycle of a JSF application see JSF application lifecycle

In general JSF is great if you have time to learn it before you have to use it as your main venue for a major project ;-)

Saturday, June 25, 2011

Set up JSF 2 web project (Maven+ Eclipse)

In this entry we show you how to configure your project with Maven and eclipse to support JSF capabilities.

Set up web project with Maven

JSF Dependency

  • For Java EE Application

In most "Java EE 6" application servers, it has "build-in support for JSF 2.0", so you only need to download one JSF API for development purpose.


com.sun.faces
jsf-api
2.1.0-b03
provided


  • For simple servlet container like Tomcat

You may need to download the following dependencies:




javax.servlet
jstl
1.2
runtime



javax.servlet
servlet-api
2.5
provided



javax.servlet.jsp
jsp-api
2.1
provided



javax.el
el-api
provided
1.0



com.sun.faces
jsf-api
2.1.0-b03



com.sun.faces
jsf-impl
2.1.0-b03



JSF 2.0 Servlet Configuration

Just like any other standard web frameworks, you are required to configure the JSF stuff in web.xml file as bellow




Set up web project


index.jsp



Faces Servlet
javax.faces.webapp.FacesServlet
1



Faces Servlet
/faces/*



javax.faces.DEFAULT_SUFFIX
.xhtml



javax.faces.PROJECT_STAGE
Development



Explanation for web.xml content
  1. Define the version 2.5 for your web module "web-app_2_5", it's so important to do that befor executing your first Maven install to keep your project compliant with Dynamic Web Module 2.5 (servlet specification 2.5) and thereafter add the JSF capabilities to your eclipse project (as shown in the next chapter)

  2. Add the JSF servlet in the web.xml, define a “javax.faces.webapp.FacesServlet” mapping to "/faces/*" ( you can also add the extension (*.jsf, *.xhtml,*.faces) to your mapping.

  3. Define a default mapping "javax.faces.DEFAULT_SUFFIX" with .xhtml file extension (not mandatory)

  4. In JSF 2.0 development, it’s recommended (not mandatory) to set the “javax.faces.PROJECT_STAGE” to “Development“, it will provide many useful debugging information to let you track the bugs easily (for deployment, just change it to “Production“)

Set up web project in eclipse

After importing your maven web project into eclipse, everything looks fine except the code assist doesn't work! ie : when you presse on the “Ctrl + Space” combination keys it prompts nothing?

To resolve that: in Eclipse project, you have to make sure the project is supported the WTP and JSF capabilities. so Right click on the project, choose properties, select “Project Facets“, make sure the “JavaServer Faces” is checked.
This allow you also to open your page with "web page editor" and drag and drop JSF component ...