You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2021/08/12 11:07:34 UTC

[wicket] branch WICKET-6913-replace-cglib-with-bytebuddy-wicket-10.x created (now f16168b)

This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a change to branch WICKET-6913-replace-cglib-with-bytebuddy-wicket-10.x
in repository https://gitbox.apache.org/repos/asf/wicket.git.


      at f16168b  WICKET-6913 Replace CGLib with ByteBuddy

This branch includes the following new commits:

     new 44b9755  WICKET-6913 Replace CGLib with ByteBuddy in LazyInitProxyFactory
     new a480bcd  WICKET-6913 Convert Objenesis proxy generator to ByteBuddy
     new f16168b  WICKET-6913 Replace CGLib with ByteBuddy

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[wicket] 02/03: WICKET-6913 Convert Objenesis proxy generator to ByteBuddy

Posted by mg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch WICKET-6913-replace-cglib-with-bytebuddy-wicket-10.x
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit a480bcd353e0706a96a52d4199cf69e5fdf03d0c
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Thu Aug 12 09:51:43 2021 +0300

    WICKET-6913 Convert Objenesis proxy generator to ByteBuddy
    
    (cherry picked from commit 43f040e1ffc2ea03a458cb74aca186e2692e63e8)
---
 .../apache/wicket/proxy/LazyInitProxyFactory.java  |  44 ++++---
 ...tor.java => ObjenesisByteBuddyInterceptor.java} |   8 +-
 .../proxy/objenesis/ObjenesisProxyFactory.java     |  29 ++---
 .../proxy/objenesis/ObjenesisProxyReplacement.java |   2 +-
 wicket-jmx/pom.xml                                 |   5 +-
 wicket-jmx/src/main/java/module-info.java          |   2 +-
 .../java/org/apache/wicket/jmx/Initializer.java    | 130 ++++++++++++++-------
 .../org/apache/wicket/jmx/wrapper/Application.java |  21 ----
 .../wicket/jmx/wrapper/ApplicationSettings.java    |   9 --
 9 files changed, 130 insertions(+), 120 deletions(-)

diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java
index d478a25..8a24bc2 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java
@@ -41,6 +41,7 @@ import org.apache.wicket.Application;
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.core.util.lang.WicketObjects;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.proxy.objenesis.ObjenesisProxyFactory;
 import org.apache.wicket.util.io.IClusterable;
 
 /**
@@ -173,31 +174,40 @@ public class LazyInitProxyFactory
 		}
 		else if (IS_OBJENESIS_AVAILABLE && !hasNoArgConstructor(type))
 		{
-			return null; //ObjenesisProxyFactory.createProxy(type, locator, WicketNamingPolicy.INSTANCE);
+			return ObjenesisProxyFactory.createProxy(type, locator);
 		}
 		else
 		{
-			ClassLoader classLoader = resolveClassLoader();
-
-			Class<?> dynamicType = DYNAMIC_CLASS_CACHE.findOrInsert(classLoader,
-					new TypeCache.SimpleKey(type),
-					() -> BYTE_BUDDY
-							.subclass(type)
-							.implement(Serializable.class, ILazyInitProxy.class, IWriteReplace.class)
-							.method(ElementMatchers.any())
-							.intercept(MethodDelegation.to(new ByteBuddyInterceptor(type, locator)))
-							.make()
-							.load(classLoader, ClassLoadingStrategy.Default.INJECTION)
-							.getLoaded());
-
-			try {
-				return dynamicType.getDeclaredConstructor().newInstance();
-			} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+			ByteBuddyInterceptor interceptor = new ByteBuddyInterceptor(type, locator);
+			Class<?> proxyClass = createProxyClass(type, interceptor);
+
+			try
+			{
+				return proxyClass.getDeclaredConstructor().newInstance();
+			}
+			catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e)
+			{
 				throw new WicketRuntimeException(e);
 			}
 		}
 	}
 
+	public static Class<?> createProxyClass(Class<?> type, Object interceptor)
+	{
+		ClassLoader classLoader = resolveClassLoader();
+		Class<?> dynamicType = DYNAMIC_CLASS_CACHE.findOrInsert(classLoader,
+				new TypeCache.SimpleKey(type),
+				() -> BYTE_BUDDY
+						.subclass(type)
+						.implement(Serializable.class, ILazyInitProxy.class, IWriteReplace.class)
+						.method(ElementMatchers.any())
+						.intercept(MethodDelegation.to(interceptor))
+						.make()
+						.load(classLoader, ClassLoadingStrategy.Default.INJECTION)
+						.getLoaded());
+		return dynamicType;
+	}
+
 	private static ClassLoader resolveClassLoader()
 	{
 		ClassLoader classLoader = null;
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisCGLibInterceptor.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisByteBuddyInterceptor.java
similarity index 82%
rename from wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisCGLibInterceptor.java
rename to wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisByteBuddyInterceptor.java
index b4197ea..ee40a60 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisCGLibInterceptor.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisByteBuddyInterceptor.java
@@ -22,12 +22,12 @@ import org.apache.wicket.proxy.IProxyTargetLocator;
 import org.apache.wicket.proxy.LazyInitProxyFactory;
 
 /**
- * Method interceptor for proxies representing concrete object not backed by an interface. These
- * proxies are representing by cglib proxies.
+ * Method interceptor for proxies representing concrete object not backed by an interface.
+ * These proxies are representing by ByteBuddy proxies.
  */
-public class ObjenesisCGLibInterceptor extends LazyInitProxyFactory.AbstractByteBuddyInterceptor
+public class ObjenesisByteBuddyInterceptor extends LazyInitProxyFactory.AbstractByteBuddyInterceptor
 {
-	public ObjenesisCGLibInterceptor(Class<?> type, IProxyTargetLocator locator) {
+	public ObjenesisByteBuddyInterceptor(Class<?> type, IProxyTargetLocator locator) {
 		super(type, locator);
 	}
 
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java
index 2be6129..050c255 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java
@@ -16,13 +16,9 @@
  */
 package org.apache.wicket.proxy.objenesis;
 
-import java.io.Serializable;
-
-import javax.security.auth.callback.Callback;
-
-import org.apache.wicket.proxy.ILazyInitProxy;
+import net.bytebuddy.NamingStrategy;
 import org.apache.wicket.proxy.IProxyTargetLocator;
-import org.apache.wicket.proxy.LazyInitProxyFactory.IWriteReplace;
+import org.apache.wicket.proxy.LazyInitProxyFactory;
 import org.objenesis.ObjenesisStd;
 
 //import net.sf.cglib.core.NamingPolicy;
@@ -34,23 +30,12 @@ public class ObjenesisProxyFactory
 {
 	private static final ObjenesisStd OBJENESIS = new ObjenesisStd(false);
 
-	public static Object createProxy(final Class<?> type, final IProxyTargetLocator locator/*, NamingPolicy namingPolicy*/)
+	public static Object createProxy(final Class<?> type, final IProxyTargetLocator locator)
 	{
-		ObjenesisCGLibInterceptor handler = new ObjenesisCGLibInterceptor(type, locator);
+		ObjenesisByteBuddyInterceptor interceptor = new ObjenesisByteBuddyInterceptor(type, locator);
+		final Class<?> proxyClass = LazyInitProxyFactory.createProxyClass(type, interceptor);
 
-//		Enhancer e = new Enhancer();
-//		e.setInterfaces(new Class[]{Serializable.class, ILazyInitProxy.class, IWriteReplace.class});
-//		e.setSuperclass(type);
-//		e.setCallbackType(handler.getClass());
-//		e.setNamingPolicy(namingPolicy);
-//		Class<?> proxyClass = e.createClass();
-//
-//		Object instance = OBJENESIS.newInstance(proxyClass);
-//
-//		// set callbacks directly (WICKET-6607)
-//		((Factory) instance).setCallbacks(new Callback[]{handler});
-//
-//		return instance;
-		return null;
+		Object instance = OBJENESIS.newInstance(proxyClass);
+		return instance;
 	}
 }
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyReplacement.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyReplacement.java
index 7d2dc1d..f51258c 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyReplacement.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyReplacement.java
@@ -50,6 +50,6 @@ class ObjenesisProxyReplacement implements IClusterable
 							"] with the currently configured org.apache.wicket.application.IClassResolver");
 			throw new WicketRuntimeException(cause);
 		}
