I am writing a Bamboo Notification Plugin. I have the NotificationType, NotoficationListener and Notification classes defined. In the listener I cannot get the notificationRules. I get the error below.
Caused by: net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed
I can't seem to do anything that would require bamboo to access data in the database. I am doing this in SDK 3.7.2. Should I be importing something in my plugin.xml or my pom.xml file that I am not already doing?
Does anyone have a working Notification Plugin for an example?
atlassian-plugin.xml
<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.name}" plugins-version="2"> <plugin-info> <description>${project.description}</description> <version>${project.version}</version> <vendor name="${project.organization.name}" url="${project.organization.url}" /> </plugin-info> <!-- internationalize your plugin --> <resource type="i18n" name="txdps.bamboo language" location="english" /> <notificationType key="deployStageCompleted.allBuilds" name="Any Completed Deploy Stages" class="txdps.bamboo.DeployNotificationType" weight="10"> <description>Any Deploy Completed Stages</description> <scope>chain</scope> </notificationType> <bambooEventListener key="completedDeployStageNotificationEventListener" name="Completed Deploy Stage Event Notification Listener" class="txdps.bamboo.DeployNotificationListener"> <description>something </description> </bambooEventListener> </atlassian-plugin>
DeployNotificationListener.java
@ThreadSafe public class DeployNotificationListener extends AbstractNotificationEventListener<BuildStateResultEvent> { private ResultsSummaryManager resultsSummaryManager; public DeployNotificationListener() { super(BuildStateResultEvent.class, Sets.<Class<? extends NotificationType>> newHashSet(DeployNotificationType.class)); } @Override public void handleEvent(BuildStateResultEvent event, Plan plan) { Notification myNotification = new DeployNotification(); myNotification.setEvent(event); BuildResultsSummary resultsSummary = resultsSummaryManager .getResultsSummary(event.getPlanResultKey(), BuildResultsSummary.class, ResultDataRead.EAGER); for (NotificationRule rule : getNotificationRules(plan, event)) { NotificationRecipient recipient = rule.getNotificationRecipient(); if (recipient != null) { myNotification.addRecipient(recipient); } } notificationDispatcher.dispatchNotifications(myNotification); } public void setResultsSummaryManager( ResultsSummaryManager resultsSummaryManager) { this.resultsSummaryManager = resultsSummaryManager; } }
The code throws the exception here:
for (NotificationRule rule : getNotificationRules(plan, event)) { NotificationRecipient recipient = rule.getNotificationRecipient(); if (recipient != null) { myNotification.addRecipient(recipient); } }
Shortened StackTrace:
2011-12-06 16:41:04,363 INFO AtlassianEvent::0-BAM::EVENTS:pool-1-thread-9 DeployNotificationListener resultsSummary.getLifeCycleState().getValue(): Finished 2011-12-06 16:41:04,366 ERROR AtlassianEvent::0-BAM::EVENTS:pool-1-thread-9 LazyInitializer Exception initializing proxy net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed at com.atlassian.bamboo.notification.NotificationManagerImpl.getNotificationRules(NotificationManagerImpl.java:143) at $Proxy166.getNotificationRules(Unknown Source) at com.atlassian.bamboo.notification.AbstractNotificationEventListener.getNotificationRules(AbstractNotificationEventListener.java:73) at txdps.bamboo.DeployNotificationListener.handleEvent(DeployNotificationListener.java:65)
Community moderators have prevented the ability to post new answers.
Hi Mark,
Your code is trying to access the database but the database session has been closed. Originally the event listeners had magic interceptors to ensure the session was there, but these dont work for plugins 2 plugins. So, you will need to manually put your code inside a transaction. You can use SAL's transaction template:
@Override public void handleEvent(BuildStateResultEvent event, Plan plan) { transactionTemplate.execute(new TransactionCallback<Object>() { @Override public Object doInTransaction() { // your code goes here... return null; } }); }
You will also need to import the TransactionTemplate in your atlassian-plugin.xml
<component-import key="transactionTemplate" name="Hibernate Transaction Template" interface="com.atlassian.sal.api.transaction.TransactionTemplate"> <description>Component that provides a hibernate transaction</description> </component-import>
Cheers,
Brydie
Hey Rudy,
Thanks for replying! Yea we're alreading implementing that interface directly rather than the abstract class. We've extended one of the Atlassian events and then published it ourselves inside a task to try to create a notification task and I'm starting to think that's why we can't get the session to work.
We were able to get the NotificationRules fine when we were using the standard event that's fired at the end of a stage. Guess it's back to the drawing board unless anyone thinks what we've done should work too.
ContinuousDeliveryNotificationEvent extends the BuildCompletedEvent (somewhat arbitrarily) so I was kinda hoping it would just work with the existing notification framework.
Anyone believe this should work or know of another way we can access the NotificationRules from our EventListener (or task).
Thanks for your help,
Matt
Here's the code from our NotificationTask that publishes the event:
@Override public TaskResult execute(final TaskContext taskContext) { buildLogger = taskContext.getBuildLogger(); BuildContext buildContext = taskContext.getBuildContext(); Map<String, String> data = taskContext.getConfigurationMap(); ContinuousDeliveryNotificationEvent cdEvent = getContinuousDeliveryNotificationEvent(data.get(SELECTED_NOTIFICATION_KEY), buildContext);
eventManager.publishEvent(cdEvent); return TaskResultBuilder.create(taskContext).success().build(); }
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey Matt,
What is the parent class for your listener. I found the HARD way that using HibernateEventListner as the parent interface instead of AbstractNotificationEventListner makes Brydie's suggestion work.
Rudy
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Got exactly the same issue in Bamboo 4.4.3
As Rudy said I can see in the stack trace that the transactionTemplate wrapper is being used but I'm still getting the net.sf.hibernate.HibernateException: Could not initialize proxy error message.
Any suggestions for solutions/work arounds?
Thanks,
Matt
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello,
I am having the same issue in Bamboo 4.3.1. I have injected the transactionTemlate into the Plugin and I can confirm from the stacktrace that it is being used. But, still the same error.
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed at net.sf.hibernate.proxy.LazyInitializer.initialize(LazyInitializer.java:47) at net.sf.hibernate.proxy.LazyInitializer.initializeWrapExceptions(LazyInitializer.java:60) at net.sf.hibernate.proxy.LazyInitializer.getImplementation(LazyInitializer.java:164) ...... at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at $Proxy67.getNotificationRules(Unknown Source) at sun.reflect.GeneratedMethodAccessor665.invoke(Unknown Source) ...... at com.atlassian.plugin.osgi.bridge.external.HostComponentFactoryBean$DynamicServiceInvocationHandler.invoke(HostComponentFactoryBean.java:154) at $Proxy162.getNotificationRules(Unknown Source) at com.atlassian.bamboo.notification.AbstractNotificationEventListener.getNotificationRules(AbstractNotificationEventListener.java:73) ...... at java.lang.reflect.Method.invoke(Unknown Source) at com.atlassian.plugin.osgi.hostcomponents.impl.DefaultComponentRegistrar$ContextClassLoaderSettingInvocationHandler.invoke(DefaultComponentRegistrar.java:129) at $Proxy216.doInTransaction(Unknown Source) at sun.reflect.GeneratedMethodAccessor462.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.atlassian.plugin.osgi.bridge.external.HostComponentFactoryBean$DynamicServiceInvocationHandler.invoke(HostComponentFactoryBean.java:154) at $Proxy216.doInTransaction(Unknown Source) at com.atlassian.sal.core.transaction.HostContextTransactionTemplate.execute(HostContextTransactionTemplate.java:21) ....... at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at $Proxy768.execute(Unknown Source) ....... at java.lang.Thread.run(Unknown Source)
Any other ideas?
Thanks,
Rudy
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Community moderators have prevented the ability to post new answers.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.