Hi, I saw a lot this message in the forum : "Don't specify a SessionFactory JNDI name, Tomcat JNDI is read-only".
That's true only for Web applications. Tomcat can initialize JNDI names thanks to server.xml with <GlobalNamingResources>, <Resource> and <ResourceParams>, but to configure that, we have to use a class which implements "javax.naming.ObjectFactory". There are none class in Hibernate that implements it. That's why we can't configure Tomcat to get a SessionFactory with JNDI. I create this class and after many tests, I had good results to get a SessionFactory and to create Sessions. After I have a problem to read data and here I need your help. ;-( look at this link : http://jakarta.apache.org/tomcat/tomcat-4.1-doc/jndi-resources-howto.html#Ad ding%20Custom%20Resource%20Factories See the code for the factory : import java.io.File; import java.io.InputStream; import java.util.Enumeration; import java.util.Properties; import java.util.Hashtable; import java.util.Iterator; import javax.naming.Context; import javax.naming.Name; import javax.naming.NamingException; import javax.naming.RefAddr; import javax.naming.Reference; import javax.naming.spi.ObjectFactory; import net.sf.hibernate.HibernateException; import net.sf.hibernate.SessionFactory; import net.sf.hibernate.cfg.Configuration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.impl.SimpleLog; import org.apache.commons.logging.LogConfigurationException; /** * JndiSessionFactoryImpl to configure in an API Server to initialize * a SessionFactory in a JNDI context. * * Tomcat Configuration in server.xml : * * <!-- Global JNDI resources --> * <GlobalNamingResources> * ... * <Resource description="SessionFactory Resource" * name="HibernateSessionFactory" auth="Container" * type="net.sf.hibernate.SessionFactory"/> * <ResourceParams name="HibernateSessionFactory"> * <parameter> * <name>factory</name> * <value>JndiSessionFactoryImpl</value> * </parameter> * <parameter> * <name>pathname</name> * <value>conf/hibernate.cfg.xml</value> * </parameter> * </ResourceParams> * </GlobalNamingResources> * * ... * <!-- Define the Tomcat Stand-Alone Service --> * <Service name="Tomcat-Standalone"> * <!-- Define the top level container in our container hierarchy --> * <Engine name="Standalone" defaultHost="localhost" debug="0"> * <Host name="localhost" debug="0" appBase="webapps" * unpackWARs="true" autoDeploy="true"> * ... * <Context path="/testjndi" docBase="/testjndi.war" debug="0" * reloadable="true" crossContext="true" privileged="true" useNaming="true"> * <Logger className="org.apache.catalina.logger.FileLogger" * prefix="localhost_jndi_log." suffix=".txt" * timestamp="true"/> * <ResourceLink name="hibernate/SessionFactory" * global="HibernateSessionFactory" * type="net.sf.hibernate.SessionFactory"/> * </Context> * </Host> * </Engine> * </Service> * */ public class JndiSessionFactoryImpl implements ObjectFactory { public static final String PATH_NAME = "pathname"; private static SessionFactory sf = null; private static Log log = null; static { try { log = LogFactory.getLog (JndiSessionFactoryImpl.class); } catch (LogConfigurationException e) { System.err.println ("Cannot get a LogFactory instance!"); log = new SimpleLog ("log"); } } public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws NamingException { RefAddr addr = ((Reference)obj).get (PATH_NAME); String content = null; log.info ("Initializes a Sessionfactory instance"); if (addr != null) content = (String)addr.getContent (); else log.error ("parameter " + PATH_NAME + " not found"); log.debug ("pathname : " + content); if (System.getProperty ("api.server.home") == null) log.error ("property \"api.server.home\" not found please initialize -Dapi.server.home with API server home."); // Initialize Hibernate configuration with hibernate.cfg.xml : log.info ("Read the hibernate.cfg.xml at : " + System.getProperty("api.server.home") + File.separator + content); if (sf == null) { try { File file = new File (System.getProperty("api.server.home") + "/" + content); sf = new Configuration ().configure (file).buildSessionFactory (); log.info ("Sessionfactory successfully initialize !!"); } catch (HibernateException e) { log.fatal ("Cannot get a SessionFactory instance", e); } } return sf; } } Tomcat Configuration : - put alls hibernate librairies in tomcat/common/lib - This class use a new property "api.server.home" which must contain the API server home. ==> Thus add -Dapi.server.home="%CATALINA_HOME%" in the file catalina.bat (or cataline.sh). - put hibernate.cfg.xml in tomcat/conf. - put all mappings and JAVA BEANs and the factory "JndiSessionFactoryImpl.class" in tomcat/common/classes - finally modify tomcat/conf/server.xml : <!-- Global JNDI resources --> <GlobalNamingResources> ... <Resource description="SessionFactory Resource" name="HibernateSessionFactory" auth="Container" type="net.sf.hibernate.SessionFactory" /> <ResourceParams name="HibernateSessionFactory"> <parameter> <name>factory</name> <value>JndiSessionFactoryImpl</value> </parameter> <parameter> <name>pathname</name> <value>conf/hibernate.cfg.xml</value> </parameter> </ResourceParams> </GlobalNamingResources> ... <Context path="/testjndi" docBase="/testjndi.war" debug="0" reloadable="true" crossContext="true" privileged="true" useNaming="true"> <Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_jndi_log." suffix=".txt" timestamp="true"/> <ResourceLink name="hibernate/SessionFactory" global="HibernateSessionFactory" type="net.sf.hibernate.SessionFactory"/> </Context> Note : I send to you a full example with the factory, my server.xml, catalina.bat, and a servlet. - First initialize Tomcat and run it : If the configuration is good, you should have some informations when the factory initialize the SessionFactory at startup. - After that execute the servlet. When I execute the servlet, I have this result in the browser : > sf = [EMAIL PROTECTED] > session : [EMAIL PROTECTED] > Cannot read data > net.sf.hibernate.MappingException: No persister for: bo.Reception at net.sf.hibernate.impl.SessionFactoryImpl.getPersister(SessionFactoryImpl.jav a:444) at net.sf.hibernate.impl.SessionImpl.getPersister(SessionImpl.java:2249) at net.sf.hibernate.impl.SessionImpl.doLoadByClass(SessionImpl.java:1739) at net.sf.hibernate.impl.SessionImpl.load(SessionImpl.java:1674) at TestJndi.doPost(TestJndi.java:63) at TestJndi.doGet(TestJndi.java:31) at javax.servlet.http.HttpServlet.service(HttpServlet.java:740) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Application FilterChain.java:247) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCh ain.java:193) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.ja va:260) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok eNext(StandardPipeline.java:643) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.ja va:191) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok eNext(StandardPipeline.java:643) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180 ) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok eNext(StandardPipeline.java:643) at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve. java:170) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok eNext(StandardPipeline.java:641) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172 ) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok eNext(StandardPipeline.java:641) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java :174) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok eNext(StandardPipeline.java:643) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:432) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConne ction(Http11Protocol.java:386) at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:534) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.jav a:530) at java.lang.Thread.run(Thread.java:536) Do you have any idees about this problem ? Can you help me to resolve it ? Best regards,
Jndi Tomcat.zip
Description: Zip compressed data