Monday, April 27, 2009

Run Glassfish v2 EJB3 example on JBoss 5

  • JBoss 5 with Derby as DataSource
There are some really good blogs about how to use derby as JBoss DataSource like Alistair Israel's, but still things to be noticed.
After copy ${JBOSS_HOME}/docs/examples/jca/derby-ds.xml to ${JBOSS_HOME}/server/default/deploy, several items should be adjusted according to the sample, like:
<jndi-name>jdbc/sample</jndi-name>
<connection-url>jdbc:derby://localhost:1527/sample</connection-url>
<driver-class>org.apache.derby.jdbc.ClientXADataSource</driver-class>
And the following to specify the database:
<mbean code="org.jboss.jdbc.DerbyDatabase" name="jboss:service=Derby">
<attribute name="Database">sample</attribute>
</mbean>
Then, Copy ${JBOSS_HOME}/docs/examples/varia/derby-plugin.jar and the ${DERBY_HOME}/lib/derby.jar and derbyclient.jar to ${JBOSS_HOME}/server/default/lib.

Next is workaround of JBoss JMX if using JBoss 5.01GA(fixed in 5.1.0GA), add -Djboss.platform.mbeanserver at the end of line in ${JBOSS_HOME}/bin/run.bat(or run.sh):
set JAVA_OPTS=...
  • JBossXBRuntimeException
You won't have it in this example, but say if you try to run the entity demo, you probably get:
DEPLOYMENTS IN ERROR:
Deployment "vfszip:.../server/default/deploy/lab-entity-demo4.jar/" is in error due to the following reason(s): org.jboss.xb.binding.JBossXBRuntimeException: Failed to resolve schema nsURI= location=persistence

This is due to the persistence.xml missing schema namespaces:
<?xml version="1.0" encoding="UTF-8"?>
<persistence>
<persistence-unit name="lab-entity-demo4">
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>

To correct it, the following should be put in persistence element:
version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
  • org.jboss.deployers.spi.DeploymentException:
Required config property RequiredConfigPropertyMetaData@f1770a[name=destination descriptions=[DescriptionMetaData@7f0b4e[language=en]]] for messagingType 'javax.jms.MessageListener' not found in activation config [ActivationConfigProperty(destinationType=javax.jms.Queue)] ra=jboss.jca:service=RARDeployment,name='jms-ra.rar'

Need to add "destination" property in ActivationConfigProperty. See next step.
  • Modify MessageBean, add JBoss specific annotation:
import org.jboss.ejb3.annotation.Depends;

@MessageDriven(mappedName = "jms/NewsMsg", activationConfig = {
// JBoss by default uses AUTO_ACKNOWLEDGE:
// @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="jms/NewsMsg")
})
@Depends ("jboss.mq.destination:service=Queue,name=ejbfoo")
public class NewsMessageBean implements MessageListener {
...

  • Add ejbfoo-queue-service.xml in src/conf. Netbeans will pack this file in META-INF when build the jar fiel.
<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=ejbfoo">
<attribute name="JNDIName">jms/NewsMsg</attribute>
<depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>
</server>
  • Modify persistence.xml as following:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="EjbFoo-ejbPU" transaction-type="JTA">
<!-- Toplink is default for Glassfish
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<jta-data-source>jdbc/sample</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="toplink.ddl-generation" value="create-tables"/>
</properties>
-->

<!-- Hibernate for JBoss -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/jdbc/sample</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>

  • Modify PostNews servlet, which is the messageProducer and send the message through queue:
public class PostNews extends HttpServlet {
// For Glassfish:
//@Resource(mappedName = "jms/NewsMsgFactory")
// For JBoss:
@Resource(mappedName = "ConnectionFactory")
private ConnectionFactory connectionFactory;
@Resource(mappedName = "jms/NewsMsg")
private Queue queue;
...
  • Deploy and run as you would under Glassfish.

No comments: