Home > OS >  Spring - generic superclass not instantiated properly?
Spring - generic superclass not instantiated properly?

Time:12-10

ATM I am in the middle of refactoring our Selenium E2E Test Framework to use Spring.

My class/bean:

package info.fingo.selenium.utils.driver;

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class ProxyDecorator extends WebDriverDecorator<WebDriver> {

@Autowired
public ProxyDecorator(TestUtils testUtils, DriverManager driverManager) {
    super(WebDriver.class);
    this.testUtils = testUtils;
    this.driverManager = driverManager;

Superclass:

package org.openqa.selenium.support.decorators;


public class WebDriverDecorator<T extends WebDriver> {

  private final Class<T> targetWebDriverClass;

  private Decorated<T> decorated;

  @SuppressWarnings("unchecked")
  public WebDriverDecorator() {
    this((Class<T>) WebDriver.class);
  }

  public WebDriverDecorator(Class<T> targetClass) {
    this.targetWebDriverClass = targetClass;
  }

  public final T decorate(T original) {
    Require.nonNull("WebDriver", original);

    decorated = createDecorated(original);
    return createProxy(decorated, targetWebDriverClass);
  }

Issue occures on calling this line:

createProxy(decorated, targetWebDriverClass)

Where targetWebDriverClass for unknown reason is null and NullPointerException is later thrown. This should not EVER happen as targetWebDriverClass is ALWAYS set through constructor - either provided by client (calling super(class)) or defaulted to WebDriver.class in default WebDriverDecorator constructor. Worked fine without Spring, and unfortunately I don't understand Spring enough to get any information through debugging.

My Spring dependencies:

ext.springVersion = '2.7.1'

dependencies {
    //SPRING BOOT
    api "org.springframework.boot:spring-boot-starter:$springVersion",
            "org.springframework.boot:spring-boot-starter-aop:$springVersion",
            "org.springframework.boot:spring-boot-starter-test:$springVersion",

CodePudding user response:

decorate method in superclass WebDriverDecorator in marked as final which makes it ineligible for Spring CGLIB proxying as it cannot proxy final methods (& classes) - Sorry, I don't know exact reason why this caused my issue. This is not my own class, it is taken from inside of dependency so I cannot change this.

This means that this class cannot be managed by Spring. In order for this to somehow work I get rid of inheritance (extends keyword) and replace it with composition. Got to do some reflection magic (for one of its protected method) but this seems to do the trick.

  • Related