[
http://jira.nuxeo.org/browse/NXP-3017?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=48246#action_48246
]
Olivier Grisel commented on NXP-3017:
-------------------------------------
Proposed patch against the 5.1 branch:
diff --git
a/nuxeo-platform-directory-facade/src/main/java/org/nuxeo/ecm/platform/directory/ejb/DirectoryManagerBean.java
b/nuxeo-platform-directory-facade/src/main/java/org/nuxeo/ecm/platform/directory/ejb/DirectoryManagerBean.java
---
a/nuxeo-platform-directory-facade/src/main/java/org/nuxeo/ecm/platform/directory/ejb/DirectoryManagerBean.java
+++
b/nuxeo-platform-directory-facade/src/main/java/org/nuxeo/ecm/platform/directory/ejb/DirectoryManagerBean.java
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
+ * (C) Copyright 2006-2009 Nuxeo SAS (http://nuxeo.com/) and contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
@@ -31,6 +31,7 @@
import javax.ejb.PrePassivate;
import javax.ejb.Remote;
import javax.ejb.Stateful;
+import javax.ejb.Remove;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -48,33 +49,31 @@
/**
* @author <a href="mailto:[email protected]">George Lefter</a>
- *
+ * @author <a href="mailto:[email protected]">Olivier Grisel</a>
*/
@Stateful
-// XXX OG+GR: this bean is definitely not thread-safe.
-// think of it while removing the jboss specific annotation
@SerializedConcurrentAccess
@Remote(DirectoryManager.class)
@Local(DirectoryManager.class)
public class DirectoryManagerBean implements DirectoryManager {
- @SuppressWarnings("unused")
+
private static final Log log =
LogFactory.getLog(DirectoryManagerBean.class);
- private static final Map<Long, Session> sessionMap = new HashMap<Long,
Session>();
+ // do not forget to make the following maps thread-safe with
+ // Collections.synchronizedMap if the @SerializedConcurrentAccess
annotation
+ // is ever removed
- private static final Map<Long, String> sessionDirectoryNames = new
HashMap<Long, String>();
+ private final Map<Long, Session> sessionMap = new HashMap<Long,
Session>();
+
+ private final Map<Long, String> sessionDirectoryNames = new HashMap<Long,
String>();
+
+ private final AtomicLong sessionIdCounter = new AtomicLong(0);
private transient DirectoryService directoryService;
- private AtomicLong sessionIdCounter = new AtomicLong(0);
-
@PostActivate
@PostConstruct
public void initialize() {
- // UserService userService = (UserService) Framework.getRuntime()
- // .getComponent(UserService.NAME);
- // userManager = userService.getUserManager();
- // sessionMap = new HashMap<Long, Session>();
getService();
}
@@ -82,21 +81,31 @@
if (directoryService == null) {
directoryService =
Framework.getLocalService(DirectoryService.class);
}
-
return directoryService;
}
@PrePassivate
- public void cleanup() {
- directoryService = null;
+ @Remove
+ public void cleanupOpenSessions() {
+ // close any open directory sessions upon passivation or removal
+ // the sessionMap should be empty anyway since the client code should
+ // only use short lived directory clients in try / finally blocks
+ if (!sessionMap.isEmpty()) {
+ log.warn(String.format(
+ "about to close directory %d directory sessions:"
+ + " client code should not keep open directory
session",
+ sessionMap.size()));
+ }
for (Session session : sessionMap.values()) {
try {
session.close();
} catch (DirectoryException e) {
- // ignore
+ log.error("failed to close directory session properly: "
+ + e.getMessage(), e);
}
}
sessionMap.clear();
+ sessionDirectoryNames.clear();
}
private Session getSession(long sessionId) throws DirectoryException {
@@ -108,7 +117,7 @@
"Could not find directory name while rebuilding
session with id: "
+ sessionId);
}
- session = directoryService.open(directoryName);
+ session = getService().open(directoryName);
}
return session;
}
@@ -330,26 +339,26 @@
public String getDirectoryIdField(String directoryName)
throws DirectoryException {
- return directoryService.getDirectoryIdField(directoryName);
+ return getService().getDirectoryIdField(directoryName);
}
public String getDirectoryPasswordField(String directoryName)
throws DirectoryException {
- return directoryService.getDirectoryPasswordField(directoryName);
+ return getService().getDirectoryPasswordField(directoryName);
}
public void registerDirectory(String directoryName, DirectoryFactory
factory) {
- directoryService.registerDirectory(directoryName, factory);
+ getService().registerDirectory(directoryName, factory);
}
public void unregisterDirectory(String directoryName,
DirectoryFactory factory) {
- directoryService.unregisterDirectory(directoryName, factory);
+ getService().unregisterDirectory(directoryName, factory);
}
public String getParentDirectoryName(String directoryName)
throws DirectoryException {
- return directoryService.getParentDirectoryName(directoryName);
+ return getService().getParentDirectoryName(directoryName);
}
}
> Fix DirectoryManagerBean bad concurrency management when closing sessions
> -------------------------------------------------------------------------
>
> Key: NXP-3017
> URL: http://jira.nuxeo.org/browse/NXP-3017
> Project: Nuxeo Enterprise Platform
> Issue Type: Bug
> Components: Directory
> Affects Versions: 5.1.6, 5.2 M3
> Reporter: Olivier Grisel
> Assignee: Olivier Grisel
> Priority: Major
> Fix For: 5.1.7, 5.2 M4
>
>
> When using pages with heavy directory usage (such as forms with many
> vocabulary access) with several concurrent users one can get the following
> crash:
> Caused by: org.nuxeo.ecm.directory.DirectoryException: Could not find
> directory name while rebuilding session with id: 1
> at
> org.nuxeo.ecm.platform.directory.ejb.DirectoryManagerBean.getSession(DirectoryManagerBean.java:107)
> at
> org.nuxeo.ecm.platform.directory.ejb.DirectoryManagerBean.close(DirectoryManagerBean.java:127)
> at sun.reflect.GeneratedMethodAccessor150.invoke(Unknown Source)
> This is due to the fact that the sessions maps are static while the session
> counter is not. A proposed patch will be attached in comments.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.nuxeo.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
_______________________________________________
ECM-tickets mailing list
[email protected]
http://lists.nuxeo.com/mailman/listinfo/ecm-tickets
