Uploaded image for project: 'Kuali Rice Development'
  1. Kuali Rice Development
  2. KULRICE-7263

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

    Details

    • Type: Bug Fix
    • Status: Closed
    • Priority: 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
    • 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)

        Attachments

          Activity

          Hide
          gilesp 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
          gilesp 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
          ewestfal 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
          ewestfal 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
          ewestfal 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
          ewestfal 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
          gilesp Peter Giles (Inactive) added a comment -

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

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

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

          Show
          kbtaylor 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:
              gilesp Peter Giles (Inactive)
              Reporter:
              jkeller Jonathan Keller
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: