1717
1818package org .openqa .selenium .support .decorators ;
1919
20+ import net .bytebuddy .ByteBuddy ;
21+ import net .bytebuddy .dynamic .loading .ClassLoadingStrategy ;
22+ import net .bytebuddy .implementation .InvocationHandlerAdapter ;
23+ import net .bytebuddy .matcher .ElementMatchers ;
24+
2025import org .openqa .selenium .Alert ;
2126import org .openqa .selenium .Beta ;
2227import org .openqa .selenium .WebDriver ;
2934import java .lang .reflect .InvocationHandler ;
3035import java .lang .reflect .InvocationTargetException ;
3136import java .lang .reflect .Method ;
32- import java .lang .reflect .Proxy ;
3337import java .util .HashMap ;
3438import java .util .HashSet ;
3539import java .util .List ;
@@ -183,7 +187,7 @@ public final WebDriver decorate(WebDriver original) {
183187 Require .nonNull ("WebDriver" , original );
184188
185189 decorated = createDecorated (original );
186- return createProxy (decorated );
190+ return createProxy (decorated , WebDriver . class );
187191 }
188192
189193 public Decorated <WebDriver > getDecoratedDriver () {
@@ -244,31 +248,31 @@ public Object onError(
244248
245249 private Object decorateResult (Object toDecorate ) {
246250 if (toDecorate instanceof WebDriver ) {
247- return createProxy (getDecoratedDriver ());
251+ return createProxy (getDecoratedDriver (), WebDriver . class );
248252 }
249253 if (toDecorate instanceof WebElement ) {
250- return createProxy (createDecorated ((WebElement ) toDecorate ));
254+ return createProxy (createDecorated ((WebElement ) toDecorate ), WebElement . class );
251255 }
252256 if (toDecorate instanceof Alert ) {
253- return createProxy (createDecorated ((Alert ) toDecorate ));
257+ return createProxy (createDecorated ((Alert ) toDecorate ), Alert . class );
254258 }
255259 if (toDecorate instanceof VirtualAuthenticator ) {
256- return createProxy (createDecorated ((VirtualAuthenticator ) toDecorate ));
260+ return createProxy (createDecorated ((VirtualAuthenticator ) toDecorate ), VirtualAuthenticator . class );
257261 }
258262 if (toDecorate instanceof WebDriver .Navigation ) {
259- return createProxy (createDecorated ((WebDriver .Navigation ) toDecorate ));
263+ return createProxy (createDecorated ((WebDriver .Navigation ) toDecorate ), WebDriver . Navigation . class );
260264 }
261265 if (toDecorate instanceof WebDriver .Options ) {
262- return createProxy (createDecorated ((WebDriver .Options ) toDecorate ));
266+ return createProxy (createDecorated ((WebDriver .Options ) toDecorate ), WebDriver . Options . class );
263267 }
264268 if (toDecorate instanceof WebDriver .TargetLocator ) {
265- return createProxy (createDecorated ((WebDriver .TargetLocator ) toDecorate ));
269+ return createProxy (createDecorated ((WebDriver .TargetLocator ) toDecorate ), WebDriver . TargetLocator . class );
266270 }
267271 if (toDecorate instanceof WebDriver .Timeouts ) {
268- return createProxy (createDecorated ((WebDriver .Timeouts ) toDecorate ));
272+ return createProxy (createDecorated ((WebDriver .Timeouts ) toDecorate ), WebDriver . Timeouts . class );
269273 }
270274 if (toDecorate instanceof WebDriver .Window ) {
271- return createProxy (createDecorated ((WebDriver .Window ) toDecorate ));
275+ return createProxy (createDecorated ((WebDriver .Window ) toDecorate ), WebDriver . Window . class );
272276 }
273277 if (toDecorate instanceof List ) {
274278 return ((List <?>) toDecorate ).stream ()
@@ -278,7 +282,7 @@ private Object decorateResult(Object toDecorate) {
278282 return toDecorate ;
279283 }
280284
281- protected final <Z > Z createProxy (final Decorated <Z > decorated ) {
285+ protected final <Z > Z createProxy (final Decorated <Z > decorated , Class < Z > clazz ) {
282286 Set <Class <?>> decoratedInterfaces = extractInterfaces (decorated );
283287 Set <Class <?>> originalInterfaces = extractInterfaces (decorated .getOriginal ());
284288 Map <Class <?>, InvocationHandler > derivedInterfaces = deriveAdditionalInterfaces (decorated .getOriginal ());
@@ -311,8 +315,21 @@ protected final <Z> Z createProxy(final Decorated<Z> decorated) {
311315 allInterfaces .addAll (derivedInterfaces .keySet ());
312316 Class <?>[] allInterfacesArray = allInterfaces .toArray (new Class <?>[0 ]);
313317
314- return (Z ) Proxy .newProxyInstance (
315- this .getClass ().getClassLoader (), allInterfacesArray , handler );
318+ Class <? extends Z > proxy = new ByteBuddy ()
319+ .subclass (Object .class )
320+ .implement (allInterfacesArray )
321+ .method (ElementMatchers .any ())
322+ .intercept (InvocationHandlerAdapter .of (handler ))
323+ .make ()
324+ .load (clazz .getClassLoader (), ClassLoadingStrategy .Default .WRAPPER )
325+ .getLoaded ()
326+ .asSubclass (clazz );
327+
328+ try {
329+ return proxy .newInstance ();
330+ } catch (ReflectiveOperationException e ) {
331+ throw new IllegalStateException ("Unable to create new proxy" , e );
332+ }
316333 }
317334
318335 static Set <Class <?>> extractInterfaces (final Object object ) {
@@ -381,7 +398,7 @@ private Map<Class<?>, InvocationHandler> deriveAdditionalInterfaces(Object objec
381398 }
382399
383400 @ FunctionalInterface
384- interface JsonSerializer {
401+ protected interface JsonSerializer {
385402 Object toJson ();
386403 }
387404}
0 commit comments