Hi, Before we go that way, please do some performance tests. We've seen very bad performance in StackWalker, especially when it is called many times over. This may have improved in more recent JDKs, but in Java 11 the overhead was so significant that a single StackWalker call in a log call would kill the server slowly over time: https://issues.redhat.com/browse/LOGMGR-263
Best regards, Emond On Tue, Dec 15, 2020 at 8:45 AM Martin Grigorov <mgrigo...@apache.org> wrote: > > Hi Chris, > > Thank you for your advices! > > On Mon, Dec 14, 2020 at 6:11 PM Chris Hegarty <chris.hega...@oracle.com> > wrote: > > > > > > On 14 Dec 2020, at 10:03, Rory O'Donnell <rory.odonn...@oracle.com> > > wrote: > > > > > > ... > > > On 14/12/2020 09:45, Martin Grigorov wrote: > > >> Hi Rory, > > >> > > >> Apache Wicket build and tests are OK with JDK 16 b28 for both aarch64 > > and > > >> x86_64 (Ubuntu 20.10)! > > >> > > >> I had to add --add-opens=java.base/java.io=ALL-UNNAMED to > > >> maven-surefire-plugin's JVM arguments because it seems this plugin does > > not > > >> use the (automatic) module name of the Maven project and the JDK sees > > it as > > >> unnamed. > > >> And because of this Wicket was not able to install its hooks into Java > > >> Serialization API. > > >> > > >> > > https://github.com/apache/wicket/commit/b269b6dcc6a7642c5b5211cae60c7fa24dd7e7ef__;!!GqivPVa7Brio!OG8UiKWp8imcsbWbsHgnGZT9g23KrXftUL9elEebSECla8O_rUMab08gGqzzNApXj5k$ > > > > Opening the `java.io` package will of course work, but requires all > > deployments of Wicket to do so. Maybe there is a better alternative. > > > > > Actually there is no problem. > The unit tests were failing because of 'module java.base does not "opens > java.io" to unnamed module'. > It seems maven-surefire-plugin does not use the Maven module's (automatic) > module name while running the tests and the JVM sees it as "unnamed". > So, I've added the exception to maven-surefire-plugin's JVM args: > https://github.com/apache/wicket/blob/b269b6dcc6a7642c5b5211cae60c7fa24dd7e7ef/pom.xml#L1086-L1097 > If I deploy a .war file to a web container like Apache Tomcat then there is > no such exception at runtime. I haven't verified but I guess all is fine > due to the Automatic-Module-Name in META-INF/MANIFEST.MF ( > https://github.com/apache/wicket/blob/b269b6dcc6a7642c5b5211cae60c7fa24dd7e7ef/pom.xml#L989-L1004 > ) > > > > I see that `org.apache.wicket.serialize.java.JavaSerializer` is using > > `setAccessible(true)` to access the private static method > > `latestUserDefinedLoader` in `java.io.ObjectInputStream`. There is a > > straightforward way of implementing similar functionality with the > > standard java.lang.StackWalker API. If you do this, then the > > `--add-opens` can probably be dropped. > > > > I will try to improve this with your suggestion! > > But the problem I solved was for > https://github.com/apache/wicket/blob/b269b6dcc6a7642c5b5211cae60c7fa24dd7e7ef/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/CheckingObjectOutputStream.java#L251-L282 > Here Wicket uses Reflection for ObjectStreamClass and ObjectStreamField to > be able to pinpoint which member field of a Java object is not Serializable > for debugging purposes. > > > > > > Here is an example of such: > > > > static { > > PrivilegedAction<StackWalker> pa1 = > > () -> > > StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); > > PrivilegedAction<ClassLoader> pa2 = > > () -> ClassLoader.getPlatformClassLoader(); > > STACKWALKER = AccessController.doPrivileged(pa1); > > PLATFORM_LOADER = AccessController.doPrivileged(pa2); > > } > > > > /** > > * Returns the first non-null and non-platform class loader (not > > counting > > * class loaders of generated reflection implementation classes) up the > > * execution stack, or the platform class loader if only code from the > > * bootstrap and platform class loader is on the stack. > > */ > > private static ClassLoader latestUserDefinedLoader() { > > return STACKWALKER.walk(s -> > > s.map(StackWalker.StackFrame::getDeclaringClass) > > .map(Class::getClassLoader) > > .filter(Objects::nonNull) > > .filter(cl -> !PLATFORM_LOADER.equals(cl)) > > .findFirst() > > .orElse(PLATFORM_LOADER)); > > } > > > > Remove the PrivilegedAction / doPrivileged stuff if not interested in > > running with a security manager enabled. > > > > Let me know if I can do anything further to help. > > > > -Chris. > > > >