Kuali Rice Development
  1. Kuali Rice Development
  2. KULRICE-7263

Passing Collections.emptyMap() as role qualifier causes failures in KIM

    Details

    • Type: Bug Fix Bug Fix
    • Status: Closed Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 2.0.1
    • Fix Version/s: 2.0.2
    • Component/s: Development
    • Security Level: Public (Public: Anyone can view)
    • Labels:
      None
    • Similar issues:
      KULRICE-12842RoleDaoJdbc generating wrong SQL when null qualifier passed in.
      KULRICE-2353KIM Role Service Test
      KULRICE-12836Role qualifiers lost on role maintenance document
      KULRICE-4886Role qualifiers values cannot include whitespace
      KULRICE-1470KIM Qualified Role with multiple qualifications
      KULRICE-4153Inactive qualifiers cause problems on existing roles
      KULRICE-7082KIM role document not handling missing qualifiers on role members
      KULRICE-1489KIM needs to support role qualifier validation
      KULRICE-4405Adding check to role qualifiers in ResponsibilityService
      KULRICE-8513Role document blows up if the attribute definition id of a qualifier contains a hyphen
    • Rice Module:
      KNS, KIM
    • KAI Review Status:
      Not Required
    • KTI Review Status:
      Not Required

      Description

      It appears that, in some cases, Collections.emptyMap() is being passed as the role qualifier instead of a null. The code below is from the KNS class DocumentAuthorizerBase. This appears to be causing a problem when attempting to cache the results of permission and role checks as you can see in the stack trace below:

      DocumentAuthorizerBase.java
          public final boolean canInitiate(String documentTypeName, Person user) {
              String nameSpaceCode = KRADConstants.KUALI_RICE_SYSTEM_NAMESPACE;
              Map<String, String> permissionDetails = new HashMap<String, String>();
              permissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, documentTypeName);
              return getPermissionService().isAuthorizedByTemplate(user.getPrincipalId(), nameSpaceCode,
                      KimConstants.PermissionTemplateNames.INITIATE_DOCUMENT, permissionDetails,
                      Collections.<String, String>emptyMap());
          }
      
          [junit] 2012-05-09 18:00:29,233 [main] u:/d:9212 WARN  org.kuali.rice.kim.impl.role.RoleServiceImpl :: Not able to retrieve RoleTypeService from remote system for role Id: 92
          [junit] java.lang.ClassCastException: java.util.Collections$EmptyMap cannot be cast to java.lang.Comparable
          [junit] 	at java.util.Collections.sort(Collections.java:121)
          [junit] 	at org.kuali.rice.core.api.cache.CacheKeyUtils.key(CacheKeyUtils.java:71)
          [junit] 	at $Proxy107.principalHasRole(Unknown Source)
          [junit] 	at org.kuali.kfs.fp.identity.CashReceiptInitiatorDerivedRoleTypeServiceImpl.hasRoleMembership(CashReceiptInitiatorDerivedRoleTypeServiceImpl.java:82)
          [junit] 	at org.kuali.kfs.fp.identity.CashReceiptInitiatorDerivedRoleTypeServiceImpl.principalMemberOfSysUsers(CashReceiptInitiatorDerivedRoleTypeServiceImpl.java:59)
          [junit] 	at org.kuali.kfs.fp.identity.CashReceiptInitiatorDerivedRoleTypeServiceImpl.hasDerivedRole(CashReceiptInitiatorDerivedRoleTypeServiceImpl.java:44)
          [junit] 	at org.kuali.rice.kim.impl.role.RoleServiceImpl.principalHasRole(RoleServiceImpl.java:1106)
          [junit] 	at org.kuali.rice.kim.impl.role.RoleServiceImpl.principalHasRole(RoleServiceImpl.java:498)
          [junit] 	at org.kuali.rice.kim.impl.permission.PermissionServiceImpl.isAuthorizedByTemplate(PermissionServiceImpl.java:172)
          [junit] 	at org.kuali.rice.kns.document.authorization.DocumentAuthorizerBase.canInitiate(DocumentAuthorizerBase.java:143)
          [junit] 	at org.kuali.rice.krad.service.impl.DocumentServiceImpl.getNewDocument(DocumentServiceImpl.java:506)
          [junit] 	at org.kuali.rice.krad.service.impl.DocumentServiceImpl.getNewDocument(DocumentServiceImpl.java:469)
          [junit] 	at org.kuali.kfs.sys.service.IsDebitTestUtils.getDocument(IsDebitTestUtils.java:110)
          [junit] 	at org.kuali.kfs.fp.document.validation.impl.CashReceiptDocumentRuleTest.testIsDebit_liability_zeroAmount(CashReceiptDocumentRuleTest.java:191)
      

      (stripped reflection trace elements)

        Activity

        Hide
        Peter Giles (Inactive) added a comment -

        Well spotted Eric, I should have noticed that the line number in the stack trace for CacheKeyUtils.key was from the Collection version!! I should be able to fix this up after the KTI.

        Show
        Peter Giles (Inactive) added a comment - Well spotted Eric, I should have noticed that the line number in the stack trace for CacheKeyUtils.key was from the Collection version!! I should be able to fix this up after the KTI.
        Hide
        Eric Westfall added a comment -

        It's interesting to me that it is even able to do this. I'm not sure what the SPEL is doing but apparently it's able to invoke a method on CacheKeyUtils which takes a Collection and pass a Map to it. Even when using reflection I would think you would get an error when trying to invoke a method with an incorrect type at runtime. In terms of why this is happening on these servers, maybe whatever weirdness SPEL is doing is being handled differently on OpenJDK which is resulting in the dispatch to the appropriate overloaded method to go horribly wrong.

        Show
        Eric Westfall added a comment - It's interesting to me that it is even able to do this. I'm not sure what the SPEL is doing but apparently it's able to invoke a method on CacheKeyUtils which takes a Collection and pass a Map to it. Even when using reflection I would think you would get an error when trying to invoke a method with an incorrect type at runtime. In terms of why this is happening on these servers, maybe whatever weirdness SPEL is doing is being handled differently on OpenJDK which is resulting in the dispatch to the appropriate overloaded method to go horribly wrong.
        Hide
        Eric Westfall added a comment -

        Actually, after looking at what's happening here, it looks like Spring uses it's "TypeConverters" to attempt to coerce a given type to the target type (see ReflectionHelper.convertArguments in Spring). So my guess is that the type converter in this case is converting the given map to a single element list containing that map as the only element in the list.

        Then I'm guessing that however the SPEL is attempting to resolve the static method with name "key" is working differently under Oracle JDK vs. OpenJDK which is why this is affecting us on the OpenJDK-based servers (just a guess on that, I'm too lazy to actually try and prove it since I don't have openjdk installed on my machine

        Show
        Eric Westfall added a comment - Actually, after looking at what's happening here, it looks like Spring uses it's "TypeConverters" to attempt to coerce a given type to the target type (see ReflectionHelper.convertArguments in Spring). So my guess is that the type converter in this case is converting the given map to a single element list containing that map as the only element in the list. Then I'm guessing that however the SPEL is attempting to resolve the static method with name "key" is working differently under Oracle JDK vs. OpenJDK which is why this is affecting us on the OpenJDK-based servers (just a guess on that, I'm too lazy to actually try and prove it since I don't have openjdk installed on my machine
        Hide
        Peter Giles (Inactive) added a comment -

        As Eric suggested, renamed the method to mapKey and changed usages to match.

        Show
        Peter Giles (Inactive) added a comment - As Eric suggested, renamed the method to mapKey and changed usages to match.
        Hide
        Kristina Taylor (Inactive) added a comment -

        This seems to have solved KC's problem as well, even though we are running Oracle JDK6.

        Show
        Kristina Taylor (Inactive) added a comment - This seems to have solved KC's problem as well, even though we are running Oracle JDK6.

          People

          • Assignee:
            Peter Giles (Inactive)
            Reporter:
            Jonathan Keller
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Structure Helper Panel