I am writing this to document two resolutions to a problem I have found while running EntityManager within a servlet container on Windows and the way that PersistenceXmlLoader.java within EntityManager searches for persistence_1_0.xsd (NOT persistence.xml).
This is specific to windows, and its file locking behaviour.
Environment: Windows XP SP2, JDK 1.5.0_05, Hibernate-everything at 3.2.0GA, Tomcat 5.5.12
Problem: When undeploying a webapp that uses EntityManager, the EntityManager.jar within the webapp is locked and cannot be deleted. This results in a failure to undeploy the webapp. If the servlet container (Tomcat) is shut down, the lock is released and the jar can be deleted.
PersistenceXmlLoader.java involvement: This class appears to be involved in searching for persistence_1_0.xsd on the classpath using a url. However it does not set caching to false before doing the configURL.openStream() call. This means that all the jars that it opens get locked by windows.
Root cause: Jar access using a URL with caching enabled. See:
http://forum.springframework.org/archive/index.php/t-19516.html
http://tomcat.apache.org/faq/windows.html#lock
Resolution #1:
Copy persistence_1_0.xsd out of EntityManager.jar, and place it in WEB-INF/classes. This should cause the xml loading code to find it first, and not search any of the jars.
Resolution #2:
Make sure the following code is ran before instantiating the EntityManager (can use ServletContextListener for example):
Code:
try
{
if(System.getProperty("os.name").contains("Windows"))
new URL("http://This-is-just-to-get-the-URLConnection").openConnection().setDefaultUseCaches(false);
}
catch (IOException e)
{
e.printStackTrace();
}
This is a vm-wide setting so it will affect all url connections. Why isn't this code cleaner? See:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4851466
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4405789
I hope this helps anyone else in the same situation!
Maybe the code could also be in EntityManager itself? I'll leave that to the dev team.
Jim