Details
-
Bug
-
Resolution: Fixed
-
High
Description
Under certain conditions, fetching the status of a Workbox notification can OOME the server.
This was observed on OD instance rdcgroup.atlassian.net via ZOOME (link to OOME details
The truncated stack trace that blows the stack out and causes the OOME is:
at java.lang.OutOfMemoryError.<init>()V (OutOfMemoryError.java:25) at java.util.Arrays.copyOf([CI)[C (Arrays.java:2882) [...] at org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.getObject(Ljava/lang/String;)Ljava/lang/Object; (DelegatingResultSet.java:328) at net.java.ao.EntityManager.find(Ljava/lang/Class;Ljava/lang/String;Lnet/java/ao/Query;)[Lnet/java/ao/RawEntity; (EntityManager.java:777) at net.java.ao.EntityManager.find(Ljava/lang/Class;Lnet/java/ao/Query;)[Lnet/java/ao/RawEntity; (EntityManager.java:675) at com.atlassian.activeobjects.internal.EntityManagedActiveObjects.find(Ljava/lang/Class;Lnet/java/ao/Query;)[Lnet/java/ao/RawEntity; (EntityManagedActiveObjects.java:181) at com.atlassian.activeobjects.osgi.TenantAwareActiveObjects.find(Ljava/lang/Class;Lnet/java/ao/Query;)[Lnet/java/ao/RawEntity; (TenantAwareActiveObjects.java:335) [...] at com.atlassian.mywork.host.dao.ao.AONotificationDao.getItemStatus(Lcom/atlassian/mywork/model/Notification;)Lcom/atlassian/mywork/model/Status; (AONotificationDao.java:71) at com.atlassian.mywork.host.dao.ao.AONotificationDao.create(Lcom/atlassian/mywork/model/Notification;Ljava/util/Date;)Lcom/atlassian/mywork/model/Notification; (AONotificationDao.java:60) at com.atlassian.mywork.host.dao.ao.AONotificationDao.create(Lcom/atlassian/mywork/model/Notification;)Lcom/atlassian/mywork/model/Notification; (AONotificationDao.java:52)
Looking at the calling code in AONotificationDao#getItemStatus, we see:
for (AONotification other : ao.find(AONotification.class, select().where("USER = ? AND GLOBAL_ID = ?", getStringKeyForUsername(notification.getUser()), globalId))) { return other.getStatus(); }
Here we have a for loop that returns from the method on the first loop iteration. However, the call to ao.find is unbounded, and so potentially can return a very large result set. It doesn't matter that the for loop only wants the first one.
It appears that if a given Notification has a large number of associated AONotifications for that user, then memory usaqe will be high, and may trigger an OOME.
This method needs to be rewritten to limit the size of the result set to a single item.