diff --git a/.idea/libraries/byte_buddy.xml b/.idea/libraries/byte_buddy.xml new file mode 100644 index 0000000000000..22f18650765c6 --- /dev/null +++ b/.idea/libraries/byte_buddy.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/cglib.xml b/.idea/libraries/cglib.xml deleted file mode 100644 index 463a32459de0a..0000000000000 --- a/.idea/libraries/cglib.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/java/client/.classpath b/java/client/.classpath index ab2505787483a..1ab48c994df3e 100644 --- a/java/client/.classpath +++ b/java/client/.classpath @@ -16,7 +16,6 @@ - @@ -45,5 +44,6 @@ + diff --git a/java/client/client.iml b/java/client/client.iml index dd264fe0eddc0..6b670e134a235 100644 --- a/java/client/client.iml +++ b/java/client/client.iml @@ -16,6 +16,7 @@ + diff --git a/java/client/src/org/openqa/selenium/remote/Augmenter.java b/java/client/src/org/openqa/selenium/remote/Augmenter.java index 1ee7053f1a3be..77f1837b2cb0a 100644 --- a/java/client/src/org/openqa/selenium/remote/Augmenter.java +++ b/java/client/src/org/openqa/selenium/remote/Augmenter.java @@ -18,16 +18,20 @@ package org.openqa.selenium.remote; +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.named; + import com.google.common.collect.ImmutableList; -import com.google.common.collect.Sets; -import net.sf.cglib.proxy.Enhancer; -import net.sf.cglib.proxy.MethodInterceptor; -import net.sf.cglib.proxy.MethodProxy; +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.description.annotation.AnnotationDescription; +import net.bytebuddy.implementation.FixedValue; +import net.bytebuddy.implementation.InvocationHandlerAdapter; import org.openqa.selenium.WebDriver; import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -37,6 +41,7 @@ import java.util.Set; import java.util.logging.Logger; + /** * Enhance the interfaces implemented by an instance of the * {@link org.openqa.selenium.remote.RemoteWebDriver} based on the returned @@ -49,8 +54,10 @@ public class Augmenter extends BaseAugmenter { private static final Logger logger = Logger.getLogger(Augmenter.class.getName()); @Override - protected X create(RemoteWebDriver driver, - Map augmentors, X objectToAugment) { + protected X create( + RemoteWebDriver driver, + Map augmentors, + X objectToAugment) { CompoundHandler handler = determineAugmentation(driver, augmentors, objectToAugment); X augmented = performAugmentation(handler, objectToAugment); @@ -62,12 +69,10 @@ protected X create(RemoteWebDriver driver, @Override protected RemoteWebDriver extractRemoteWebDriver(WebDriver driver) { - if (driver.getClass().isAnnotationPresent(Augmentable.class) || - driver.getClass().getName().startsWith( - "org.openqa.selenium.remote.RemoteWebDriver$$EnhancerByCGLIB")) { + if (driver.getClass().isAnnotationPresent(Augmentable.class)) { return (RemoteWebDriver) driver; - } + logger.warning("Augmenter should be applied to the instances of @Augmentable classes " + "or previously augmented instances only (instance class was: " + driver.getClass() + ")"); return null; @@ -91,10 +96,6 @@ private void copyField(Object source, Object target, Field field) { return; } - if (field.getName().startsWith("CGLIB$")) { - return; - } - try { field.setAccessible(true); Object value = field.get(source); @@ -104,8 +105,10 @@ private void copyField(Object source, Object target, Field field) { } } - private CompoundHandler determineAugmentation(RemoteWebDriver driver, - Map augmentors, Object objectToAugment) { + private CompoundHandler determineAugmentation( + RemoteWebDriver driver, + Map augmentors, + Object objectToAugment) { Map capabilities = driver.getCapabilities().asMap(); CompoundHandler handler = new CompoundHandler(driver, objectToAugment); @@ -131,39 +134,41 @@ private CompoundHandler determineAugmentation(RemoteWebDriver driver, protected X performAugmentation(CompoundHandler handler, X from) { if (handler.isNeedingApplication()) { Class superClass = from.getClass(); - while (Enhancer.isEnhanced(superClass)) { - superClass = superClass.getSuperclass(); - } - - Enhancer enhancer = new Enhancer(); - enhancer.setCallback(handler); - enhancer.setSuperclass(superClass); - Set> interfaces = Sets.newHashSet(); - interfaces.addAll(ImmutableList.copyOf(from.getClass().getInterfaces())); - interfaces.addAll(handler.getInterfaces()); - enhancer.setInterfaces(interfaces.toArray(new Class[interfaces.size()])); - - return (X) enhancer.create(); + Class loaded = new ByteBuddy() + .subclass(superClass) + .implement(ImmutableList.copyOf(handler.getInterfaces())) + .annotateType(AnnotationDescription.Builder.ofType(Augmentable.class).build()) + .method(any()).intercept(InvocationHandlerAdapter.of(handler)) + .method(named("isAugmented")).intercept(FixedValue.value(true)) + .make() + .load(superClass.getClassLoader()) + .getLoaded() + .asSubclass(from.getClass()); + + try { + return (X) loaded.newInstance(); + } catch (ReflectiveOperationException e) { + throw new RuntimeException("Unable to create subclass", e); + } } return from; } - private class CompoundHandler implements MethodInterceptor { - - private Map handlers = new HashMap<>(); - private Set> interfaces = new HashSet<>(); + private class CompoundHandler implements InvocationHandler { - private final RemoteWebDriver driver; + private final ExecuteMethod execute; private final Object originalInstance; + private final Map handlers = new HashMap<>(); + private final Set> interfaces = new HashSet<>(); private CompoundHandler(RemoteWebDriver driver, Object originalInstance) { - this.driver = driver; + this.execute = new RemoteExecuteMethod(driver); this.originalInstance = originalInstance; } - public void addCapabilityHander(Class fromInterface, InterfaceImplementation handledBy) { + void addCapabilityHander(Class fromInterface, InterfaceImplementation handledBy) { if (fromInterface.isInterface()) { interfaces.add(fromInterface); } @@ -172,16 +177,16 @@ public void addCapabilityHander(Class fromInterface, InterfaceImplementation } } - public Set> getInterfaces() { + Set> getInterfaces() { return interfaces; } - public boolean isNeedingApplication() { + boolean isNeedingApplication() { return !handlers.isEmpty(); } - public Object intercept(Object self, Method method, Object[] args, MethodProxy methodProxy) - throws Throwable { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { InterfaceImplementation handler = handlers.get(method); if (handler == null) { @@ -192,7 +197,7 @@ public Object intercept(Object self, Method method, Object[] args, MethodProxy m } } - return handler.invoke(new RemoteExecuteMethod(driver), self, method, args); + return handler.invoke(execute, proxy, method, args); } } } diff --git a/java/client/src/org/openqa/selenium/remote/BUCK b/java/client/src/org/openqa/selenium/remote/BUCK index b93b96f8b9d6d..2b6c08ec6cde8 100644 --- a/java/client/src/org/openqa/selenium/remote/BUCK +++ b/java/client/src/org/openqa/selenium/remote/BUCK @@ -54,7 +54,7 @@ java_library(name = 'remote', '//java/client/src/org/openqa/selenium:selenium', ], deps = [ - '//third_party/java/cglib:cglib', + '//third_party/java/bytebuddy:bytebuddy', '//third_party/java/guava:guava', ], visibility = ['PUBLIC'], diff --git a/java/client/test/org/openqa/selenium/remote/BaseAugmenterTest.java b/java/client/test/org/openqa/selenium/remote/BaseAugmenterTest.java index cd689e8b7558b..687f9afed13cd 100644 --- a/java/client/test/org/openqa/selenium/remote/BaseAugmenterTest.java +++ b/java/client/test/org/openqa/selenium/remote/BaseAugmenterTest.java @@ -165,12 +165,7 @@ public Class getDescribedInterface() { } public InterfaceImplementation getImplementation(Object value) { - return new InterfaceImplementation() { - public Object invoke(ExecuteMethod executeMethod, Object self, Method method, - Object... args) { - return "Hello World"; - } - }; + return (executeMethod, self, method, args) -> "Hello World"; } }); diff --git a/third_party/java/cglib/BUCK b/third_party/java/cglib/BUCK deleted file mode 100644 index 8dea1cab52829..0000000000000 --- a/third_party/java/cglib/BUCK +++ /dev/null @@ -1,10 +0,0 @@ -prebuilt_jar( - name = 'cglib', - maven_coords = 'cglib:cglib-nodep:jar:3.2.4', - binary_jar = 'cglib-nodep-3.2.4.jar', - source_jar = 'cglib-nodep-3.2.4-sources.jar', - visibility = [ - '//java/client/src/org/openqa/selenium/remote:remote', - ], -) - diff --git a/third_party/java/cglib/cglib-nodep-3.2.4-sources.jar b/third_party/java/cglib/cglib-nodep-3.2.4-sources.jar deleted file mode 100644 index a29d34af1e002..0000000000000 Binary files a/third_party/java/cglib/cglib-nodep-3.2.4-sources.jar and /dev/null differ diff --git a/third_party/java/cglib/cglib-nodep-3.2.4.jar b/third_party/java/cglib/cglib-nodep-3.2.4.jar deleted file mode 100644 index 57d8e31179ac4..0000000000000 Binary files a/third_party/java/cglib/cglib-nodep-3.2.4.jar and /dev/null differ