Bug #30925 Get stack trace when saving a new rule to a name that already exists
Submitted: 10 Sep 2007 6:48 Modified: 14 Oct 2008 16:26
Reporter: Bill Weber Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Enterprise Monitor: Web Severity:S3 (Non-critical)
Version:1.2.0.7481 OS:Any
Assigned to: Eric Herman CPU Architecture:Any
Tags: mer 121

[10 Sep 2007 6:48] Bill Weber
Description:
Saving a rule to a name that already exists gets the following stack trace in the window instead of a dialog or simple error message:

Error Message
com.mysql.merlin.server.monitors.MonitorException: E1300: Advisor "Always Critical" already exists.
Stack Trace
com.mysql.merlin.server.monitors.MonitorService.createMonitor(MonitorService.java:132)
com.mysql.merlin.server.ServiceMgrServices.createMonitor(ServiceMgrServices.java:392)
com.mysql.merlin.ui.actions.monitor.advisors.SaveRule.execute(SaveRule.java:294)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:585)
com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:404)
com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:267)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:229)
com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:167)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:170)
com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
com.mysql.merlin.ui.interceptors.InitializeInterceptor.intercept(InitializeInterceptor.java:57)
com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
com.mysql.merlin.ui.interceptors.AuthenticationInterceptor.intercept(AuthenticationInterceptor.java:92)
com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:50)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:507)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:421)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
java.lang.Thread.run(Thread.java:595)

How to repeat:
- Advisors tab, Manage Rules
- click copy next to one of the existing rules
- take off the "copy" from the name so it has the same name as the original
- click save
|stack trace
[10 Sep 2007 21:13] Peter Lavin
Added to the documentation as a known issue.
[12 May 2008 19:36] Joshua Ganderson
This bug becomes somewhat more confused with the addition of internationalized rule names for certified rules. Do we complain that there's a duplicate rule only on the current user's localized rule name? What happens if the name put in conflicts with a rule for a different user's locale?

The simple and straightforward solution is to add an indication that a rule is certified in the manage rules page. That way user's can name rules whatever they please and only be dealing with conflicts against other user named rules. Since these rules will have burned in names rather than localized, localization differences don't come into it.

The one problem with this solution is that a user naming a rule the same as the KEY for the name of a certified rule will cause an error. However, that's an unlikely scenario. If it becomes an issue, we could special case it and provide a more meaningful error OR do some hack that prepends something to the user generated name and strips it off for display.

Other than the new snags pointed out above, I believe name collisions should cause a UI error rather than a stack trace on the error page. However, I can't confirm this since rule creation seems to be broken. I will set this to verified until the behavior can be determined.
[4 Sep 2008 19:01] Bill Weber
with 2.0.0.7044 get following stack trace:

2008-09-04 11:53:53,254 ERROR [http-18080-1:com.mysql.misc] could not insert: [com.mysql.etools.monitor.pom.hib.HibRule]
org.hibernate.exception.ConstraintViolationException: could not insert: [com.mysql.etools.monitor.pom.hib.HibRule]
	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
	at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:40)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2163)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2643)
	at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:51)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
	at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
	at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
	at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
	at sun.reflect.GeneratedMethodAccessor53.invoke(Unknown Source)
...

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'Attempted Connections To The Server Have Failed - copy 1' for key 2
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
	at com.mysql.jdbc.Util.getInstance(Util.java:381)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3512)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3444)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1948)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2081)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2554)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1751)
[9 Oct 2008 17:13] Bill Weber
verified fixed in build 2.0.0.7072
[14 Oct 2008 16:26] Tony Bedford
An entry was added to the 2.0 changelog:

Saving a rule with a name that already existed resulted in a stack trace in the window, instead of a more user-friendly error message.