-
1. Re: How to change Synchronized.DEFAULT_TIMEOUT without recompilation
luxspes Oct 28, 2009 11:54 PM (in response to luxspes)Seems like the only way to do it would be to replace org.jboss.seam.core.SynchronizationInterceptor with my own custom implementation that reads the value from components.xml.
But since SynchronizationInterceptor is a core part of Seam I do not feel comfortable doing this...
-
2. Re: How to change Synchronized.DEFAULT_TIMEOUT without recompilation
kragoth Oct 29, 2009 2:57 AM (in response to luxspes)You could try reflectively setting the value of Component.timeout at startup time or creation of a component. So intercept the creation of a component and reflectively set it's timeout value.
Don't have time to investigate if this will be enough to get you going, but it might be.
Based on the line in the SynchronizationInterceptor
if ( lock.tryLock( getComponent().getTimeout(), TimeUnit.MILLISECONDS ) )
All you need to do is make sure the call to getComponent.getTimeout() returns your X value.
Anyways, just an idea.
-
3. Re: How to change Synchronized.DEFAULT_TIMEOUT without recompilation
luxspes Oct 29, 2009 8:03 PM (in response to luxspes)Finally found the place where the default interceptors are defined org.jboss.seam.core.Init:
public static List<String> DEFAULT_INTERCEPTORS = new ArrayList<String>(Arrays.asList( SynchronizationInterceptor.class.getName(), AsynchronousInterceptor.class.getName(), RemoveInterceptor.class.getName(), HibernateSessionProxyInterceptor.class.getName(), EntityManagerProxyInterceptor.class.getName(), MethodContextInterceptor.class.getName(), EventInterceptor.class.getName(), ConversationalInterceptor.class.getName(), BusinessProcessInterceptor.class.getName(), ConversationInterceptor.class.getName(), BijectionInterceptor.class.getName(), RollbackInterceptor.class.getName(), TransactionInterceptor.class.getName(), WSSecurityInterceptor.class.getName(), SecurityInterceptor.class.getName() ));
This list (and the reasons for this particular order) should be part of Seam documentation but I could not find it.
So now I am going to use:
<core:init debug="true"> <core:interceptors> ... </core:interceptors> </core:init>
To replace SynchronizationInterceptor with my own more flexible ConfigurableSynchronizationInterceptor class...
Hope it works...
-
4. Re: How to change Synchronized.DEFAULT_TIMEOUT without recompilation
luxspes Oct 29, 2009 8:55 PM (in response to luxspes)Here is how, first, adjust your list of interceptors in components.xml (remove SynchronizationInterceptor, add your custom ConfigurableSynchronizationInterceptor):
<core:init debug="true"> <core:interceptors> <!-- <value>org.jboss.seam.core.SynchronizationInterceptor</value>--> <value>my.company.ConfigurableSynchronizationInterceptor</value> <value>org.jboss.seam.async.AsynchronousInterceptor</value> <value>org.jboss.seam.ejb.RemoveInterceptor</value> <value>org.jboss.seam.persistence.HibernateSessionProxyInterceptor</value> <value>org.jboss.seam.persistence.EntityManagerProxyInterceptor</value> <value>org.jboss.seam.core.MethodContextInterceptor</value> <value>org.jboss.seam.core.EventInterceptor</value> <value>org.jboss.seam.core.ConversationalInterceptor</value> <value>org.jboss.seam.bpm.BusinessProcessInterceptor</value> <value>org.jboss.seam.core.ConversationInterceptor</value> <value>org.jboss.seam.core.BijectionInterceptor</value> <value>org.jboss.seam.transaction.RollbackInterceptor</value> <value>org.jboss.seam.transaction.TransactionInterceptor</value> <value>org.jboss.seam.webservice.WSSecurityInterceptor</value> <value>org.jboss.seam.security.SecurityInterceptor</value> </core:interceptors> </core:init>
Write your own interceptor with configurable timeout:
@Interceptor(type=InterceptorType.CLIENT) public class ConfigurableSynchronizationInterceptor extends AbstractInterceptor { private ReentrantLock lock = new ReentrantLock(true); @AroundInvoke public Object aroundInvoke(InvocationContext invocation) throws Exception { SynchronizationConfiguration cfg=(SynchronizationConfiguration) Component.getInstance("synchronizationConfiguration"); if ( lock.tryLock( cfg.getSynchronizationTimeOut(), TimeUnit.MILLISECONDS ) ) { try { return invocation.proceed(); } finally { lock.unlock(); } } else { throw new LockTimeoutException("could not acquire lock on @Synchronized component: " + getComponent().getName()); } } public boolean isInterceptorEnabled() { return getComponent().isSynchronize(); } }
Create a class that you will use to set and store the configurable timeout value:
public class SynchronizationConfiguration { private long synchronizationTimeOut; public long getSynchronizationTimeOut() { return synchronizationTimeOut; } public void setSynchronizationTimeOut(long synchronizationTimeOut) { this.synchronizationTimeOut = synchronizationTimeOut; } }
Configure the timeout value in components.xml:
<component class="my.company.SynchronizationConfiguration" name="synchronizationConfiguration" scope="application"> <property name="synchronizationTimeOut">60000</property> </component>
And that is it, now you can change the synchronizationTimeOut for ALL the components in your application in a single place, without any recompilation.
IMO this should be part of Seam core... why it was not implemented like this since the beginning?...
-
5. Re: How to change Synchronized.DEFAULT_TIMEOUT without recompilation
luxspes Oct 29, 2009 9:13 PM (in response to luxspes)And so a new JIRA issue is created: JBSEAM-4459
-
6. Re: How to change Synchronized.DEFAULT_TIMEOUT without recompilation
markwigmans Dec 14, 2009 9:41 PM (in response to luxspes)Greate code, just what I needed. I think that if explicit a timeout is given, you can this that as well:
..
final Method method = invocation.getMethod();
final Synchronized annotation = method.getDeclaringClass().getAnnotation(Synchronized.class);
long timeout = annotation != null ? annotation.timeout() : cfg.getSynchronizationTimeOut();
if (lock.tryLock(timeout, TimeUnit.MILLISECONDS)) {
..