Thanks for your feedback Romain! Indeed this is not an easy thing to test.
The build is broken now; and it looks like this is the reason.

I will rollback the changes while I'm unable to create an unit test for it.

[]s,
Thiago.



On Wed, Dec 4, 2013 at 2:38 AM, Romain Manni-Bucau <[email protected]>wrote:

> Marker = key in a hasmap or sthg like it.
>
> The point is we use kind of fake loader delegating to real loaders. So
> hashCode is effectively equals but equals shouldnt return true from a
> strict perspective but if it doesnt do it we are not able to use cdi
> correctly (excepted luck or particular case) and a lot of ee libs are
> broken
>
> To try to do a test I think you need to execute both from a webapp and from
> a jaxws request. But when the bug was reported it was very hard to find and
> it was in a complicated case so not sure that's trivial to do, we have good
> fallbacks for simple cases
> Le 4 déc. 2013 03:03, "Thiago Veronezi" <[email protected]> a écrit :
>
> > Hmmmm, ok. I guess I start to understand what the problem is. If I'm
> right,
> > we already have a buggy feature. Bear with me.
> >
> > None of the parents of LazyStopWebappClassLoader implements "hashCode",
> > therefore our current "LazyStopWebappClassLoader#equals" implementation
> (at
> > the least the one just before my last commit) is based on the result of
> > "Object.hashCode()". According the the "java api", "Object#hashCode" is
> > typically implemented by converting the internal address of the object
> into
> > an integer.
> >
> > Furthermore, the general contract of hashCode is (also java api):
> > * Whenever it is invoked on the same object more than once during an
> > execution of a Java application, the hashCode method must consistently
> > return the same integer, provided no information used in equals
> comparisons
> > on the object is modified. This integer need not remain consistent from
> one
> > execution of an application to another execution of the same application.
> > * If two objects are equal according to the equals(Object) method, then
> > calling the hashCode method on each of the two objects must produce the
> > same integer result.
> > * It is not required that if two objects are unequal according to the
> > equals(java.lang.Object) method, then calling the hashCode method on each
> > of the two objects must produce distinct integer results. However, the
> > programmer should be aware that producing distinct integer results for
> > unequal objects may improve the performance of hash tables.
> >
> >
> > So, in our case...
> >
> > LazyStopWebappClassLoader.java
> > ******************************************************
> >    public boolean equals(final Object other) {
> >        return other != null && ClassLoader.class.isInstance(other) &&
> > hashCode() == other.hashCode();
> >    }
> >    public int hashCode() {
> >        return super.hashCode();
> >    }
> > ******************************************************
> >
> > If this.hashCode() is equal to other.hashCode(), that means that "this ==
> > other". In other words, "this" is the same instance (same memory address)
> > represented by "other". In this case we have the same result as we would
> > have by using the "Object" implementation of both methods.
> >
> > Object.class
> > ******************************************************
> >     public boolean equals(Object obj) {
> >   return (this == obj);
> >     }
> >     public native int hashCode();
> > ******************************************************
> >
> >
> >
> > Why I think we have a bug? In both implementations, we would never have
> two
> > equal classloader objects if both aren't exactly the same instance
> because
> > in both implementations we use "Object.hashCode" to compare "this" and
> > "other". Am I right?
> >
> > >>we and libs like deltaspike use classloader as marker
> > I didn't get what you mean by "marker". How does it work?
> >
> > Anyway, the build was successful and all my own applications still run
> > perfectly. Can you give me some direction on how to create a unit test
> that
> > validates it?
> >
> > []s,
> > Thiago.
> >
> >
> >
> >
> > On Tue, Dec 3, 2013 at 6:48 PM, Romain Manni-Bucau <
> [email protected]
> > >wrote:
> >
> > > The more obvious issue comes from the fact we and libs like deltaspike
> > use
> > > classloader as marker so if both are not equals when needed it doesnt
> > work
> > > (we dont find cdi context ror instance)
> > > Le 3 déc. 2013 23:34, "Thiago Veronezi" <[email protected]> a écrit
> :
> > >
> > > > >>If you have time to add tests it would be great
> > > > I will test it a little bit further.
> > > >
> > > > But I didn't quite get the problem yet... sorry! :)
> > > >
> > > >
> > > > This is our implementation (without the cache)...
> > > >
> > > >
> > >
> >
> *****************************************************************************************************
> > > >    public boolean equals(final Object other) {
> > > >        return other != null && ClassLoader.class.isInstance(other) &&
> > > > hashCode() == other.hashCode();
> > > >    }
> > > >
> > > >    public int hashCode() {
> > > >        return super.hashCode();
> > > >    }
> > > >
> > > >
> > >
> >
> *****************************************************************************************************
> > > >
> > > > This is the default implementation...
> > > >
> > > >
> > >
> >
> *****************************************************************************************************
> > > >     public boolean equals(Object obj) {
> > > >   return (this == obj);
> > > >     }
> > > >
> > > >     public native int hashCode();
> > > >
> > > >
> > >
> >
> *****************************************************************************************************
> > > >
> > > > The default method will return the same integer if  "this == other";
> > and
> > > we
> > > > are basically comparing the result of both hashCode() calls. Isn't it
> > the
> > > > same thing?
> > > >
> > > > []s,
> > > > Thiago.
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > On Tue, Dec 3, 2013 at 5:11 PM, Romain Manni-Bucau <
> > > [email protected]
> > > > >wrote:
> > > >
> > > > > well, the issue is without doing it the classloader used for cxf
> > > > > (
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/repos/asf/tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfContainerClassLoader.java
> > > > > )
> > > > > and the webapp loader are different. I'm 100% sure that's a
> > regression
> > > > > even if build passes and we can't keep it.
> > > > >
> > > > > This makes equals not symmetric so using JVM equals/hashCode is the
> > > > > best we can do.
> > > > >
> > > > > If you have time to add tests it would be great, the issue can come
> > > > > from client/server and jaxws/jaxrs. It can cause linkagerror,
> > > > > classcast or even prevent deployment.
> > > > > Romain Manni-Bucau
> > > > > Twitter: @rmannibucau
> > > > > Blog: http://rmannibucau.wordpress.com/
> > > > > LinkedIn: http://fr.linkedin.com/in/rmannibucau
> > > > > Github: https://github.com/rmannibucau
> > > > >
> > > > >
> > > > >
> > > > > 2013/12/3 Thiago Veronezi <[email protected]>:
> > > > > > It didn't locally. It takes ~2 hrs to have an exception or not.
> > > > > > It should happen in the next 1:15 hrs. If anything happens we can
> > > > always
> > > > > > revert it back. :)
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > On Tue, Dec 3, 2013 at 4:19 PM, Romain Manni-Bucau <
> > > > > [email protected]>wrote:
> > > > > >
> > > > > >> it does for sure, not sure we have tests btw
> > > > > >> Romain Manni-Bucau
> > > > > >> Twitter: @rmannibucau
> > > > > >> Blog: http://rmannibucau.wordpress.com/
> > > > > >> LinkedIn: http://fr.linkedin.com/in/rmannibucau
> > > > > >> Github: https://github.com/rmannibucau
> > > > > >>
> > > > > >>
> > > > > >>
> > > > > >> 2013/12/3 Thiago Veronezi <[email protected]>:
> > > > > >> > I tested it locally without the methods.
> > > > > >> > Committed the code to see if the build server complains.
> > > > > >> >
> > > > > >> > []s,
> > > > > >> > Thiago.
> > > > > >> >
> > > > > >> >
> > > > > >> >
> > > > > >> > On Tue, Dec 3, 2013 at 1:11 PM, Romain Manni-Bucau <
> > > > > >> [email protected]>wrote:
> > > > > >> >
> > > > > >> >> hashcode is just a cached impl, equals is mandatory because
> of
> > > the
> > > > > >> >> hack we have to isolate a bit cxf from apps.
> > > > > >> >>
> > > > > >> >> If you fix isolation you can remove it ;).
> > > > > >> >> Romain Manni-Bucau
> > > > > >> >> Twitter: @rmannibucau
> > > > > >> >> Blog: http://rmannibucau.wordpress.com/
> > > > > >> >> LinkedIn: http://fr.linkedin.com/in/rmannibucau
> > > > > >> >> Github: https://github.com/rmannibucau
> > > > > >> >>
> > > > > >> >>
> > > > > >> >>
> > > > > >> >> 2013/12/3 Thiago Veronezi <[email protected]>:
> > > > > >> >> > The equals and hashCode look weird.
> > > > > >> >> >
> > > > > >> >> > ****************************************
> > > > > >> >> >     @Override
> > > > > >> >> >     public boolean equals(final Object other) {
> > > > > >> >> >         return other != null &&
> > > > > ClassLoader.class.isInstance(other) &&
> > > > > >> >> > hashCode() == other.hashCode();
> > > > > >> >> >     }
> > > > > >> >> >
> > > > > >> >> >     @Override
> > > > > >> >> >     public int hashCode() {
> > > > > >> >> >         return hashCode;
> > > > > >> >> >     }
> > > > > >> >> > ****************************************
> > > > > >> >> >
> > > > > >> >> > I wonder if we need these methods at all. Usually equal
> > > hashCodes
> > > > > does
> > > > > >> >> not
> > > > > >> >> > mean that "equals" is true, right?
> > > > > >> >> >
> > > > > >> >> > []s,
> > > > > >> >> > Thiago.
> > > > > >> >> >
> > > > > >> >> >
> > > > > >> >> >
> > > > > >> >> >
> > > > > >> >> > On Tue, Dec 3, 2013 at 12:57 PM, <[email protected]>
> > > wrote:
> > > > > >> >> >
> > > > > >> >> >> Author: rmannibucau
> > > > > >> >> >> Date: Tue Dec  3 17:57:19 2013
> > > > > >> >> >> New Revision: 1547499
> > > > > >> >> >>
> > > > > >> >> >> URL: http://svn.apache.org/r1547499
> > > > > >> >> >> Log:
> > > > > >> >> >> correct hashcode in lazywebappclassloader
> > > > > >> >> >>
> > > > > >> >> >> Modified:
> > > > > >> >> >>
> > > > > >> >> >>
> > > > > >> >>
> > > > > >>
> > > > >
> > > >
> > >
> >
> tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java
> > > > > >> >> >>
> > > > > >> >> >> Modified:
> > > > > >> >> >>
> > > > > >> >>
> > > > > >>
> > > > >
> > > >
> > >
> >
> tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java
> > > > > >> >> >> URL:
> > > > > >> >> >>
> > > > > >> >>
> > > > > >>
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java?rev=1547499&r1=1547498&r2=1547499&view=diff
> > > > > >> >> >>
> > > > > >> >> >>
> > > > > >> >>
> > > > > >>
> > > > >
> > > >
> > >
> >
> ==============================================================================
> > > > > >> >> >> ---
> > > > > >> >> >>
> > > > > >> >>
> > > > > >>
> > > > >
> > > >
> > >
> >
> tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java
> > > > > >> >> >> (original)
> > > > > >> >> >> +++
> > > > > >> >> >>
> > > > > >> >>
> > > > > >>
> > > > >
> > > >
> > >
> >
> tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/LazyStopWebappClassLoader.java
> > > > > >> >> >> Tue Dec  3 17:57:19 2013
> > > > > >> >> >> @@ -41,19 +41,21 @@ public class
> LazyStopWebappClassLoader e
> > > > > >> >> >>      private boolean restarting = false;
> > > > > >> >> >>      private boolean forceStopPhase =
> > > > > >> >> >>
> > > > > >> >>
> > > > > >>
> > > > >
> > > >
> > >
> >
> Boolean.parseBoolean(SystemInstance.get().getProperty("tomee.webappclassloader.force-stop-phase",
> > > > > >> >> >> "false"));
> > > > > >> >> >>      private ClassLoaderConfigurer configurer = null;
> > > > > >> >> >> +    private final int hashCode;
> > > > > >> >> >>
> > > > > >> >> >>      public LazyStopWebappClassLoader() {
> > > > > >> >> >> -        construct();
> > > > > >> >> >> +        hashCode = construct();
> > > > > >> >> >>      }
> > > > > >> >> >>
> > > > > >> >> >>      public LazyStopWebappClassLoader(final ClassLoader
> > > parent)
> > > > {
> > > > > >> >> >>          super(parent);
> > > > > >> >> >> -        construct();
> > > > > >> >> >> +        hashCode = construct();
> > > > > >> >> >>      }
> > > > > >> >> >>
> > > > > >> >> >> -    private void construct() {
> > > > > >> >> >> +    private int construct() {
> > > > > >> >> >>          setDelegate(isDelegate());
> > > > > >> >> >>          configurer = INIT_CONFIGURER.get();
> > > > > >> >> >> +        return super.hashCode();
> > > > > >> >> >>      }
> > > > > >> >> >>
> > > > > >> >> >>      @Override
> > > > > >> >> >> @@ -211,12 +213,8 @@ public class
> LazyStopWebappClassLoader
> > e
> > > > > >> >> >>      }
> > > > > >> >> >>
> > > > > >> >> >>      @Override
> > > > > >> >> >> -    public int hashCode() { // could be improved a bit
> > adding
> > > > the
> > > > > >> host
> > > > > >> >> >> and ensuring contextName != null, an alternative is
> > getURLs()
> > > > but
> > > > > it
> > > > > >> is
> > > > > >> >> >> longer
> > > > > >> >> >> -        final String name = getContextName();
> > > > > >> >> >> -        if (name != null) {
> > > > > >> >> >> -            return name.hashCode();
> > > > > >> >> >> -        }
> > > > > >> >> >> -        return super.hashCode();
> > > > > >> >> >> +    public int hashCode() {
> > > > > >> >> >> +        return hashCode;
> > > > > >> >> >>      }
> > > > > >> >> >>
> > > > > >> >> >>      @Override
> > > > > >> >> >>
> > > > > >> >> >>
> > > > > >> >> >>
> > > > > >> >>
> > > > > >>
> > > > >
> > > >
> > >
> >
>

Reply via email to