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.

Thursday, April 23, 2009

Play with JBoss 5: ejb3.deployer not found

Like all other open source stuffs, you have to pull the scattered pieces together before you can actually get like a simple tutorial working. Recently I downloaded JBoss 5.0.1 AS and wanted to play with the ejb3. So I downloaded the EJB3Labs from JBoss community and just as I expected, it won't run without some tweaking. Here are the tricks:
  • In build.bat, comment out set ANT_HOME=..\..\..\ant-dist and set the variable in the environment.
  • Then run build runejb, and there you get:
JBossWorldBerlinLabs\lab-slsb-demo3\src\build\build.xml:44: jboss-5.0.1.GA\server\default\deploy\ejb3.deployer not found.
  • In build.xml, you have to change the classpath as it was restructured in JBoss AS5:
deploy/ejb3.deployer -> deployers/ejb3.deployer
deploy/jboss-aop-jdk50.deployer -> deployers/jboss-aop-jboss5.deployer


Then add:
<fileset dir="${jboss.home}/common/lib">
  <include name="**/*.jar">
  </include>
</fileset>

  • Last, in Client.java
calculator = (Calculator) ctx.lookup("TODO:insert name");
should be changed to
calculator = (Calculator) ctx.lookup("CalculatorBean/remote");
Ref: JBoss EJB3 Tutorial

Thursday, April 2, 2009

Change Oracle XE default HTTP and DB ports

  • Stop listener in command window:
lsnrctl stop
  • Modify ORACLE_HOME/app/oracle/product/10.2.0/server/NETWORK/ADMIN/listener.ora
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
(ADDRESS = (PROTOCOL = TCP)(HOST = myhost)(PORT = 1521))
)
)
Change the PORT to the number wanted. Also modify PORT in tnsnames.ora and save.
  • Start listener:
lsnrctl start
  • Run SQL Plus to add local listener for that port, then change HTTP listening port:
conn system/password;
alter system set local_listener = "(ADDRESS=(PROTOCOL=TCP)(HOST=your.com)(PORT=1522))";
exec dbms_xdb.sethttpport(nnnn);
alter system register;
disc;
If "set local_listener" is omitted, you probably will get get "ORA-12514: TNS:listener does not currently know of service requested when openning SQL Plus with sqlplus system@xe

alter system register" is also important as it reregisters the DB and all services with the listener. Otherwise you can find the port is not listening with netstat -an. Also you can verify with lsnrctl status, and a line like following should be there:
...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=your.com)(PORT=8090))(Presentation=HTTP)(Session=RAW))

  • Confirm:
select dbms_xdb.gethttpport as "HTTP Port",
dbms_xdb.getftpport as "FTP Port" from dual;
Ref: http://download.oracle.com/docs/cd/B25329_01/doc/admin.102/b25107/network.htm#BHCCDEIH