Tuesday, May 15, 2007

JBoss 4.2 with Seam 1.2 using MyFaces

JBoss stopped using MyFaces in JBoss 4.2 and started using a JSF 1.2 compliant deployment.
This creates problems when using Seam 1.2.1 and JBoss 4.2 together. The fix is quite simple and can be remedied in three easy steps.

Step One:
Remove the MyFaces entry in web.xml by commenting out the MyFaces listener as shown below by adding the blue text below:
<!--
<listener> <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
-->

Step Two:
Edit application.xml (usually in the project's resources directory) and remove by either deletion or comment the el-api.jar module.

You can comment it out as shown below:
<!--
<module>
<java>el-api.jar</java>
</module>
-->

Step Three:
The final step is to make sure the build.xml copies commons-digester and commons-beanutils to the WEB-INF/lib directory of the web application's war file.

Add the following two lines to build.xml that are highlighted below in blue in the build files "war" target:
<target name="war" depends="compile"
description="Build the distribution .war file">
<copy todir="${war.dir}">
<fileset dir="${basedir}/view" />
</copy>
<copy todir="${war.dir}/WEB-INF">
<fileset dir="${basedir}/resources/WEB-INF">
<include name="*.*"/>
<include name="classes/**/*.*"/>
<exclude name="classes/**/*.class"/>
</fileset>
<filterset>
<filter token="debug" value="${debug}" />
<filter token="jndiPattern" value="${project.name}/#{ejbName}/local" />
<filter token="embeddedEjb" value="false" />
</filterset>
</copy>
<copy todir="${war.dir}/WEB-INF">
<fileset dir="${basedir}/resources/WEB-INF">
<include name="lib/*.*"/>
<include name="classes/**/*.class"/>
</fileset>
</copy>
<copy todir="${war.dir}/WEB-INF/lib">
<fileset dir="${lib.dir}">
<include name="ajax4jsf*.jar" />
<include name="richfaces*.jar" />
<include name="oscache*.jar" />
<include name="jsf-facelets.jar" />
<include name="jboss-seam-*.jar" />
<include name="commons-digester-*.jar"/>
<include name="commons-beanutils-*.jar"/>
<exclude name="jboss-seam-gen.jar" />
</fileset>
</copy>
<copy todir="${war.dir}/WEB-INF/classes">
<fileset dir="${basedir}/resources">
<include name="messages*.properties"/>
</fileset>
</copy>
</target>

That should be sufficient to run the seam-gen generated applications to run on JBoss 4.2.0GA.

Sunday, May 6, 2007

JBoss and Global JNDI Entries

In Tomcat, global JNDI entries can be added to the server.xml file to allow for JNDI entries to be shared across all deployed applications needing them. Trying to find way to get global JNDI entries in JBoss 4 was difficult, but the solution was easy. Probably a Google search string issue, anyway on to the solution.

How do you add global JNDI entries to JBoss?
To add global JNDI entries you simply create (edit if it exists) an jboss-service.xml file and use the JNDIBindingServiceMgr MBean.

jboss-service.xml:
   <?xml    version="1.0" encoding="UTF-8"?>
<!DOCTYPE server PUBLIC "-//JBoss//DTD MBean Service 4.0//EN"
"http://www.jboss.org/j2ee/dtd/jboss-service_4_0.dtd">
<server>
<mbean code="org.jboss.naming.JNDIBindingServiceMgr"
name="jboss.tests:service=JNDIBindingServiceMgr">
<attribute name="BindingsConfig" serialDataType="jbxb">
<jndi:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jndi="urn:jboss:jndi-binding-service:1.0"
xs:schemaLocation="urn:jboss:jndi-binding-service:1.0 resource:jndi-binding-service_1_0.xsd">
<jndi:binding name="urls/jboss-home">
<jndi:value type="java.net.URL">http://www.jboss.org</jndi:value>
</jndi:binding>

<jndi:binding name="urls/scotts-test">
<jndi:value type="java.lang.String">http://www.yahoo.com</jndi:value>
</jndi:binding>

<jndi:binding name="hosts/localhost">
<jndi:value editor="org.jboss.util.propertyeditor.InetAddressEditor">127.0.0.1</jndi:value>
</jndi:binding>
<jndi:binding name="maps/testProps">
<java:properties xmlns:java="urn:jboss:java-properties"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="urn:jboss:java-properties resource:java-properties_1_0.xsd">
<java:property>
<java:key>key1</java:key>
<java:value>value1</java:value>
</java:property>
<java:property>
<java:key>key2</java:key>
<java:value>value2</java:value>
</java:property>
</java:properties>
</jndi:binding>
</jndi:bindings>
</attribute>
</mbean>

</server>


</server>


Simply add/edit a jndi:binding to suit your needs and you will be able to access from either your EJB or web application. The Java code to access the entries in /urls including "scotts-test" above, simply perform the following in your enterprise application.


Retrieving Global JNDI Entries:
Context ctx = new InitialContext();
NamingEnumeration items = ctx.listBindings("/urls");
while ( items.hasMoreElements() ) {
System.out.println( items.next().toString() );
}


Some are probably wondering where the jboss-service.xml file goes. The place that worked for me was into <JBOSS_HOME>/server/default/deploy and then restart JBoss.

Related Links:
JBoss Wiki on JNDIBindingServiceMgr


Contributors