LDAP directory fails to synchronise with error "Error occurred while refreshing the cache for directory [ XXXXX ]. java.lang.IllegalArgumentException: Passed List had more than one value."
Version observed | 6.0.5 |
---|---|
Affects | Embedded Crowd, LDAP Directory |
Bug Report |
Symptoms
- LDAP directory synchronisation fails
- The following appears in the
atlassian-jira.log
:
2014-03-05 06:30:15,246 QuartzScheduler_Worker-1 INFO [atlassian.crowd.directory.DbCachingRemoteDirectory] failed synchronisation complete for directory [ 10000 ] in [ 12ms ]
2014-03-05 06:30:15,667 QuartzScheduler_Worker-1 ERROR [atlassian.crowd.directory.DbCachingDirectoryPoller] Error occurred while refreshing the cache for directory [ 10000 ].
java.lang.IllegalArgumentException: Passed List had more than one value.
at org.ofbiz.core.entity.EntityUtil.getOnly(EntityUtil.java:62)
at com.atlassian.jira.crowd.embedded.ofbiz.OfBizInternalMembershipDao.isDirectMember(OfBizInternalMembershipDao.java:85)
at com.atlassian.jira.crowd.embedded.ofbiz.OfBizInternalMembershipDao.isGroupDirectMember(OfBizInternalMembershipDao.java:80)
at com.atlassian.jira.crowd.embedded.ofbiz.OfBizDelegatingMembershipDao.isGroupDirectMember(OfBizDelegatingMembershipDao.java:70)
at com.atlassian.crowd.directory.AbstractInternalDirectory.isGroupDirectGroupMember(AbstractInternalDirectory.java:711)
at com.atlassian.crowd.directory.AbstractInternalDirectory.removeGroupFromGroup(AbstractInternalDirectory.java:768)
at com.atlassian.crowd.directory.DbCachingRemoteChangeOperations.removeGroupMembershipsForGroup(DbCachingRemoteChangeOperations.java:879)
at com.atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations.syncGroupMembersForGroup(DirectoryCacheImplUsingChangeOperations.java:145)
at com.atlassian.crowd.directory.ldap.cache.AbstractCacheRefresher.synchroniseMemberships(AbstractCacheRefresher.java:149)
at com.atlassian.crowd.directory.ldap.cache.AbstractCacheRefresher.synchroniseAll(AbstractCacheRefresher.java:84)
at com.atlassian.crowd.directory.ldap.cache.UsnChangedCacheRefresher.synchroniseAll(UsnChangedCacheRefresher.java:124)
at com.atlassian.crowd.directory.DbCachingRemoteDirectory.synchroniseCache(DbCachingRemoteDirectory.java:644)
at com.atlassian.crowd.manager.directory.DirectorySynchroniserImpl.synchronise(DirectorySynchroniserImpl.java:63)
at com.atlassian.crowd.directory.DbCachingDirectoryPoller.pollChanges(DbCachingDirectoryPoller.java:50)
at com.atlassian.crowd.manager.directory.monitor.poller.DirectoryPollerJob.execute(DirectoryPollerJob.java:34)
at org.quartz.core.JobRunShell.run(JobRunShell.java:195)
Cause
User has duplicate membership for a group in the same directory
The most common reason is that the information in the database is inconsistent resulting in one or more users having duplicate membership information for the same group within the same directory. In that case, the logs show the exception "Passed List had more than one value" for the method "com.atlassian.jira.crowd.embedded.ofbiz.OfBizInternalMembershipDao.isDirectMember".
java.lang.IllegalArgumentException: Passed List had more than one value.
at org.ofbiz.core.entity.EntityUtil.getOnly(EntityUtil.java:62)
at com.atlassian.jira.crowd.embedded.ofbiz.OfBizInternalMembershipDao.isDirectMember(OfBizInternalMembershipDao.java:85)
...
Resolution
The recommended way to resolve the problem is to disable the affected LDAP directory and enable it again. This will re-create the user to group mappings for the affected directory.
Workaround
This workaround is advised only if you do not wish to disable and re-enable the LDAP Directory from the JIRA administration interface. This could be because you have LDAP users mapped to local (JIRA internal) groups, which are removed when you disable the LDAP directory.
Always back up your data before performing any modification to the database. If possible, try your modifications on a test server.
Identify the duplicate database entries by executing the following SQL command:
PostgreSQL database:SELECT directory_id || ', ' || lower_parent_name || ', ' || child_name AS "directory_id, lower_parent_name, child_name", COUNT(id) FROM cwd_membership GROUP BY directory_id || ', ' || lower_parent_name || ', ' || child_name HAVING COUNT(ID) > 1;
Microsoft SQL Server:
SELECT cast(directory_id as varchar) + ', ' + lower_parent_name + ', ' + child_name AS "directory_id, lower_parent_name, child_name" , COUNT(id) FROM jiraschema.cwd_membership GROUP BY cast(directory_id as varchar) + ', ' + lower_parent_name + ', ' + child_name HAVING COUNT(ID) > 1;
Please replace "jiraschema" with the correct schema from your database.
For each of the returned mappings, identify the duplicate rows using the following query, substituting values of <DIRECTORY_ID>, <LOWER_PARENT_NAME> and <CHILD_NAME> with the result from previous query:
SELECT id, directory_id, lower_parent_name, child_name FROM cwd_membership WHERE directory_id = <DIRECTORY_ID> AND lower_parent_name = '<LOWER_PARENT_NAME>' AND child_name = '<CHILD_NAME>';
and delete one of the duplicate rows from the database using the following query, substituting the value of <ID> from the above query:DELETE FROM cwd_membership WHERE id = <ID>;
- Start a synchronisation for the LDAP directory from the JIRA interface.