I would like to quickly point out that the method java.lang.reflect.Method#isSynthetic() gives you access to the synthetic flag in a very easy way.
My understanding from JIT implementors has always been that final is a good thing for performance. I also like the additional safety it adds to the proxy code, preventing us accidentally overriding our own implementations. I do think overriding synthetic methods when proxying is a reasonably bad idea, similarly for bridge methods, which I imagine are also overridden. Intercepting these calls gives the wrong behaviour unless you are extremely careful. Obviously I'm not part of the OWB discussion, and they may be making valid points. For clarity we avoid weaving/overriding synthetic, static, private, bridge, abstract or native modified methods in Aries code. I assume removing the final modifier from the proxy weaving code also fixes the issue? Regards, Tim ---------------------------------------- > Subject: Re: Another weaving problem? > From: [email protected] > Date: Thu, 2 Jun 2011 16:01:20 -0700 > To: [email protected] > > My source (Mark Struberg) says all 1.5++ vms, but I have no direct knowledge. > > david jencks > > On Jun 2, 2011, at 3:39 PM, Alasdair Nottingham wrote: > > > Is that claim about final methods true of all JVMs do you know? I know > > different JVMs tend to have different JITs so I was wondering if they are > > talking about just the hotspur JVM? > > > > I'm deliberately not commenting on the rest, I'm just trying to learn. > > > > Alasdair Nottingham > > > > On 2 Jun 2011, at 23:34, David Jencks wrote: > > > >> Hi Tim, > >> > >> First I fixed this in OWB by having their proxyability-checking code > >> ignore synthetic methods. This works and AFAICT the actual proxy building > >> code seems to work ok. However a couple of OWB committers have objected to > >> this and one of them has told me that starting in java 1.5 marking methods > >> final has no effect on whether the JIT can optimize better. I'm a little > >> nervous about this change also since the synthetic flag is not exposed by > >> the java reflection code. > >> > >> So when I get a minute I'm going to try removing the final modifier from > >> the generated synthetic methods and restore the OWB code. If you have any > >> concerns please speak up :-) > >> > >> thanks! > >> david jencks > >> > >> On Jun 1, 2011, at 1:28 AM, Timothy Ward wrote: > >> > >>> > >>> Hi David, > >>> > >>> The proxying code does indeed add a couple of final methods on the > >>> highest woven supertype of a class hierarchy. The equivalent source for > >>> these would be the following: > >>> > >>> -------------------------------------------------------- > >>> > >>> public final Callable org_apache_aries_proxy_weaving_WovenProxy_unwrap() { > >>> return dispatcherField; > >>> } > >>> > >>> > >>> > >>> public final boolean > >>> org_apache_aries_proxy_weaving_WovenProxy_isProxyInstance() { > >>> > >>> return dispatcherField != null && listenerField != null; > >>> > >>> } > >>> > >>> -------------------------------------------------------- > >>> > >>> dispatcherField and listenerField are protected final member variables > >>> with long, auto-generated field names that should never clash with > >>> anything already in the class. > >>> > >>> Both of these methods are marked synthetic in the bytecode, which I would > >>> have hoped meant that they would be safely ignored. The primary reason > >>> for making the methods final is to ensure the JIT can optimize > >>> effectively, so if you'd like to try changing line 67 of > >>> AbstractWovenProxyAdapter to remove the ACC_FINAL part of the bitmask > >>> then that will stop the methods from being final. This should have no > >>> functional effect on the proxy code, just a potential, minor performance > >>> impact. > >>> > >>> It's a shame that the webbeans implementation can't use the existing > >>> proxying, but I suppose that's not possible... > >>> > >>> > >>> > >>> For completeness, weaving also adds the following code to every class > >>> that it weaves (not just the highest supertype): > >>> > >>> -------------------------------------------------------- > >>> > >>> protected Constructor(Callable dispatcher, InvocationListener listener) { > >>> //either this for the sub-types > >>> super(dispatcher, listener); > >>> > >>> //or this for the highest woven supertype > >>> super(); // sometimes this(); if there is no no-args super > >>> dispatcherField = dispatcher; > >>> listenerField = listener; > >>> > >>> } > >>> > >>> public WovenProxy > >>> org_apache_aries_proxy_weaving_WovenProxy_createNewProxyInstance(Callable > >>> dispatcher, InvocationListener listener) { > >>> return new ThisClass(dispatcher, listener); > >>> } > >>> > >>> -------------------------------------------------------- > >>> > >>> > >>> Regards, > >>> > >>> Tim > >>> > >>> > >>> ---------------------------------------- > >>>> From: [email protected] > >>>> Subject: Another weaving problem? > >>>> Date: Tue, 31 May 2011 17:05:04 -0700 > >>>> To: [email protected] > >>>> > >>>> Thanks tim for fixing the SerialVersionUID problem. I think I'm running > >>>> into another problem with the weaving since this doesn't show up with > >>>> plain geronimo + owb. Most of the jcdi tck fails with deployment errors > >>>> like this: > >>>> > >>>> 2011-05-31 16:02:27,902 ERROR [WebBeansConfigurationListener] An error > >>>> occured while starting application context path : > >>>> [/org.jboss.jsr299.tck.tests.context.ContextTest] > >>>> 2011-05-31 16:02:27,903 ERROR [ContextTest]] Exception sending context > >>>> initialized event to listener instance of class > >>>> org.apache.geronimo.openwebbeans.WebBeansConfigurationListener > >>>> javax.enterprise.inject.UnproxyableResolutionException: WebBeans with > >>>> api type with normal scope must be proxiable to inject. > >>>> org.jboss.jsr299.tck.tests.context.MySessionBean has final methods! CDI > >>>> doesn't allow that. > >>>> at > >>>> org.apache.webbeans.util.InjectionExceptionUtils.throwUnproxyableResolutionException(InjectionExceptionUtils.java:39) > >>>> at > >>>> org.apache.webbeans.util.WebBeansUtil.checkUnproxiableApiType(WebBeansUtil.java:1852) > >>>> at > >>>> org.apache.webbeans.component.creation.ManagedBeanCreatorImpl.checkCreateConditions(ManagedBeanCreatorImpl.java:70) > >>>> at > >>>> org.apache.webbeans.util.WebBeansUtil.defineManagedBean(WebBeansUtil.java:2598) > >>>> at > >>>> org.apache.webbeans.config.BeansDeployer.defineManagedBean(BeansDeployer.java:859) > >>>> at > >>>> org.apache.webbeans.config.BeansDeployer.deploySingleAnnotatedType(BeansDeployer.java:539) > >>>> at > >>>> org.apache.webbeans.config.BeansDeployer.deployFromClassPath(BeansDeployer.java:484) > >>>> at > >>>> org.apache.webbeans.config.BeansDeployer.deploy(BeansDeployer.java:165) > >>>> at > >>>> org.apache.webbeans.lifecycle.AbstractLifeCycle.startApplication(AbstractLifeCycle.java:129) > >>>> at > >>>> org.apache.webbeans.web.lifecycle.WebContainerLifecycle.startApplication(WebContainerLifecycle.java:87) > >>>> at > >>>> org.apache.geronimo.openwebbeans.WebBeansConfigurationListener.contextInitialized(WebBeansConfigurationListener.java:85) > >>>> at > >>>> org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4521) > >>>> at > >>>> org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5004) > >>>> at > >>>> org.apache.catalina.core.StandardContext$1.call(StandardContext.java:4999) > >>>> at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) > >>>> at java.util.concurrent.FutureTask.run(FutureTask.java:138) > >>>> at > >>>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) > >>>> at > >>>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) > >>>> at java.lang.Thread.run(Thread.java:680) > >>>> > >>>> I don't see any final methods in MySessionBean: > >>>> > >>>> @SessionScoped > >>>> class MySessionBean implements Serializable > >>>> { > >>>> private static final long serialVersionUID = 1L; > >>>> > >>>> private int id = 0; > >>>> > >>>> public void setId(int id) > >>>> { > >>>> this.id = id; > >>>> } > >>>> > >>>> public int getId() > >>>> { > >>>> return id; > >>>> } > >>>> > >>>> public void ping() > >>>> { > >>>> } > >>>> > >>>> } > >>>> > >>>> so I'm guessing the weaving might have added something?? > >>>> > >>>> Is there a description of what the weaving does in terms of java code? > >>>> Or even a description of what it does in java op codes? > >>>> > >>>> thanks > >>>> david jencks > >>>> > >>> > >> >