-		return ObjenesisProxyFactory.createProxy(clazz, locator/*, LazyInitProxyFactory.WicketNamingPolicy.INSTANCE*/);
+		return ObjenesisProxyFactory.createProxy(clazz, locator);
 	}
 }
diff --git a/wicket-jmx/pom.xml b/wicket-jmx/pom.xml
index c312f9b..b827a78 100644
--- a/wicket-jmx/pom.xml
+++ b/wicket-jmx/pom.xml
@@ -30,8 +30,9 @@
 
 	<dependencies>
 		<dependency>
-			<groupId>cglib</groupId>
-			<artifactId>cglib</artifactId>
+			<groupId>net.bytebuddy</groupId>
+			<artifactId>byte-buddy</artifactId>
+			<version>1.11.12</version>
 		</dependency>
 		<dependency>
 			<groupId>org.apache.wicket</groupId>
diff --git a/wicket-jmx/src/main/java/module-info.java b/wicket-jmx/src/main/java/module-info.java
index d07942d..a0366f8 100644
--- a/wicket-jmx/src/main/java/module-info.java
+++ b/wicket-jmx/src/main/java/module-info.java
@@ -20,7 +20,7 @@ module org.apache.wicket.jmx {
     requires org.apache.wicket.util;
     requires org.apache.wicket.core;
     requires org.slf4j;
-    requires cglib;
+    requires net.bytebuddy;
 
     provides org.apache.wicket.IInitializer with org.apache.wicket.jmx.Initializer;
     exports org.apache.wicket.jmx;
diff --git a/wicket-jmx/src/main/java/org/apache/wicket/jmx/Initializer.java b/wicket-jmx/src/main/java/org/apache/wicket/jmx/Initializer.java
index ca990ac..a2d9b3d 100644
--- a/wicket-jmx/src/main/java/org/apache/wicket/jmx/Initializer.java
+++ b/wicket-jmx/src/main/java/org/apache/wicket/jmx/Initializer.java
@@ -17,6 +17,7 @@
 package org.apache.wicket.jmx;
 
 import java.lang.management.ManagementFactory;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
@@ -30,9 +31,16 @@ import javax.management.MalformedObjectNameException;
 import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectName;
 
-import net.sf.cglib.core.DefaultNamingPolicy;
-import net.sf.cglib.core.Predicate;
-import net.sf.cglib.proxy.Enhancer;
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.NamingStrategy;
+import net.bytebuddy.TypeCache;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
+import net.bytebuddy.implementation.MethodDelegation;
+import net.bytebuddy.implementation.bind.annotation.AllArguments;
+import net.bytebuddy.implementation.bind.annotation.Origin;
+import net.bytebuddy.implementation.bind.annotation.RuntimeType;
+import net.bytebuddy.matcher.ElementMatchers;
 
 import org.apache.wicket.IInitializer;
 import org.apache.wicket.ThreadContext;
@@ -68,7 +76,24 @@ import org.slf4j.LoggerFactory;
  */
 public class Initializer implements IInitializer
 {
-	private static Logger log = LoggerFactory.getLogger(Initializer.class);
+	private static final Logger LOG = LoggerFactory.getLogger(Initializer.class);
+
+	/**
+	 * A cache used to store the dynamically generated classes by ByteBuddy.
+	 * Without this cache a new class will be generated for each proxy creation
+	 * and this will fill up the metaspace
+	 */
+	private static final TypeCache<TypeCache.SimpleKey> DYNAMIC_CLASS_CACHE = new TypeCache.WithInlineExpunction<>(TypeCache.Sort.SOFT);
+
+	private static final ByteBuddy BYTE_BUDDY = new ByteBuddy()
+			.with(new NamingStrategy.AbstractBase()
+			{
+				@Override
+				protected String name(TypeDescription superClass)
+				{
+					return superClass.getName().replace(".wrapper", "");
+				}
+			});
 
 	// It's best to store a reference to the MBeanServer rather than getting it
 	// over and over
@@ -90,7 +115,7 @@ public class Initializer implements IInitializer
 			}
 			catch (InstanceNotFoundException | MBeanRegistrationException e)
 			{
-				log.error(e.getMessage(), e);
+				LOG.error(e.getMessage(), e);
 			}
 		}
 	}
@@ -110,7 +135,7 @@ public class Initializer implements IInitializer
 			catch (SecurityException e)
 			{
 				// Ignore - we're not allowed to read this property.
-				log.warn("not allowed to read property wicket.mbean.server.agentid due to security settings; ignoring");
+				LOG.warn("not allowed to read property wicket.mbean.server.agentid due to security settings; ignoring");
 			}
 			if (agentId != null)
 			{
@@ -121,7 +146,7 @@ public class Initializer implements IInitializer
 				}
 				else
 				{
-					log.error("unable to find mbean server with agent id " + agentId);
+					LOG.error("unable to find mbean server with agent id {}", agentId);
 				}
 			}
 			if (mbeanServer == null)
@@ -134,7 +159,7 @@ public class Initializer implements IInitializer
 				catch (SecurityException e)
 				{
 					// Ignore - we're not allowed to read this property.
-					log.warn("not allowed to read property wicket.mbean.server.class due to security settings; ignoring");
+					LOG.warn("not allowed to read property wicket.mbean.server.class due to security settings; ignoring");
 				}
 				if (impl != null)
 				{
@@ -152,7 +177,7 @@ public class Initializer implements IInitializer
 					}
 					if (mbeanServer == null)
 					{
-						log.error("unable to find mbean server of type '{}'", impl);
+						LOG.error("unable to find mbean server of type '{}'", impl);
 					}
 				}
 			}
@@ -162,7 +187,7 @@ public class Initializer implements IInitializer
 				// never null
 			}
 
-			log.info("registering Wicket mbeans with server '{}'", mbeanServer);
+			LOG.info("registering Wicket mbeans with server '{}'", mbeanServer);
 
 			// register top level application object, but first check whether
 			// multiple instances of the same application (name) are running and
@@ -238,48 +263,67 @@ public class Initializer implements IInitializer
 		registered.add(objectName);
 	}
 
