We migrated the database backing JIRA from SQL Server 2008 R2 to SQL Server 2014 by taking a SQL backup from the original server and restoring to the target server. We also changed the compatibility level on the database from SQL 2008 to SQL 2014, and had to mess around will column-level collation settings. But everything worked for a day or two afterward. Then our support license expired, and within a day or so our JIRA instance stopped working with a 500 error.
The logs on the JIRA server had a stack trace that eventually resolved to
Caused by: java.lang.IllegalArgumentException: getBoolean could not map the String 'N ' to Boolean type
at org.ofbiz.core.entity.GenericEntity.getBoolean(GenericEntity.java:414)
at com.atlassian.jira.application.OfBizApplicationRoleStore.isDefault(OfBizApplicationRoleStore.java:168)
at com.atlassian.jira.application.OfBizApplicationRoleStore.get(OfBizApplicationRoleStore.java:59)
at com.atlassian.jira.application.DefaultApplicationRoleManager$RoleLoader.lambda$load$0(DefaultApplicationRoleManager.java:688)
at com.atlassian.fugue.Option.map(Option.java:272)
at com.atlassian.jira.application.DefaultApplicationRoleManager$RoleLoader.load(DefaultApplicationRoleManager.java:682)
at com.atlassian.cache.memory.MemoryCacheManager$3$1.load(MemoryCacheManager.java:162)
at com.atlassian.cache.memory.DelegatingCache.lambda$get$0(DelegatingCache.java:158)
at com.atlassian.cache.memory.DelegatingCache.lambda$get$1(DelegatingCache.java:186)
at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4742)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2319)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2282)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2197)
at com.google.common.cache.LocalCache.get(LocalCache.java:3937)
at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4739)
at com.atlassian.cache.memory.DelegatingCache.get(DelegatingCache.java:173)
... 646 more
From there, Google brought me to https://developer.atlassian.com/static/javadoc/jira/latest/reference/com/atlassian/jira/application/OfBizApplicationRoleStore.html. Based on what that class seemed to be doing, I started looking through the SQL database for tables that had 'app' or 'role' in their name, and seemed to be related to permissions. I queried each table, looking for Boolean flags ('Y' and 'N').
I finally found the licenserolesgroup table, and the PRIMARY_GROUP column. Doing something like SELECT QUOTENAME(PRIMARY_GROUP) FROM licenserolesgroup showed the values all had a trailing space.
I tried the obvious: UPDATE licenserolesgroup SET PRIMARY_GROUP = RTRIM(PRIMARY_GROUP), but that didn't work.
The cause turned out to be that the PRIMARY_GROUP column is a NCHAR(2), so SQL Server will always pad the value with spaces. Looking back at the SQL 2008 instance, this column is a NCHAR(1) there, so something about the transition from one database version to another altered the datatype.
The fix was: ALTER TABLE licenserolesgroup ALTER COLUMN PRIMARY_GROUP nchar(1) null
Submitting this here in hopes of saving the next guy a couple hours of time debugging.