java.lang.RuntimeException: org.kuali.student.r2.common.exceptions.OperationFailedException: list size exceeds limit of 1

Kuali JIRA | Chris Mann | 3 years ago
  1. 0

    h1. Summary/Functional Impact When creating a rule statement that uses course codes, the user gets a stacktrace when entering a course code and clicking Preview Change if the course code is duplicated in CM. For example, adding either BSCI353 or PHYS131 to the Common Exam area of the Final Exam Matrix errors (throws an exception). The code appears to be searching for a single version-independent CLU ID for the desired course code and throws an exception when it finds more than one. -To give a bit more detail, the system needs to choose a clu version to assign to the exam matrix. It attempts to find any version that is in state Approved, Active, Retired, or Suspended. BSCI353 and PHYS131 have both Retired and Active clus in their version history, and so the code fails because it returns both versions.- -A BA should also look at this issue more closely. We believe the code needs to look at start and end term of the clu, since the clu may be retired/superseded in CM but the an end term is in the future. So the final exam should be associated with the retired or superseded version until the start term of the next version (the active version) takes effect.- -It's not enough to just choose the version with 'Active' state. For example, assume early in the Fall semester a new version of PHYS131 is approved with a Spring start date. A couple weeks later, the registrar decides to schedule final exams for the Fall semester course. In this case, the system should choose the 'Superseded' version with fall end term, not the new 'Active' version, since it begins in Spring.- This problem can be replicated on http://env2.ks.kuali.org/ with the latest version of the foundation code, using these courses. *Step to reproduce* - Log into env2 - Clicked on Manage Final Exam Matrix - Term = Fall, clicked the Show button - Was adding courses to Common Finals and all was working well - Then went to add PHYS131, clicked Add (screenshot attached) - Clicked Add Statement button - Chose Rule Statement Option, "Course must be <Course>" (screenshot attached) - In Course box typed in PHYS131, clicked the Preview Change button (screenshot attached) - Blew up and I received a stacktrace h1. Technical *Exception (full trace attached to ticket)* java.lang.RuntimeException: org.kuali.student.r2.common.exceptions.OperationFailedException: list size exceeds limit of 1 at org.kuali.student.lum.lu.ui.krms.util.CluInformationHelper.getCluInfoForCodeAndType(CluInformationHelper.java:326) at org.kuali.student.lum.lu.ui.krms.builder.CourseComponentBuilder.validate(CourseComponentBuilder.java:126) CluInformationHelper.getCluInfoForCodeAndType() line 314-320 (in FR1 tag) throws the above exception. Here is the code: {code:java} 314 - qbcBuilder.setPredicates(PredicateFactory.equal("officialIdentifier.code", code), 315 - PredicateFactory.in("state", CluSearchUtil.getApprovedStatesForClus().toArray()), 316 - PredicateFactory.in("luType.id", types.toArray())); 317 - //Perform the search for the clu. 318 - List<CluInfo> cluInfos = this.getCluService().searchForClus(qbcBuilder.build(), ContextUtils.getContextInfo()); 319 - CluInfo cluInfo = KSCollectionUtils.getOptionalZeroElement(cluInfos); {code} Line 315 calls CluSearchUtil.getApprovedStatesForClus() and returns a list with the following states: {code} public static List<String> getApprovedStatesForClus() { List<String> states = new ArrayList<String>(); states.add(DtoConstants.STATE_APPROVED); states.add(DtoConstants.STATE_ACTIVE); states.add(DtoConstants.STATE_RETIRED); states.add(DtoConstants.STATE_SUSPENDED); return states; } {code} However, line 319 expects only 0 or 1 result to be returned. The KSCollectionUtils.getOptionalZeroElement() method comment has: {code} * List has 1 element, return element. * List has 0 elements, return null. * else throw exception. {code} So we are getting an exception because the getApprovedStatesForClus() will always return 4 states (never 0 or 1). The code is failing when we try to add a course to the final exam matrix that has retired, suspended, and active clus in the DB. h1. Side note - This problem may may impact more than PYSC131 or BSCI353. I used the following SQL to find course that have both and Active and Retired previous version: {code:sql} SELECT * FROM ( SELECT i.cd AS cd , tab_to_string ( CAST ( COLLECT ( c.st ) AS t_varchar2_tab ) ) AS st FROM kslu_clu c JOIN kslu_clu_ident i ON ( c.OFFIC_CLU_ID = i.id ) WHERE c.LUTYPE_ID = 'kuali.lu.type.CreditCourse' GROUP BY i.cd ) WHERE st LIKE '%Retired%Active' OR st LIKE '%Active%Retired' {code} If you are on Oracle 10g, you need to install this function and type before the above SQL would run: {code:sql} -- use collect instead: http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php#collect -- You need to install this type and function to convert collections to strings -- CREATE OR REPLACE TYPE t_varchar2_tab AS TABLE OF VARCHAR2(4000); / @delimiter ++; CREATE OR REPLACE FUNCTION tab_to_string (p_varchar2_tab IN t_varchar2_tab, p_delimiter IN VARCHAR2 DEFAULT ',') RETURN VARCHAR2 IS l_string VARCHAR2(32767); BEGIN FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP IF i != p_varchar2_tab.FIRST THEN l_string := l_string || p_delimiter; END IF; l_string := l_string || p_varchar2_tab(i); END LOOP; RETURN l_string; END tab_to_string; {code} Cross-reference for tracking: https://jira.kuali.org/browse/KSENROLL-12560 https://issues.umd.edu/browse/UMDENR-533

    Kuali JIRA | 3 years ago | Chris Mann
    java.lang.RuntimeException: org.kuali.student.r2.common.exceptions.OperationFailedException: list size exceeds limit of 1
  2. 0

    h1. Summary/Functional Impact When creating a rule statement that uses course codes, the user gets a stacktrace when entering a course code and clicking Preview Change if the course code is duplicated in CM. For example, adding either BSCI353 or PHYS131 to the Common Exam area of the Final Exam Matrix errors (throws an exception). The code appears to be searching for a single version-independent CLU ID for the desired course code and throws an exception when it finds more than one. -To give a bit more detail, the system needs to choose a clu version to assign to the exam matrix. It attempts to find any version that is in state Approved, Active, Retired, or Suspended. BSCI353 and PHYS131 have both Retired and Active clus in their version history, and so the code fails because it returns both versions.- -A BA should also look at this issue more closely. We believe the code needs to look at start and end term of the clu, since the clu may be retired/superseded in CM but the an end term is in the future. So the final exam should be associated with the retired or superseded version until the start term of the next version (the active version) takes effect.- -It's not enough to just choose the version with 'Active' state. For example, assume early in the Fall semester a new version of PHYS131 is approved with a Spring start date. A couple weeks later, the registrar decides to schedule final exams for the Fall semester course. In this case, the system should choose the 'Superseded' version with fall end term, not the new 'Active' version, since it begins in Spring.- This problem can be replicated on http://env2.ks.kuali.org/ with the latest version of the foundation code, using these courses. *Step to reproduce* - Log into env2 - Clicked on Manage Final Exam Matrix - Term = Fall, clicked the Show button - Was adding courses to Common Finals and all was working well - Then went to add PHYS131, clicked Add (screenshot attached) - Clicked Add Statement button - Chose Rule Statement Option, "Course must be <Course>" (screenshot attached) - In Course box typed in PHYS131, clicked the Preview Change button (screenshot attached) - Blew up and I received a stacktrace h1. Technical *Exception (full trace attached to ticket)* java.lang.RuntimeException: org.kuali.student.r2.common.exceptions.OperationFailedException: list size exceeds limit of 1 at org.kuali.student.lum.lu.ui.krms.util.CluInformationHelper.getCluInfoForCodeAndType(CluInformationHelper.java:326) at org.kuali.student.lum.lu.ui.krms.builder.CourseComponentBuilder.validate(CourseComponentBuilder.java:126) CluInformationHelper.getCluInfoForCodeAndType() line 314-320 (in FR1 tag) throws the above exception. Here is the code: {code:java} 314 - qbcBuilder.setPredicates(PredicateFactory.equal("officialIdentifier.code", code), 315 - PredicateFactory.in("state", CluSearchUtil.getApprovedStatesForClus().toArray()), 316 - PredicateFactory.in("luType.id", types.toArray())); 317 - //Perform the search for the clu. 318 - List<CluInfo> cluInfos = this.getCluService().searchForClus(qbcBuilder.build(), ContextUtils.getContextInfo()); 319 - CluInfo cluInfo = KSCollectionUtils.getOptionalZeroElement(cluInfos); {code} Line 315 calls CluSearchUtil.getApprovedStatesForClus() and returns a list with the following states: {code} public static List<String> getApprovedStatesForClus() { List<String> states = new ArrayList<String>(); states.add(DtoConstants.STATE_APPROVED); states.add(DtoConstants.STATE_ACTIVE); states.add(DtoConstants.STATE_RETIRED); states.add(DtoConstants.STATE_SUSPENDED); return states; } {code} However, line 319 expects only 0 or 1 result to be returned. The KSCollectionUtils.getOptionalZeroElement() method comment has: {code} * List has 1 element, return element. * List has 0 elements, return null. * else throw exception. {code} So we are getting an exception because the getApprovedStatesForClus() will always return 4 states (never 0 or 1). The code is failing when we try to add a course to the final exam matrix that has retired, suspended, and active clus in the DB. h1. Side note - This problem may may impact more than PYSC131 or BSCI353. I used the following SQL to find course that have both and Active and Retired previous version: {code:sql} SELECT * FROM ( SELECT i.cd AS cd , tab_to_string ( CAST ( COLLECT ( c.st ) AS t_varchar2_tab ) ) AS st FROM kslu_clu c JOIN kslu_clu_ident i ON ( c.OFFIC_CLU_ID = i.id ) WHERE c.LUTYPE_ID = 'kuali.lu.type.CreditCourse' GROUP BY i.cd ) WHERE st LIKE '%Retired%Active' OR st LIKE '%Active%Retired' {code} If you are on Oracle 10g, you need to install this function and type before the above SQL would run: {code:sql} -- use collect instead: http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php#collect -- You need to install this type and function to convert collections to strings -- CREATE OR REPLACE TYPE t_varchar2_tab AS TABLE OF VARCHAR2(4000); / @delimiter ++; CREATE OR REPLACE FUNCTION tab_to_string (p_varchar2_tab IN t_varchar2_tab, p_delimiter IN VARCHAR2 DEFAULT ',') RETURN VARCHAR2 IS l_string VARCHAR2(32767); BEGIN FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP IF i != p_varchar2_tab.FIRST THEN l_string := l_string || p_delimiter; END IF; l_string := l_string || p_varchar2_tab(i); END LOOP; RETURN l_string; END tab_to_string; {code} Cross-reference for tracking: https://jira.kuali.org/browse/KSENROLL-12560 https://issues.umd.edu/browse/UMDENR-533

    Kuali JIRA | 3 years ago | Chris Mann
    java.lang.RuntimeException: org.kuali.student.r2.common.exceptions.OperationFailedException: list size exceeds limit of 1
  3. Speed up your debug routine!

    Automated exception search integrated into your IDE

    Not finding the right solution?
    Take a tour to get the most out of Samebug.

    Tired of useless tips?

    Automated exception search integrated into your IDE

    Root Cause Analysis

    1. java.lang.RuntimeException

      org.kuali.student.r2.common.exceptions.OperationFailedException: list size exceeds limit of 1

      at org.kuali.student.lum.lu.ui.krms.util.CluInformationHelper.getCluInfoForCodeAndType()
    2. org.kuali.student
      CourseComponentBuilder.validate
      1. org.kuali.student.lum.lu.ui.krms.util.CluInformationHelper.getCluInfoForCodeAndType(CluInformationHelper.java:326)
      2. org.kuali.student.lum.lu.ui.krms.builder.CourseComponentBuilder.validate(CourseComponentBuilder.java:126)
      2 frames