-	private Object createProxy(final org.apache.wicket.Application application, final Object o)
+	private static class Interceptor
 	{
-		Enhancer e = new Enhancer();
-		e.setInterfaces(o.getClass().getInterfaces());
-		e.setSuperclass(Object.class);
-		e.setCallback(new net.sf.cglib.proxy.InvocationHandler()
+		private final org.apache.wicket.Application application;
+		private final Object object;
+
+		private Interceptor(org.apache.wicket.Application application, Object object) {
+			this.application = application;
+			this.object = object;
+		}
+
+		@RuntimeType
+		public Object intercept(final @Origin Method method,
+								final @AllArguments Object[] args)
+				throws Throwable
 		{
-			@Override
-			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+			boolean existed = ThreadContext.exists();
+
+			if (existed == false)
 			{
-				boolean existed = ThreadContext.exists();
+				ThreadContext.setApplication(application);
+			}
 
+			try
+			{
+				return method.invoke(object, args);
+			}
+			finally
+			{
 				if (existed == false)
 				{
-					ThreadContext.setApplication(application);
-				}
-
-				try
-				{
-					return method.invoke(o, args);
+					ThreadContext.detach();
 				}
-				finally
-				{
-					if (existed == false)
-					{
-						ThreadContext.detach();
-					}
-				}
-			}
-		});
-		e.setNamingPolicy(new DefaultNamingPolicy()
-		{
-			@Override
-			public String getClassName(final String prefix, final String source, final Object key,
-				final Predicate names)
-			{
-				return o.getClass().getName().replace(".wrapper", "");
 			}
-		});
-		e.setClassLoader(resolveClassLoader());
+		}
+	}
+
+	private Object createProxy(final org.apache.wicket.Application application, final Object o)
+	{
+		Class<?> type = o.getClass();
+		ClassLoader classLoader = resolveClassLoader();
+
+		Class<?> proxyClass = DYNAMIC_CLASS_CACHE.findOrInsert(classLoader,
+				new TypeCache.SimpleKey(type),
+				() -> BYTE_BUDDY
+						.subclass(type)
+						.implement(type.getInterfaces())
+						.method(ElementMatchers.any())
+						.intercept(MethodDelegation.to(new Interceptor(application, o)))
+						.make()
+						.load(classLoader, ClassLoadingStrategy.Default.INJECTION)
+						.getLoaded());
 
-		return e.create();
+
+		try
+		{
+			return proxyClass.getDeclaredConstructor(org.apache.wicket.Application.class).newInstance(application);
+		}
+		catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e)
+		{
+			throw new WicketRuntimeException(e);
+		}
 	}
 
 	private static ClassLoader resolveClassLoader()
