To make Seam working on Resin the following steps are necessary:
- Make Resin to 'like' the web.xml by making the namespace empty: <web-app xmlns="">
- Make Resin use apache xml parser by creating WEB-INF/resin-web.xml and putting the following in it:
<web-app xmlns="http://caucho.com/ns/resin">
<system-property javax.xml.parsers.DocumentBuilderFactory="org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"/>
<system-property javax.xml.parsers.SAXParserFactory="org.apache.xerces.jaxp.SAXParserFactoryImpl"/>
</web-app>
- Put xercesImpl.jar in the lib dir of the web app
- If you want to run Seam in ejb3 micro-container you would have to delete the ejb-30.jar from Resin/lib directory otherwise you will get conflicts.
If it's not possible to delete ejb-30.jar from resin/lib (permissions don't allow or can't interfere with other virtual hosts) the the following can be still done to make ejb-3 work in jboss microcontainer:
Create the following class:
package org.emaps.resin;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Introduces a very specific classloader hack for Resin so that it uses ejb.*
* packages from deployed Seam. This hack wont be needed as soon as Resin
* catches up with ejb-3.
*
* @author Siarhei Dudzin
*
*/
public class ClassloaderHack implements ServletContextListener {
/** Log from apache commons logging */
private static final Log log = LogFactory
.getLog(ServletContextListener.class);
/**
* @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent arg0) {
// do nothing
}
/**
* @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent arg0) {
log.info("Starting Resin classloader hack for JBoss Seam");
try {
ClassLoader classLoader = ClassloaderHack.class.getClassLoader();
if (classLoader instanceof com.caucho.loader.DynamicClassLoader) {
com.caucho.loader.DynamicClassLoader resinCL = (com.caucho.loader.DynamicClassLoader) classLoader;
resinCL.addPriorityPackage("javax.persistence.");
resinCL.addPriorityPackage("javax.persistence.spi.");
resinCL.addPriorityPackage("javax.ejb.");
resinCL.addPriorityPackage("javax.ejb.spi.");
}
} catch (Throwable t) {
log.error("Could not get Resin classloader: " + t.getMessage());
t.printStackTrace();
}
}
}
and the following entry in the web.xml before the seam context listener entry:
<!-- Resin classloader hack (needs to be first before all listeners!) -->
<listener>
<listener-class>
org.emaps.resin.ClassloaderHack
</listener-class>
</listener>
This will make sure Resin will use ejb-3 interfaces from your webapp web-inf/lib directory!
That's about it! Enjoy! :)