You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2021/08/20 17:45:38 UTC

[wicket] branch jmx-standardmbean-instead-proxy created (now c776f4d)

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

svenmeier pushed a change to branch jmx-standardmbean-instead-proxy
in repository https://gitbox.apache.org/repos/asf/wicket.git.


      at c776f4d  WICKET-6913 replace proxies with StandardMBean

This branch includes the following new commits:

     new c776f4d  WICKET-6913 replace proxies with StandardMBean

The 1 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] 01/01: WICKET-6913 replace proxies with StandardMBean

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

svenmeier pushed a commit to branch jmx-standardmbean-instead-proxy
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit c776f4d922b6ecd704f846748d488942d5b87ec2
Author: Sven Meier <sv...@apache.org>
AuthorDate: Fri Aug 20 19:34:33 2021 +0200

    WICKET-6913 replace proxies with StandardMBean
---
 .../java/org/apache/wicket/jmx/Initializer.java    | 160 +++++++--------------
 1 file changed, 54 insertions(+), 106 deletions(-)

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 181f293..bb89f78 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,11 +17,11 @@
 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;
 
+import javax.management.Attribute;
+import javax.management.AttributeList;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.MBeanRegistrationException;
@@ -30,17 +30,7 @@ import javax.management.MBeanServerFactory;
 import javax.management.MalformedObjectNameException;
 import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectName;
-
-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 javax.management.StandardMBean;
 
 import org.apache.wicket.IInitializer;
 import org.apache.wicket.ThreadContext;
@@ -78,15 +68,6 @@ public class Initializer implements IInitializer
 {
 	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();
-	
 	// It's best to store a reference to the MBeanServer rather than getting it
 	// over and over
 	private MBeanServer mbeanServer = null;
@@ -246,102 +227,69 @@ public class Initializer implements IInitializer
 	 * @throws MBeanRegistrationException
 	 * @throws InstanceAlreadyExistsException
 	 */
-	private void register(final org.apache.wicket.Application application, final Object o,
+	private <T> void register(final org.apache.wicket.Application application, final T o,
 		final ObjectName objectName) throws InstanceAlreadyExistsException,
 		MBeanRegistrationException, NotCompliantMBeanException
 	{
-		Object proxy = createProxy(application, o);
-		mbeanServer.registerMBean(proxy, objectName);
-		registered.add(objectName);
-	}
-
-	// must be public to prevent JMX Server throwing:
-	// failed to access class org.apache.wicket.jmx.Initializer$Interceptor from class org.apache.wicket.jmx.Application
-	public static class Interceptor
-	{
-		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
-		{
-			boolean existed = ThreadContext.exists();
-
-			if (existed == false)
+		StandardMBean bean = new StandardMBean(o, (Class<T>)o.getClass().getInterfaces()[0]) {
+			@Override
+			public Object getAttribute(String attribute)
 			{
-				ThreadContext.setApplication(application);
+				return withApplication(() -> super.getAttribute(attribute));
 			}
-
-			try
+			
+			@Override
+			public void setAttribute(Attribute attribute)
+			{
+				withApplication(() -> {
+					super.setAttribute(attribute);
+					return null;
+				});
+			}
+			
+			@Override
+			public AttributeList setAttributes(AttributeList attributes)
 			{
-				return method.invoke(object, args);
+				return withApplication(() -> super.setAttributes(attributes));
 			}
-			finally
+			
+			@Override
+			public Object invoke(String actionName, Object[] params, String[] signature)
 			{
+				return withApplication(() -> super.invoke(actionName, params, signature));
+			}
+			
+			private <R> R withApplication(Invocation<R> invocation)
+			{
+				boolean existed = ThreadContext.exists();
+
 				if (existed == false)
 				{
-					ThreadContext.detach();
+					ThreadContext.setApplication(application);
 				}
-			}
-		}
-	}
-
-	private Object createProxy(final org.apache.wicket.Application application, final Object o)
-	{
-		final Class<?> type = o.getClass();
-		final ClassLoader classLoader = resolveClassLoader();
-
-		Class<?> proxyClass = DYNAMIC_CLASS_CACHE.findOrInsert(classLoader,
-				new TypeCache.SimpleKey(type),
-				() -> BYTE_BUDDY
-						.with(new NamingStrategy.AbstractBase()
-						{
-							@Override
-							protected String name(TypeDescription superClass)
-							{
-								return type.getName().replace(".wrapper", "");
-							}
-						})
-						.subclass(Object.class)
-						.implement(type.getInterfaces())
-						.method(ElementMatchers.any())
-						.intercept(MethodDelegation.to(new Interceptor(application, o)))
-						.make()
-						.load(classLoader, ClassLoadingStrategy.Default.INJECTION)
-						.getLoaded());
 
-
-		try
-		{
-			return proxyClass.getDeclaredConstructor().newInstance();
-		}
-		catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e)
-		{
-			throw new WicketRuntimeException(e);
-		}
+				try
+				{
+					return invocation.invoke();
+				}
+				catch (Exception ex)
+				{
+					throw new WicketRuntimeException(ex);
+				}
+				finally
+				{
+					if (existed == false)
+					{
+						ThreadContext.detach();
+					}
+				}
+			}
+		};
+		mbeanServer.registerMBean(bean, objectName);
+		registered.add(objectName);
 	}
 
-	private static ClassLoader resolveClassLoader()
-	{
-		ClassLoader classLoader = null;
-		if (org.apache.wicket.Application.exists())
-		{
-			classLoader = org.apache.wicket.Application.get().getApplicationSettings()
-					.getClassResolver().getClassLoader();
-		}
-
-		if (classLoader == null) {
-			classLoader = Thread.currentThread().getContextClassLoader();
-		}
-
-		return classLoader;
+	private static interface Invocation<R> {
+		R invoke() throws Exception;
 	}
-
-}
+}
\ No newline at end of file