As a followup to the previous post I feel the obligation to add my testing experience of a small but full featured ADF Faces and ADF Toplink application in glassfish.
The way to call the Transaction Manager in Glassfish is:
java:appserver/TransactionManager
We need to create a new class named GFTransactionController:
===============================================v
package oracle.toplink.transaction.gf;
import javax.transaction.TransactionManager;
import oracle.toplink.transaction.JTATransactionController;
public class GFTransactionController extends JTATransactionController {
public GFTransactionController() { }
protected TransactionManager acquireTransactionManager() throws Exception {
return (TransactionManager)jndiLookup("java:appserver/TransactionManager");
}
public static final String JNDI_TRANSACTION_MANAGER_NAME = "java:appserver/TransactionManager";
}
===============================================
We also need to change the Transaction Controller in our project.
Open your adf model project in Jdeveloper and follow these instructions:
===============================================
1. In the Applications Navigator, select DataModel --> Application Sources --> TopLink.
2. Select sessions.xml. In the Structure pane, double-click 'default' (or whatever you have named it).
3. On the General page, select the External Transaction Controller check box in Options.
4. Enter the following transaction class:
oracle.toplink.transaction.gf.GFTransactionController
===============================================
< web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" >
===============================================
with
===============================================
< web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5" >
===============================================
Now redeploy your project and all ejb junctionality is working correctly.
As I have already mentioned in a previous post, 90% of the problems is a path translation error, because the two servers handle paths a little differently.
The basic problem I stumbled upon was the External Transaction Controller. Toplink.jar does not provide a TransactionController for GlassFish, although there is one for Oc4j, JBoss, WebSphere and Weblogic. As a result, we have to create one on our own.
The way to call the Transaction Manager in Glassfish is:
java:appserver/TransactionManager
We need to create a new class named GFTransactionController:
===============================================v
package oracle.toplink.transaction.gf;
import javax.transaction.TransactionManager;
import oracle.toplink.transaction.JTATransactionController;
public class GFTransactionController extends JTATransactionController {
public GFTransactionController() { }
protected TransactionManager acquireTransactionManager() throws Exception {
return (TransactionManager)jndiLookup("java:appserver/TransactionManager");
}
public static final String JNDI_TRANSACTION_MANAGER_NAME = "java:appserver/TransactionManager";
}
===============================================
In order to compile this class one needs toplink.jar ({jdev_install}/toplink/jlib) and j2ee.jar ({glassfish_install}/lib) in the classpath.
Then we open toplink.jar (the one inside glassfish) with winrar. We navigate to folder oracle/toplink/transaction. Right click --> Create new folder --> gf. Navigate to gf and drag and drop the GFTransactionController.class file inside. Our new toplink.jar is ready. We copy the new toplink.jar in {glassfish_install}/lib.
We also need to change the Transaction Controller in our project.
Open your adf model project in Jdeveloper and follow these instructions:
===============================================
1. In the Applications Navigator, select DataModel --> Application Sources --> TopLink.
2. Select sessions.xml. In the Structure pane, double-click 'default' (or whatever you have named it).
3. On the General page, select the External Transaction Controller check box in Options.
4. Enter the following transaction class:
oracle.toplink.transaction.gf.GFTransactionController
===============================================
The other problem that I found was at web.xml. JDeveloper creates by default a new web project with a 2.4 xsd for web.xml. We need to change that to a 2.5 xsd. So we open our web.xml and replace our
===============================================< web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" >
===============================================
with
===============================================
< web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5" >
===============================================
Now redeploy your project and all ejb junctionality is working correctly.
Another minor change is the result of this command: getServletConfig().getServletContext().getRealPath("/test/");
Oc4j returns a slash at the end, while Glassfish does not. A simple solution is to add the last slash after the command:
getServletConfig().getServletContext().getRealPath("/test")+"/";As I have already mentioned in a previous post, 90% of the problems is a path translation error, because the two servers handle paths a little differently.
As a conlcusion, I need to note that GlassFish can successfully run an ADF Faces with ADF Toplink (EJB 3) Application with only a few configuration changes and some slight code modifications! Apart from TransactionController, all the others pass in OC4J too. So, there is no need to start using glassfish as a testing server if you are already using JDeveloper!