Hello, everyone! While I believe we should fix this problem in the Tapestry's proxy creator code, since it may have been happening in non-Hibernate stuff as well, maybe we could have an interim fix of not using PropertyShadowBuider to build the Session service? Code is in HibernateCoreModule.buildSession().
On Sat, Jun 24, 2023 at 11:17 AM Ben Weidig <b...@netzgut.net> wrote: > > I think I found the issue. > Not 100% sure yet, but my first tests look good. > > The PropertyShadowBuilder got changed in TAP5-2582, so it can handle > duplicate methods if interfaces extend each other. > > > In the case of Session, however, the return types of the methods differ, as > it's totally valid to elevate a return type if you extend an interface, as > long as the new return type extends/implements the previous one. > The > org.apache.tapestry5.ioc.internal.services.PropertyShadowBuilderImpl.MethodSignatureUniqueComparator > is used for sorting the methods, so only the first of each method is used. > > > For example,without checking the return type, the method > > public abstract org.hibernate.query.Query > org.hibernate.SharedSessionContract.getNamedQuery(java.lang.String) > > gets removed. > > > > With comparing return types, the method > > public default org.hibernate.Query > org.hibernate.SharedSessionContract.getNamedQuery(java.lang.String) > > gets removed. > > > What confused me was the "default" modifier on the method, as the method > declarations in the interface don't have a "default" implementations. > Let's recreate the scenario: > > interface Original { > Number test(); > } > interface Extended extends Original { > Double test(); > } > > Time for some bytecode: > > Classfile /Users/ben/code/tapestry/tapestry-5/Extended.class > Last modified 24 Jun 2023; size 254 bytes > SHA-256 checksum > 708c3793a9074f5afdd523542cf287559d5cbeee871a0ca9757444dc28edafe3 > Compiled from "Extended.java" > interface Extended extends Original > minor version: 0 > major version: 61 > flags: (0x0600) ACC_INTERFACE, ACC_ABSTRACT > this_class: #2 // Extended > super_class: #7 // java/lang/Object > interfaces: 1, fields: 0, methods: 2, attributes: 1 > Constant pool: > #1 = InterfaceMethodref #2.#3 // > Extended.test:()Ljava/lang/Double; > #2 = Class #4 // Extended > #3 = NameAndType #5:#6 // test:()Ljava/lang/Double; > #4 = Utf8 Extended > #5 = Utf8 test > #6 = Utf8 ()Ljava/lang/Double; > #7 = Class #8 // java/lang/Object > #8 = Utf8 java/lang/Object > #9 = Class #10 // Original > #10 = Utf8 Original > #11 = Utf8 ()Ljava/lang/Number; > #12 = Utf8 Code > #13 = Utf8 LineNumberTable > #14 = Utf8 SourceFile > #15 = Utf8 Extended.java > { > public abstract java.lang.Double test(); > descriptor: ()Ljava/lang/Double; > flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT > > public default java.lang.Number test(); > descriptor: ()Ljava/lang/Number; > flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC > Code: > stack=1, locals=1, args_size=1 > 0: aload_0 > 1: invokeinterface #1, 1 // InterfaceMethod > test:()Ljava/lang/Double; > 6: areturn > LineNumberTable: > line 1: 0 > } > SourceFile: "Extended.java" > > Ok, the "default" method now makes more sense, as the two methods exist on > the interface but with different return types. > This might feel like invalid Java, as the return type doesn't count to the > method signature, but the JVM allows that. > The ACC_BRIDGE flag means that the method was generated by the compiler to > "bridge" between the original method declaration and the override. > > > With that knowledge, my hunch is that even though the default method, which > should call the correct method, can't because, well, Proxies do a lot of > bytecode magic themselves. > > > On Fri, Jun 23, 2023 at 8:22 PM Vangel V. Ajanovski <ajanov...@gmail.com> > wrote: > > > On 21.6.23 20:32, Volker Lamp wrote: > > > Is there any chance I can motivate you to contribute your test case as > > > a unit test to the Tapestry code base? Have a look at the test apps in > > > tapestry-jpa as a starting point. > > > > If I find some free time in the following months to look it up and learn > > how to create an entire test case. For the time-being it will be faster > > for me to create a docker container spec to reproduce the bug. > > > > As an alternative, I tried to modify the tapestry sources and the > > existing tests. I have never tried to build tapestry from source in the > > past, so bare with my ignorance. I cloned the sources from git, and > > decided for the command line route and just did ./gradlew build. > > > > It seems successful. All the .jars are at the expected locations. I > > modified the gradle build file and hibernate.cfg.xml in the test folders > > inside tapestry-hibernate so that it should connect to another database > > and it uses another driver, just to see if this will stir things up, but > > nothing happened. The problem is that I don't see any connections to the > > database when I run the build, which seems strange to me. How do I force > > the tests to rerun and which is the specific test that i should run that > > uses the connection information in > > tapestry-hibernate/src/test/resources/hibernate.cfg.xml? > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > > For additional commands, e-mail: users-h...@tapestry.apache.org > > > > -- Thiago --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org