[
https://issues.apache.org/jira/browse/ISIS-1502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Dan Haywood updated ISIS-1502:
------------------------------
Description:
The situation being an error in toString() throwing an
InvocationTargetException, as part of the processing of ChangedObjectsService
in the preCommit().
Although this preCommit() code catches RuntimeExceptions, the
InvocationTargetException thrown is actually an Exception (even though not in
any throws clause).
What therefore happened was that the catch block in endTransaction did not
fire, and was then caught a layer further out (in WebRequestCycleForIsis),
which incorrectly created a new transaction but with the current transaction's
state / transaction manager's transactionLevel in invalid states.
The net effect was a transaction with the current transaction still in
progress, but with transactionLevel = 0. A subsequent endTransaction took the
transactionLevel to -1, then resulting in the infinite loop.
Fixes are:
1. catch Exception rather than just RuntimeException in endTransaction
2. also change the order in which transactionLevel is decremented, so that it
is only done after the preCommit stuff has completed ok
3. in the place where we throw an exception if transactionLevel is found to be
-1, then also ensure that the state of the current transaction is set
appropriately.
All of these have been implemented (and any is sufficient to prevent the
infinite loop).
In addition, further logging to detect when there is an invalid end state of
transactionLevel and transaction state has been added.
Original root cause that was not caught in endTransaction :
{code}
Caused by:
java.lang.reflect.InvocationTargetException
sun.reflect.GeneratedMethodAccessor367#invoke(null:-1)
sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method#invoke(Method.java:498)
org.apache.isis.core.runtime.services.ServiceInstantiator$2#invoke(ServiceInstantiator.java:219)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal_$$_jvst301_6#getChangedObjectProperties(ChangedObjectsServiceInternal_$$_jvst301_6.java:-1)
org.apache.isis.core.runtime.services.auditing.AuditingServiceInternal#audit(AuditingServiceInternal.java:79)
org.apache.isis.core.runtime.system.transaction.IsisTransaction#preCommit(IsisTransaction.java:424)
org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#endTransaction(IsisTransactionManager.java:363)
org.apache.isis.viewer.wicket.viewer.integration.wicket.WebRequestCycleForIsis#onRequestHandlerExecuted(WebRequestCycleForIsis.java:129)
Caused by:
java.lang.IllegalArgumentException
No such method ' getSent' or 'isSent'
org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:372)
org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
org.apache.isis.core.runtime.services.changes.PreAndPostValues#setPost(PreAndPostValues.java:90)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#capturePostValuesAndDrain(ChangedObjectsServiceInternal.java:241)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#getChangedObjectProperties(ChangedObjectsServiceInternal.java:222)
Caused by:
java.lang.NoSuchMethodException
org.incode.module.communications.dom.impl.comms.Communication.getSent()
java.lang.Class#getMethod(Class.java:1786)
org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:364)
org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
{code}
was:
The situation being an error in toString() throwing an
InvocationTargetException, as part of the processing of ChangedObjectsService
in the preCommit().
Although this preCommit() code catches RuntimeExceptions, the
InvocationTargetException thrown is actually an Exception (even though not in
any throws clause).
What therefore happened was that the catch block in endTransaction did not
fire, and was then caught a layer further out (in WebRequestCycleForIsis),
which incorrectly created a new transaction but with the current transaction's
state / transaction manager's transactionLevel in invalid states.
The net effect was a transaction with the current transaction still in
progress, but with transactionLevel = 0. A subsequent endTransaction took the
transactionLevel to -1, then resulting in the infinite loop.
Fixes are:
1. catch Exception rather than just RuntimeException in endTransaction
2. also change the order in which transactionLevel is decremented, so that it
is only done after the preCommit stuff has completed ok
Both of these have been implemented (and either one is sufficient to prevent
the error).
In addition, further logging to detect when there is an invalid end state of
transactionLevel and transaction state has been added.
Original root cause that was not caught in endTransaction :
{code}
Caused by:
java.lang.reflect.InvocationTargetException
sun.reflect.GeneratedMethodAccessor367#invoke(null:-1)
sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method#invoke(Method.java:498)
org.apache.isis.core.runtime.services.ServiceInstantiator$2#invoke(ServiceInstantiator.java:219)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal_$$_jvst301_6#getChangedObjectProperties(ChangedObjectsServiceInternal_$$_jvst301_6.java:-1)
org.apache.isis.core.runtime.services.auditing.AuditingServiceInternal#audit(AuditingServiceInternal.java:79)
org.apache.isis.core.runtime.system.transaction.IsisTransaction#preCommit(IsisTransaction.java:424)
org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#endTransaction(IsisTransactionManager.java:363)
org.apache.isis.viewer.wicket.viewer.integration.wicket.WebRequestCycleForIsis#onRequestHandlerExecuted(WebRequestCycleForIsis.java:129)
Caused by:
java.lang.IllegalArgumentException
No such method ' getSent' or 'isSent'
org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:372)
org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
org.apache.isis.core.runtime.services.changes.PreAndPostValues#setPost(PreAndPostValues.java:90)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#capturePostValuesAndDrain(ChangedObjectsServiceInternal.java:241)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#getChangedObjectProperties(ChangedObjectsServiceInternal.java:222)
Caused by:
java.lang.NoSuchMethodException
org.incode.module.communications.dom.impl.comms.Communication.getSent()
java.lang.Class#getMethod(Class.java:1786)
org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:364)
org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
{code}
> Error handling of invalid domain object not strong enough, causing infinite
> loop in endTransaction.
> ---------------------------------------------------------------------------------------------------
>
> Key: ISIS-1502
> URL: https://issues.apache.org/jira/browse/ISIS-1502
> Project: Isis
> Issue Type: Bug
> Components: Core
> Affects Versions: 1.13.0
> Reporter: Dan Haywood
> Assignee: Dan Haywood
> Fix For: 1.13.1
>
>
> The situation being an error in toString() throwing an
> InvocationTargetException, as part of the processing of ChangedObjectsService
> in the preCommit().
> Although this preCommit() code catches RuntimeExceptions, the
> InvocationTargetException thrown is actually an Exception (even though not in
> any throws clause).
> What therefore happened was that the catch block in endTransaction did not
> fire, and was then caught a layer further out (in WebRequestCycleForIsis),
> which incorrectly created a new transaction but with the current
> transaction's state / transaction manager's transactionLevel in invalid
> states.
> The net effect was a transaction with the current transaction still in
> progress, but with transactionLevel = 0. A subsequent endTransaction took
> the transactionLevel to -1, then resulting in the infinite loop.
> Fixes are:
> 1. catch Exception rather than just RuntimeException in endTransaction
> 2. also change the order in which transactionLevel is decremented, so that it
> is only done after the preCommit stuff has completed ok
> 3. in the place where we throw an exception if transactionLevel is found to
> be -1, then also ensure that the state of the current transaction is set
> appropriately.
> All of these have been implemented (and any is sufficient to prevent the
> infinite loop).
> In addition, further logging to detect when there is an invalid end state of
> transactionLevel and transaction state has been added.
> Original root cause that was not caught in endTransaction :
> {code}
> Caused by:
> java.lang.reflect.InvocationTargetException
> sun.reflect.GeneratedMethodAccessor367#invoke(null:-1)
> sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
> java.lang.reflect.Method#invoke(Method.java:498)
> org.apache.isis.core.runtime.services.ServiceInstantiator$2#invoke(ServiceInstantiator.java:219)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal_$$_jvst301_6#getChangedObjectProperties(ChangedObjectsServiceInternal_$$_jvst301_6.java:-1)
> org.apache.isis.core.runtime.services.auditing.AuditingServiceInternal#audit(AuditingServiceInternal.java:79)
> org.apache.isis.core.runtime.system.transaction.IsisTransaction#preCommit(IsisTransaction.java:424)
> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#endTransaction(IsisTransactionManager.java:363)
> org.apache.isis.viewer.wicket.viewer.integration.wicket.WebRequestCycleForIsis#onRequestHandlerExecuted(WebRequestCycleForIsis.java:129)
> Caused by:
> java.lang.IllegalArgumentException
> No such method ' getSent' or 'isSent'
> org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:372)
> org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
> org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
> org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
> org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
> org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
> org.apache.isis.core.runtime.services.changes.PreAndPostValues#setPost(PreAndPostValues.java:90)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#capturePostValuesAndDrain(ChangedObjectsServiceInternal.java:241)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#getChangedObjectProperties(ChangedObjectsServiceInternal.java:222)
> Caused by:
> java.lang.NoSuchMethodException
> org.incode.module.communications.dom.impl.comms.Communication.getSent()
> java.lang.Class#getMethod(Class.java:1786)
> org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:364)
> org.apache.isis.applib.util.ObjectContracts#asString(ObjectContracts.java:282)
> org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:276)
> org.apache.isis.applib.util.ObjectContracts#toStringOf(ObjectContracts.java:270)
> org.apache.isis.applib.util.ObjectContracts#toString(ObjectContracts.java:127)
> org.incode.module.communications.dom.impl.comms.Communication#toString(Communication.java:324)
> org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal#asString(ChangedObjectsServiceInternal.java:292)
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)