diff --git a/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/Application.java b/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/Application.java
index 56e0eff..3d23047 100644
--- a/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/Application.java
+++ b/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/Application.java
@@ -39,63 +39,42 @@ public class Application implements ApplicationMBean
 		this.application = application;
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationMBean#clearMarkupCache()
-	 */
 	@Override
 	public void clearMarkupCache() throws IOException
 	{
 		application.getMarkupSettings().getMarkupFactory().getMarkupCache().clear();
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationMBean#getApplicationClass()
-	 */
 	@Override
 	public String getApplicationClass() throws IOException
 	{
 		return application.getClass().getName();
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationMBean#getConfigurationType()
-	 */
 	@Override
 	public String getConfigurationType()
 	{
 		return application.getConfigurationType().name();
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationMBean#getHomePageClass()
-	 */
 	@Override
 	public String getHomePageClass() throws IOException
 	{
 		return application.getHomePage().getName();
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationMBean#getMarkupCacheSize()
-	 */
 	@Override
 	public int getMarkupCacheSize() throws IOException
 	{
 		return application.getMarkupSettings().getMarkupFactory().getMarkupCache().size();
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationMBean#getWicketVersion()
-	 */
 	@Override
 	public String getWicketVersion() throws IOException
 	{
 		return application.getFrameworkSettings().getVersion();
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationMBean#clearLocalizerCache()
-	 */
 	@Override
 	public void clearLocalizerCache() throws IOException
 	{
diff --git a/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/ApplicationSettings.java b/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/ApplicationSettings.java
index a6a0d4c..c5bda35 100644
--- a/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/ApplicationSettings.java
+++ b/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/ApplicationSettings.java
@@ -40,18 +40,12 @@ public class ApplicationSettings implements ApplicationSettingsMBean
 		this.application = application;
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationSettingsMBean#getAccessDeniedPage()
-	 */
 	@Override
 	public String getAccessDeniedPage()
 	{
 		return Classes.name(application.getApplicationSettings().getAccessDeniedPage());
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationSettingsMBean#getClassResolver()
-	 */
 	@Override
 	public String getClassResolver()
 	{
@@ -64,9 +58,6 @@ public class ApplicationSettings implements ApplicationSettingsMBean
 		return application.getApplicationSettings().getDefaultMaximumUploadSize().toString();
 	}
 
-	/**
-	 * @see org.apache.wicket.jmx.ApplicationSettingsMBean#getInternalErrorPage()
-	 */
 	@Override
 	public String getInternalErrorPage()
 	{

[wicket] 01/03: WICKET-6913 Replace CGLib with ByteBuddy in LazyInitProxyFactory

Posted by mg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch WICKET-6913-replace-cglib-with-bytebuddy-wicket-10.x
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit 44b9755a0cb8dbc909523c7e123cbf24c8381cf3
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Tue Aug 10 01:35:07 2021 +0300

    WICKET-6913 Replace CGLib with ByteBuddy in LazyInitProxyFactory
    
    TODO: Update the Objenesis related classes too and wicket-jmx
    (cherry picked from commit 8e1a15b3c08a59cc21c285440d1bf4d3b1876419)
---
 wicket-ioc/pom.xml                                 |   5 +-
 wicket-ioc/src/main/java/module-info.java          |   2 +-
 .../apache/wicket/proxy/LazyInitProxyFactory.java  | 176 ++++++++-------------
 .../proxy/objenesis/ObjenesisCGLibInterceptor.java |   2 +-
 .../proxy/objenesis/ObjenesisProxyFactory.java     |  39 ++---
 .../proxy/objenesis/ObjenesisProxyReplacement.java |   2 +-
 .../wicket/proxy/LazyInitProxyFactoryTest.java     |  51 +++---
 7 files changed, 123 insertions(+), 154 deletions(-)

diff --git a/wicket-ioc/pom.xml b/wicket-ioc/pom.xml
index a7da8d9..1a43586 100644
--- a/wicket-ioc/pom.xml
+++ b/wicket-ioc/pom.xml
@@ -33,8 +33,9 @@
 
 	<dependencies>
 		<dependency>
-			<groupId>cglib</groupId>
-			<artifactId>cglib</artifactId>
+			<groupId>net.bytebuddy</groupId>
+			<artifactId>byte-buddy</artifactId>
+			<version>1.11.12</version>
 		</dependency>
 		<dependency>
 			<groupId>jakarta.inject</groupId>
diff --git a/wicket-ioc/src/main/java/module-info.java b/wicket-ioc/src/main/java/module-info.java
index 6f7f7e1..b9814fe 100644
--- a/wicket-ioc/src/main/java/module-info.java
+++ b/wicket-ioc/src/main/java/module-info.java
@@ -18,7 +18,7 @@
 module org.apache.wicket.ioc {
     requires org.apache.wicket.util;
     requires org.apache.wicket.core;
-    requires cglib;
+    requires net.bytebuddy;
     requires org.objenesis;
 
     exports org.apache.wicket.injection;
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java
index ccc7769..d478a25 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java
@@ -22,27 +22,26 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
 import java.util.Arrays;
 import java.util.List;
 
-import net.sf.cglib.core.DefaultNamingPolicy;
-import net.sf.cglib.core.Predicate;
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.CallbackFilter;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-import net.sf.cglib.proxy.NoOp;
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.NamingStrategy;
+import net.bytebuddy.TypeCache;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
+import net.bytebuddy.implementation.MethodDelegation;
+import net.bytebuddy.implementation.bind.annotation.AllArguments;
+import net.bytebuddy.implementation.bind.annotation.Origin;
+import net.bytebuddy.implementation.bind.annotation.RuntimeType;
+import net.bytebuddy.matcher.ElementMatchers;
 
 import org.apache.wicket.Application;
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.core.util.lang.WicketObjects;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.proxy.objenesis.ObjenesisProxyFactory;
 import org.apache.wicket.util.io.IClusterable;
-import org.apache.wicket.util.string.Strings;
 
 /**
  * A factory class that creates lazy init proxies given a type and a {@link IProxyTargetLocator}
@@ -112,14 +111,19 @@ public class LazyInitProxyFactory
 	/**
 	 * Primitive java types and their object wrappers
 	 */
-	@SuppressWarnings({ "unchecked", "rawtypes" })
-	private static final List PRIMITIVES = Arrays.asList(String.class, byte.class, Byte.class,
+	private static final List<Class<?>> PRIMITIVES = Arrays.asList(String.class, byte.class, Byte.class,
 		short.class, Short.class, int.class, Integer.class, long.class, Long.class, float.class,
 		Float.class, double.class, Double.class, char.class, Character.class, boolean.class,
 		Boolean.class);
 
-	private static final int CGLIB_CALLBACK_NO_OVERRIDE = 0;
-	private static final int CGLIB_CALLBACK_HANDLER = 1;
+	/**
+	 * A cache used to store the dynamically generated classes by ByteBuddy.
+	 * Without this cache a new class will be generated for each proxy creation
+	 * and this will fill up the metaspace
+	 */
+	private static final TypeCache<TypeCache.SimpleKey> DYNAMIC_CLASS_CACHE = new TypeCache.WithInlineExpunction<>(TypeCache.Sort.SOFT);
+
+	private static final ByteBuddy BYTE_BUDDY = new ByteBuddy().with(WicketNamingPolicy.INSTANCE);
 
 	private static final boolean IS_OBJENESIS_AVAILABLE = isObjenesisAvailable();
 
@@ -169,26 +173,28 @@ public class LazyInitProxyFactory
 		}
 		else if (IS_OBJENESIS_AVAILABLE && !hasNoArgConstructor(type))
 		{
-			return ObjenesisProxyFactory.createProxy(type, locator, WicketNamingPolicy.INSTANCE);
+			return null; //ObjenesisProxyFactory.createProxy(type, locator, WicketNamingPolicy.INSTANCE);
 		}
 		else
 		{
-			CGLibInterceptor handler = new CGLibInterceptor(type, locator);
-
-			Callback[] callbacks = new Callback[2];
-			callbacks[CGLIB_CALLBACK_NO_OVERRIDE] = SerializableNoOpCallback.INSTANCE;
-			callbacks[CGLIB_CALLBACK_HANDLER] = handler;
-
-			Enhancer e = new Enhancer();
-			e.setClassLoader(resolveClassLoader());
-			e.setInterfaces(new Class[] { Serializable.class, ILazyInitProxy.class,
-					IWriteReplace.class });
-			e.setSuperclass(type);
-			e.setCallbackFilter(NoOpForProtectedMethodsCGLibCallbackFilter.INSTANCE);
-			e.setCallbacks(callbacks);
-			e.setNamingPolicy(WicketNamingPolicy.INSTANCE);
-
-			return e.create();
+			ClassLoader classLoader = resolveClassLoader();
+
+			Class<?> dynamicType = DYNAMIC_CLASS_CACHE.findOrInsert(classLoader,
+					new TypeCache.SimpleKey(type),
+					() -> BYTE_BUDDY
+							.subclass(type)
+							.implement(Serializable.class, ILazyInitProxy.class, IWriteReplace.class)
+							.method(ElementMatchers.any())
+							.intercept(MethodDelegation.to(new ByteBuddyInterceptor(type, locator)))
+							.make()
+							.load(classLoader, ClassLoadingStrategy.Default.INJECTION)
+							.getLoaded());
+
+			try {
+				return dynamicType.getDeclaredConstructor().newInstance();
+			} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+				throw new WicketRuntimeException(e);
+			}
 		}
 	}
 
@@ -286,15 +292,13 @@ public class LazyInitProxyFactory
 	}
 
 	/**
-	 * Method interceptor for proxies representing concrete object not backed by an interface. These
-	 * proxies are represented by cglib proxies.
+	 * Method interceptor for proxies representing concrete object not backed by an interface.
+	 * These proxies are represented by ByteBuddy proxies.
 	 * 
 	 * @author Igor Vaynberg (ivaynberg)
-	 * 
 	 */
-	public abstract static class AbstractCGLibInterceptor
+	public abstract static class AbstractByteBuddyInterceptor
 		implements
-			MethodInterceptor,
 			ILazyInitProxy,
 			Serializable,
 			IWriteReplace
@@ -316,20 +320,17 @@ public class LazyInitProxyFactory
 		 * @param locator
 		 *            object locator used to locate the object this proxy represents
 		 */
-		public AbstractCGLibInterceptor(final Class<?> type, final IProxyTargetLocator locator)
+		public AbstractByteBuddyInterceptor(final Class<?> type, final IProxyTargetLocator locator)
 		{
 			super();
 			typeName = type.getName();
 			this.locator = locator;
 		}
 
-		/**
-		 * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object,
-		 *      java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)
-		 */
-		@Override
-		public Object intercept(final Object object, final Method method, final Object[] args,
-			final MethodProxy proxy) throws Throwable
+		@RuntimeType
+		public Object intercept(final @Origin Method method,
+								final @AllArguments Object[] args)
+				throws Throwable
 		{
 			if (isFinalizeMethod(method))
 			{
@@ -361,12 +362,10 @@ public class LazyInitProxyFactory
 			{
 				target = locator.locateProxyTarget();
 			}
-			return proxy.invoke(target, args);
+
+			return method.invoke(target, args);
 		}
 
-		/**
-		 * @see org.apache.wicket.proxy.ILazyInitProxy#getObjectLocator()
-		 */
 		@Override
 		public IProxyTargetLocator getObjectLocator()
 		{
@@ -375,21 +374,18 @@ public class LazyInitProxyFactory
 	}
 
 	/**
-	 * Method interceptor for proxies representing concrete object not backed by an interface. These
-	 * proxies are representing by cglib proxies.
+	 * Method interceptor for proxies representing concrete object not backed by an interface.
+	 * These proxies are representing by ByteBuddy proxies.
 	 *
 	 * @author Igor Vaynberg (ivaynberg)
 	 */
-	protected static class CGLibInterceptor extends AbstractCGLibInterceptor
+	protected static class ByteBuddyInterceptor extends AbstractByteBuddyInterceptor
 	{
-		public CGLibInterceptor(Class<?> type, IProxyTargetLocator locator)
+		public ByteBuddyInterceptor(Class<?> type, IProxyTargetLocator locator)
 		{
 			super(type, locator);
 		}
 
-		/**
-		 * @see org.apache.wicket.proxy.LazyInitProxyFactory.IWriteReplace#writeReplace()
-		 */
 		@Override
 		public Object writeReplace() throws ObjectStreamException
 		{
@@ -398,47 +394,6 @@ public class LazyInitProxyFactory
 	}
 
 	/**
-	 * Serializable implementation of the NoOp callback.
-	 */
-	public static class SerializableNoOpCallback implements NoOp, Serializable
-	{
-		private static final long serialVersionUID = 1L;
-
-		private static final NoOp INSTANCE = new SerializableNoOpCallback();
-	}
-
-	/**
-	 * CGLib callback filter which does not intercept protected methods.
-	 * 
-	 * Protected methods need to be called with invokeSuper() instead of invoke().
-	 * When invoke() is called on a protected method, it throws an "IllegalArgumentException:
-	 * Protected method" exception.
-	 * That being said, we do not need to intercept the protected methods so this callback filter
-	 * is designed to use a NoOp callback for protected methods.
-	 * 
-	 * @see <a href="http://comments.gmane.org/gmane.comp.java.cglib.devel/720">Discussion about
-	 * this very issue in Spring AOP</a>
-	 * @see <a href="https://github.com/wicketstuff/core/wiki/SpringReference">The WicketStuff
-	 * SpringReference project which worked around this issue</a>
-	 */
-	private static class NoOpForProtectedMethodsCGLibCallbackFilter implements CallbackFilter
-	{
-		private static final CallbackFilter INSTANCE = new NoOpForProtectedMethodsCGLibCallbackFilter();
-
-		@Override
-		public int accept(Method method) {
-			if (Modifier.isProtected(method.getModifiers()))
-			{
-				return CGLIB_CALLBACK_NO_OVERRIDE;
-			}
-			else
-			{
-				return CGLIB_CALLBACK_HANDLER;
-			}
-		}
-	}
-
-	/**
 	 * Invocation handler for proxies representing interface based object. For interface backed
 	 * objects dynamic jdk proxies are used.
 	 * 
@@ -526,18 +481,12 @@ public class LazyInitProxyFactory
 			}
 		}
 
-		/**
-		 * @see org.apache.wicket.proxy.ILazyInitProxy#getObjectLocator()
-		 */
 		@Override
 		public IProxyTargetLocator getObjectLocator()
 		{
 			return locator;
 		}
 
-		/**
-		 * @see org.apache.wicket.proxy.LazyInitProxyFactory.IWriteReplace#writeReplace()
-		 */
 		@Override
 		public Object writeReplace() throws ObjectStreamException
 		{
@@ -611,7 +560,7 @@ public class LazyInitProxyFactory
 			(method.getParameterTypes().length == 0) && method.getName().equals("writeReplace");
 	}
 
-	public static final class WicketNamingPolicy extends DefaultNamingPolicy
+	public static final class WicketNamingPolicy extends NamingStrategy.AbstractBase
 	{
 		public static final WicketNamingPolicy INSTANCE = new WicketNamingPolicy();
 
@@ -621,14 +570,23 @@ public class LazyInitProxyFactory
 		}
 
 		@Override
-		public String getClassName(final String prefix, final String source, final Object key,
-				final Predicate names)
-		{
+		protected String name(TypeDescription superClass) {
+			final String prefix = superClass.getName();
 			int lastIdxOfDot = prefix.lastIndexOf('.');
 			String packageName = prefix.substring(0, lastIdxOfDot);
 			String className = prefix.substring(lastIdxOfDot + 1);
-			String newPrefix = packageName + ".Wicket_Proxy_" + className;
-			return super.getClassName(newPrefix, source, key, names);
+			String name = packageName + ".Wicket_Proxy_" + className;
+			return name;
+		}
+
+		@Override
+		public String redefine(TypeDescription typeDescription) {
+			return typeDescription.getName();
+		}
+
+		@Override
+		public String rebase(TypeDescription typeDescription) {
+			return typeDescription.getName();
 		}
 	}
 
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisCGLibInterceptor.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisCGLibInterceptor.java
index 63975a0..b4197ea 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisCGLibInterceptor.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisCGLibInterceptor.java
@@ -25,7 +25,7 @@ import org.apache.wicket.proxy.LazyInitProxyFactory;
  * Method interceptor for proxies representing concrete object not backed by an interface. These
  * proxies are representing by cglib proxies.
  */
-public class ObjenesisCGLibInterceptor extends LazyInitProxyFactory.AbstractCGLibInterceptor
+public class ObjenesisCGLibInterceptor extends LazyInitProxyFactory.AbstractByteBuddyInterceptor
 {
 	public ObjenesisCGLibInterceptor(Class<?> type, IProxyTargetLocator locator) {
 		super(type, locator);
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java
index 730da6b..2be6129 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java
@@ -18,36 +18,39 @@ package org.apache.wicket.proxy.objenesis;
 
 import java.io.Serializable;
 
+import javax.security.auth.callback.Callback;
+
 import org.apache.wicket.proxy.ILazyInitProxy;
 import org.apache.wicket.proxy.IProxyTargetLocator;
 import org.apache.wicket.proxy.LazyInitProxyFactory.IWriteReplace;
 import org.objenesis.ObjenesisStd;
 
-import net.sf.cglib.core.NamingPolicy;
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Factory;
+//import net.sf.cglib.core.NamingPolicy;
+//import net.sf.cglib.proxy.Callback;
+//import net.sf.cglib.proxy.Enhancer;
+//import net.sf.cglib.proxy.Factory;
 
 public class ObjenesisProxyFactory
 {
 	private static final ObjenesisStd OBJENESIS = new ObjenesisStd(false);
 
-	public static Object createProxy(final Class<?> type, final IProxyTargetLocator locator, NamingPolicy namingPolicy)
+	public static Object createProxy(final Class<?> type, final IProxyTargetLocator locator/*, NamingPolicy namingPolicy*/)
 	{
 		ObjenesisCGLibInterceptor handler = new ObjenesisCGLibInterceptor(type, locator);
 
-		Enhancer e = new Enhancer();
-		e.setInterfaces(new Class[]{Serializable.class, ILazyInitProxy.class, IWriteReplace.class});
-		e.setSuperclass(type);
-		e.setCallbackType(handler.getClass());
-		e.setNamingPolicy(namingPolicy);
-		Class<?> proxyClass = e.createClass();
-		
-		Object instance = OBJENESIS.newInstance(proxyClass);
-
-		// set callbacks directly (WICKET-6607) 
-		((Factory) instance).setCallbacks(new Callback[]{handler});
-		
-		return instance;
+//		Enhancer e = new Enhancer();
+//		e.setInterfaces(new Class[]{Serializable.class, ILazyInitProxy.class, IWriteReplace.class});
+//		e.setSuperclass(type);
+//		e.setCallbackType(handler.getClass());
+//		e.setNamingPolicy(namingPolicy);
+//		Class<?> proxyClass = e.createClass();
+//
+//		Object instance = OBJENESIS.newInstance(proxyClass);
+//
+//		// set callbacks directly (WICKET-6607)
+//		((Factory) instance).setCallbacks(new Callback[]{handler});
+//
+//		return instance;
+		return null;
 	}
 }
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyReplacement.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyReplacement.java
index cbffee8..7d2dc1d 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyReplacement.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyReplacement.java
@@ -50,6 +50,6 @@ class ObjenesisProxyReplacement implements IClusterable
 							"] with the currently configured org.apache.wicket.application.IClassResolver");
 			throw new WicketRuntimeException(cause);
 		}
-		return ObjenesisProxyFactory.createProxy(clazz, locator, LazyInitProxyFactory.WicketNamingPolicy.INSTANCE);
+		return ObjenesisProxyFactory.createProxy(clazz, locator/*, LazyInitProxyFactory.WicketNamingPolicy.INSTANCE*/);
 	}
 }
diff --git a/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java b/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java
index 5483ce4..6b907d2 100644
--- a/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java
+++ b/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java
@@ -25,6 +25,7 @@ import org.apache.wicket.proxy.util.InterfaceObject;
 import org.apache.wicket.proxy.util.ObjectMethodTester;
 import org.junit.jupiter.api.Test;
 
+import java.io.ObjectStreamException;
 import java.lang.reflect.Proxy;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -39,11 +40,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
  * @author Igor Vaynberg (ivaynberg)
  * 
  */
-public class LazyInitProxyFactoryTest
+class LazyInitProxyFactoryTest
 {
 	private static InterfaceObject interfaceObject = new InterfaceObject("interface");
 
-	private static ConcreteObject concreteObject = new ConcreteObject("concrete");
+	private static final ConcreteObject concreteObject = new ConcreteObject("concrete");
 
 	private static final PackagePrivateConcreteObject PACKAGE_PRIVATE_CONCRETE_OBJECT = new PackagePrivateConcreteObject("package-private-concrete");
 
@@ -58,7 +59,7 @@ public class LazyInitProxyFactoryTest
 		}
 	};
 
-	private static IProxyTargetLocator concreteObjectLocator = new IProxyTargetLocator()
+	private static final IProxyTargetLocator concreteObjectLocator = new IProxyTargetLocator()
 	{
 		private static final long serialVersionUID = 1L;
 
@@ -67,6 +68,11 @@ public class LazyInitProxyFactoryTest
 		{
 			return LazyInitProxyFactoryTest.concreteObject;
 		}
+
+		// This method is needed to prevent (de)serialization of this locator instance in #testByteBuddyInterceptorReplacement()
+		private Object readResolve() throws ObjectStreamException {
+			return concreteObjectLocator;
+		}
 	};
 
 	private final static IProxyTargetLocator PACKAGE_PRIVATE_CONCRETE_OBJECT_LOCATOR = new IProxyTargetLocator()
@@ -95,7 +101,7 @@ public class LazyInitProxyFactoryTest
 	 * Tests lazy init proxy to represent interfaces
 	 */
 	@Test
-	public void testInterfaceProxy()
+	void testInterfaceProxy()
 	{
 		// test proxy creation for an interface class
 		IInterface proxy = (IInterface)LazyInitProxyFactory.createProxy(IInterface.class,
@@ -106,15 +112,15 @@ public class LazyInitProxyFactoryTest
 
 		// test proxy implements ILazyInitProxy
 		assertTrue(proxy instanceof ILazyInitProxy);
-		assertTrue(((ILazyInitProxy)proxy).getObjectLocator() == interfaceObjectLocator);
+		assertSame(((ILazyInitProxy) proxy).getObjectLocator(), interfaceObjectLocator);
 
 		// test method invocation
-		assertEquals(proxy.getMessage(), "interface");
+		assertEquals("interface", proxy.getMessage());
 
 		// test serialization
 		IInterface proxy2 = WicketObjects.cloneObject(proxy);
-		assertTrue(proxy != proxy2);
-		assertEquals(proxy2.getMessage(), "interface");
+		assertNotSame(proxy, proxy2);
+		assertEquals("interface", proxy2.getMessage());
 
 		// test equals/hashcode method interception
 		final IObjectMethodTester tester = new ObjectMethodTester();
@@ -143,32 +149,33 @@ public class LazyInitProxyFactoryTest
 	 * Tests lazy init proxy to represent concrete objects
 	 */
 	@Test
-	public void testConcreteProxy()
+	void testConcreteProxy()
 	{
 		ConcreteObject proxy = (ConcreteObject)LazyInitProxyFactory.createProxy(
 			ConcreteObject.class, concreteObjectLocator);
 
 		// test proxy implements ILazyInitProxy
 		assertTrue(proxy instanceof ILazyInitProxy);
-		assertSame(((ILazyInitProxy) proxy).getObjectLocator(), concreteObjectLocator);
+		final IProxyTargetLocator objectLocator = ((ILazyInitProxy) proxy).getObjectLocator();
+		assertSame(objectLocator, concreteObjectLocator);
 
 		// test we do not have a jdk dynamic proxy
 		assertFalse(Proxy.isProxyClass(proxy.getClass()));
 
 		// test method invocation
-		assertEquals(proxy.getMessage(), "concrete");
+		assertEquals("concrete", proxy.getMessage());
 
 		// test serialization
 		ConcreteObject proxy2 = WicketObjects.cloneObject(proxy);
 		assertNotSame(proxy, proxy2);
-		assertEquals(proxy2.getMessage(), "concrete");
+		assertEquals("concrete", proxy2.getMessage());
 
 		// test equals/hashcode method interception
 		final IObjectMethodTester tester = new ObjectMethodTester();
 		assertTrue(tester.isValid());
 
 		// test only a single class is generated,
-		// otherwise permgen space will fill up with each proxy
+		// otherwise meta space will fill up with each proxy
 		assertSame(proxy.getClass(), LazyInitProxyFactory.createProxy(
 			ConcreteObject.class, concreteObjectLocator).getClass());
 
@@ -197,25 +204,25 @@ public class LazyInitProxyFactoryTest
 	 * https://issues.apache.org/jira/browse/WICKET-4324
 	 */
 	@Test
-	public void testPackagePrivateConcreteProxy()
+	void testPackagePrivateConcreteProxy()
 	{
 		PackagePrivateConcreteObject proxy = (PackagePrivateConcreteObject)LazyInitProxyFactory.createProxy(
 				PackagePrivateConcreteObject.class, PACKAGE_PRIVATE_CONCRETE_OBJECT_LOCATOR);
 
 		// test proxy implements ILazyInitProxy
 		assertTrue(proxy instanceof ILazyInitProxy);
-		assertTrue(((ILazyInitProxy)proxy).getObjectLocator() == PACKAGE_PRIVATE_CONCRETE_OBJECT_LOCATOR);
+		assertSame(((ILazyInitProxy)proxy).getObjectLocator(), PACKAGE_PRIVATE_CONCRETE_OBJECT_LOCATOR);
 
 		// test we do not have a jdk dynamic proxy
 		assertFalse(Proxy.isProxyClass(proxy.getClass()));
 
 		// test method invocation
-		assertEquals(proxy.getMessage(), "package-private-concrete");
+		assertEquals("package-private-concrete", proxy.getMessage());
 
 		// test serialization
 		PackagePrivateConcreteObject proxy2 = WicketObjects.cloneObject(proxy);
-		assertTrue(proxy != proxy2);
-		assertEquals(proxy2.getMessage(), "package-private-concrete");
+		assertNotSame(proxy, proxy2);
+		assertEquals("package-private-concrete", proxy2.getMessage());
 
 		// test equals/hashcode method interception
 		final IObjectMethodTester tester = new ObjectMethodTester();
@@ -246,23 +253,23 @@ public class LazyInitProxyFactoryTest
 	}
 
 	/**
-	 * Tests lazy init concrete replacement replacement
+	 * Tests lazy init concrete replacement
 	 */
 	@Test
-	public void testCGLibInterceptorReplacement()
+	void testByteBuddyInterceptorReplacement()
 	{
 		ProxyReplacement ser = new ProxyReplacement(ConcreteObject.class.getName(),
 			concreteObjectLocator);
 
 		Object proxy2 = WicketObjects.cloneObject(ser);
-		assertEquals(((ConcreteObject)proxy2).getMessage(), "concrete");
+		assertEquals("concrete", ((ConcreteObject)proxy2).getMessage());
 	}
 
 	/**
 	 * Tests String beans.
 	 */
 	@Test
-	public void testStringProxy()
+	void testStringProxy()
 	{
 		// We special-case String objects to avoid proxying them, as they're
 		// final.

[wicket] 03/03: WICKET-6913 Replace CGLib with ByteBuddy

Posted by mg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch WICKET-6913-replace-cglib-with-bytebuddy-wicket-10.x
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit f16168bee0a56ef08ab2fc36f7a6ef669a7b8463
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Thu Aug 12 14:05:07 2021 +0300

    WICKET-6913 Replace CGLib with ByteBuddy
    
    Replace all occurrences of "cglib" with "byte-buddy".
    Merge AbstractByteBuddyInterceptor and ByteBuddyInterceptor. I see no need of both. If an application needs special impl of #writeReplace() then it could extend ByteBuddyInterceptor and override it.
    Improve Maven dependency management related to byte-buddy.
---
 NOTICE                                             |  8 ++++----
 README.md                                          |  4 ++--
 pom.xml                                            | 12 +++++------
 wicket-examples/src/main/resources/META-INF/NOTICE | 10 ++++-----
 wicket-ioc/pom.xml                                 |  9 ++++----
 .../apache/wicket/proxy/LazyInitProxyFactory.java  | 24 +++++-----------------
 .../objenesis/ObjenesisByteBuddyInterceptor.java   |  2 +-
 .../proxy/objenesis/ObjenesisProxyFactory.java     |  6 ------
 .../wicket/injection/util/MockDependency.java      |  2 +-
 .../wicket/proxy/PackagePrivateConcreteObject.java |  2 +-
 .../apache/wicket/proxy/util/ConcreteObject.java   |  2 +-
 wicket-jmx/pom.xml                                 |  1 -
 .../annot/SpringBeanWithGenericsTest.java          |  2 +-
 13 files changed, 31 insertions(+), 53 deletions(-)

diff --git a/NOTICE b/NOTICE
index 3e462db..b212522 100644
--- a/NOTICE
+++ b/NOTICE
@@ -53,11 +53,11 @@ src/./wicket-examples
    This product includes software developed by the Spring Framework Project
    (http://www.springframework.org).
 
-   This product includes software developed by the CGLib Project
-   (http://cglib.sourceforge.net).
+   This product includes software developed by the ByteBuddy Project
+   (https://bytebuddy.net/).
 
-   This product includes ASM, released under a BSD style license (http://asm.objectweb.org).
-   Copyright (c) 2000-2005 INRIA, France Telecom
+   This product includes ASM, released under a BSD style license (https://asm.ow2.io/).
+   Copyright (c) 2000-2011 INRIA, France Telecom
 
    This product includes jhighlight (https://jhighlight.dev.java.net/)
    which is released under CDDL 1.0 license (http://www.opensource.org/licenses/cddl1.php).
diff --git a/README.md b/README.md
index 01e9982..32b9555 100644
--- a/README.md
+++ b/README.md
@@ -158,8 +158,8 @@ the src/ folder.
 
  - wicket-ioc:
 
-    cglib 3.1 (http://cglib.sourceforge.net/) and 
-    asm-util 5.0.3 (http://asm.objectweb.org/)
+    byte-buddy 1.11.12 (https://bytebuddy.net/) and 
+    asm-util 9.1 (https://asm.ow2.io/)
 
  - wicket-spring:
 
diff --git a/pom.xml b/pom.xml
index 6564ee5..551ddc3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -137,8 +137,8 @@
 		<asm.version>9.1</asm.version>
 		<aspectj.version>1.9.6</aspectj.version>
 		<assertj-core.version>3.19.0</assertj-core.version>
+		<byte-buddy.version>1.11.12</byte-buddy.version>
 		<cdi-unit.version>4.1.0</cdi-unit.version>
-		<cglib.version>3.3.0</cglib.version>
 		<commons-collections.version>3.2.2</commons-collections.version>
 		<commons-collections4.version>4.4</commons-collections4.version>
 		<commons-fileupload.version>1.4</commons-fileupload.version>
@@ -259,11 +259,6 @@
 				<scope>provided</scope>
 			</dependency>
 			<dependency>
-				<groupId>cglib</groupId>
-				<artifactId>cglib</artifactId>
-				<version>${cglib.version}</version>
-			</dependency>
-			<dependency>
 				<groupId>com.fasterxml.jackson.core</groupId>
 				<artifactId>jackson-databind</artifactId>
 				<version>${jackson.version}</version>
@@ -323,6 +318,11 @@
 				<optional>true</optional>
 			</dependency>
 			<dependency>
+				<groupId>net.bytebuddy</groupId>
+				<artifactId>byte-buddy</artifactId>
+				<version>${byte-buddy.version}</version>
+			</dependency>
+			<dependency>
 				<groupId>org.apache.commons</groupId>
 				<artifactId>commons-collections4</artifactId>
 				<version>${commons-collections4.version}</version>
diff --git a/wicket-examples/src/main/resources/META-INF/NOTICE b/wicket-examples/src/main/resources/META-INF/NOTICE
index 619dd91..08cc74b 100644
--- a/wicket-examples/src/main/resources/META-INF/NOTICE
+++ b/wicket-examples/src/main/resources/META-INF/NOTICE
@@ -26,11 +26,11 @@
    This product includes software developed by the Spring Framework Project
    (http://www.springframework.org).
 
-   This product includes software developed by the CGLib Project
-   (http://cglib.sourceforge.net).
+   This product includes software developed by the ByteBiddy Project
+   (https://bytebuddy.net/).
 
-   This product includes ASM, released under a BSD style license (http://asm.objectweb.org).
-   Copyright (c) 2000-2005 INRIA, France Telecom
+   This product includes ASM, released under a BSD style license (https://asm.ow2.io/).
+   Copyright (c) 2000-2011 INRIA, France Telecom
 
    This product includes jhighlight (https://jhighlight.dev.java.net/)
    which is released under CDDL 1.0 license (http://www.opensource.org/licenses/cddl1.php).
@@ -42,4 +42,4 @@
    jQuery Foundation, Inc, http://jquery.org/license
 
    Contains qunit.css released under a MIT style license.
-   jQuery Foundation, Inc, http://jquery.org/license
\ No newline at end of file
+   jQuery Foundation, Inc, http://jquery.org/license
diff --git a/wicket-ioc/pom.xml b/wicket-ioc/pom.xml
index 1a43586..6e3697a 100644
--- a/wicket-ioc/pom.xml
+++ b/wicket-ioc/pom.xml
@@ -33,15 +33,14 @@
 
 	<dependencies>
 		<dependency>
-			<groupId>net.bytebuddy</groupId>
-			<artifactId>byte-buddy</artifactId>
-			<version>1.11.12</version>
-		</dependency>
-		<dependency>
 			<groupId>jakarta.inject</groupId>
 			<artifactId>jakarta.inject-api</artifactId>
 		</dependency>
 		<dependency>
+			<groupId>net.bytebuddy</groupId>
+			<artifactId>byte-buddy</artifactId>
+		</dependency>
+		<dependency>
 			<groupId>org.apache.wicket</groupId>
 			<artifactId>wicket-core</artifactId>
 			<version>${project.version}</version>
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java
index 8a24bc2..e33e67d 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java
@@ -53,7 +53,7 @@ import org.apache.wicket.util.io.IClusterable;
  * forwarded.
  * <p>
  * This factory creates two kinds of proxies: A standard dynamic proxy when the specified type is an
- * interface, and a CGLib proxy when the specified type is a concrete class.
+ * interface, and a ByteBuddy proxy when the specified type is a concrete class.
  * <p>
  * The general use case for such a proxy is to represent a dependency that should not be serialized
  * with a wicket page or {@link IModel}. The solution is to serialize the proxy and the
@@ -307,7 +307,7 @@ public class LazyInitProxyFactory
 	 * 
 	 * @author Igor Vaynberg (ivaynberg)
 	 */
-	public abstract static class AbstractByteBuddyInterceptor
+	public static class ByteBuddyInterceptor
 		implements
 			ILazyInitProxy,
 			Serializable,
@@ -330,7 +330,7 @@ public class LazyInitProxyFactory
 		 * @param locator
 		 *            object locator used to locate the object this proxy represents
 		 */
-		public AbstractByteBuddyInterceptor(final Class<?> type, final IProxyTargetLocator locator)
+		public ByteBuddyInterceptor(final Class<?> type, final IProxyTargetLocator locator)
 		{
 			super();
 			typeName = type.getName();
@@ -381,20 +381,6 @@ public class LazyInitProxyFactory
 		{
 			return locator;
 		}
-	}
-
-	/**
-	 * Method interceptor for proxies representing concrete object not backed by an interface.
-	 * These proxies are representing by ByteBuddy proxies.
-	 *
-	 * @author Igor Vaynberg (ivaynberg)
-	 */
-	protected static class ByteBuddyInterceptor extends AbstractByteBuddyInterceptor
-	{
-		public ByteBuddyInterceptor(Class<?> type, IProxyTargetLocator locator)
-		{
-			super(type, locator);
-		}
 
 		@Override
 		public Object writeReplace() throws ObjectStreamException
@@ -581,11 +567,11 @@ public class LazyInitProxyFactory
 
 		@Override
 		protected String name(TypeDescription superClass) {
-			final String prefix = superClass.getName();
+			String prefix = superClass.getName();
 			int lastIdxOfDot = prefix.lastIndexOf('.');
 			String packageName = prefix.substring(0, lastIdxOfDot);
 			String className = prefix.substring(lastIdxOfDot + 1);
-			String name = packageName + ".Wicket_Proxy_" + className;
+			String name = "bytebuddy_generated_wicket_proxy." + packageName + "." + className;
 			return name;
 		}
 
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisByteBuddyInterceptor.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisByteBuddyInterceptor.java
index ee40a60..e2bdbff 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisByteBuddyInterceptor.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisByteBuddyInterceptor.java
@@ -25,7 +25,7 @@ import org.apache.wicket.proxy.LazyInitProxyFactory;
  * Method interceptor for proxies representing concrete object not backed by an interface.
  * These proxies are representing by ByteBuddy proxies.
  */
-public class ObjenesisByteBuddyInterceptor extends LazyInitProxyFactory.AbstractByteBuddyInterceptor
+public class ObjenesisByteBuddyInterceptor extends LazyInitProxyFactory.ByteBuddyInterceptor
 {
 	public ObjenesisByteBuddyInterceptor(Class<?> type, IProxyTargetLocator locator) {
 		super(type, locator);
diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java
index 050c255..89f79f0 100644
--- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java
+++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/objenesis/ObjenesisProxyFactory.java
@@ -16,16 +16,10 @@
  */
 package org.apache.wicket.proxy.objenesis;
 
-import net.bytebuddy.NamingStrategy;
 import org.apache.wicket.proxy.IProxyTargetLocator;
 import org.apache.wicket.proxy.LazyInitProxyFactory;
 import org.objenesis.ObjenesisStd;
 
-//import net.sf.cglib.core.NamingPolicy;
-//import net.sf.cglib.proxy.Callback;
-//import net.sf.cglib.proxy.Enhancer;
-//import net.sf.cglib.proxy.Factory;
-
 public class ObjenesisProxyFactory
 {
 	private static final ObjenesisStd OBJENESIS = new ObjenesisStd(false);
diff --git a/wicket-ioc/src/test/java/org/apache/wicket/injection/util/MockDependency.java b/wicket-ioc/src/test/java/org/apache/wicket/injection/util/MockDependency.java
index cc22135..70daa3b 100644
--- a/wicket-ioc/src/test/java/org/apache/wicket/injection/util/MockDependency.java
+++ b/wicket-ioc/src/test/java/org/apache/wicket/injection/util/MockDependency.java
@@ -27,7 +27,7 @@ public class MockDependency
 	private String message;
 
 	/**
-	 * Empty default constructor. It is required by cglib to create a proxy.
+	 * Empty default constructor. It is required by byte-buddy to create a proxy.
 	 */
 	public MockDependency()
 	{
diff --git a/wicket-ioc/src/test/java/org/apache/wicket/proxy/PackagePrivateConcreteObject.java b/wicket-ioc/src/test/java/org/apache/wicket/proxy/PackagePrivateConcreteObject.java
index 3b31e63..5f87e29 100644
--- a/wicket-ioc/src/test/java/org/apache/wicket/proxy/PackagePrivateConcreteObject.java
+++ b/wicket-ioc/src/test/java/org/apache/wicket/proxy/PackagePrivateConcreteObject.java
@@ -26,7 +26,7 @@ class PackagePrivateConcreteObject
 	private String message;
 
 	/**
-	 * Empty default constructor. It is required by cglib to create a proxy.
+	 * Empty default constructor. It is required by byte-buddy to create a proxy.
 	 */
 	public PackagePrivateConcreteObject()
 	{
diff --git a/wicket-ioc/src/test/java/org/apache/wicket/proxy/util/ConcreteObject.java b/wicket-ioc/src/test/java/org/apache/wicket/proxy/util/ConcreteObject.java
index e36c269..cb45c47 100644
--- a/wicket-ioc/src/test/java/org/apache/wicket/proxy/util/ConcreteObject.java
+++ b/wicket-ioc/src/test/java/org/apache/wicket/proxy/util/ConcreteObject.java
@@ -27,7 +27,7 @@ public class ConcreteObject
 	private String message;
 
 	/**
-	 * Empty default constructor. It is required by cglib to create a proxy.
+	 * Empty default constructor. It is required by byte-buddy to create a proxy.
 	 */
 	public ConcreteObject()
 	{
diff --git a/wicket-jmx/pom.xml b/wicket-jmx/pom.xml
index b827a78..67303ae 100644
--- a/wicket-jmx/pom.xml
+++ b/wicket-jmx/pom.xml
@@ -32,7 +32,6 @@
 		<dependency>
 			<groupId>net.bytebuddy</groupId>
 			<artifactId>byte-buddy</artifactId>
-			<version>1.11.12</version>
 		</dependency>
 		<dependency>
 			<groupId>org.apache.wicket</groupId>
diff --git a/wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/SpringBeanWithGenericsTest.java b/wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/SpringBeanWithGenericsTest.java
index 653a93c..ac743c1 100644
--- a/wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/SpringBeanWithGenericsTest.java
+++ b/wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/SpringBeanWithGenericsTest.java
@@ -290,7 +290,7 @@ class SpringBeanWithGenericsTest
 		@Bean
 		public List<String> stringsList()
 		{
-			return Arrays.asList("foo", "bar", "baz");
+			return List.of("foo", "bar", "baz");
 		}
 
 		@Bean