Spring Boot JUnit with Selenium ClassNotFoundExcep

2020-04-16 03:30发布

问题:

I am trying to run a simple test with selenium, but I am getting ClassNotFoundException when I run my test and I don't know what dependency to import to solve this issue.

I couldn't find any example that did something different from this.

I am using Java 8 and spring-boot 1.5.10.RELEASE

Can you guys please help me with this?

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class VersaoControllerTest extends AbstractTest{

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private WebDriver webDriver;

    @Test
    public void test() {
        this.webDriver.get("/");
    }
}

pom.xml

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-api</artifactId>
    </dependency>

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>htmlunit-driver</artifactId>
        <scope>test</scope>
    </dependency>

Error:

Caused by: java.lang.ClassNotFoundException: org.apache.xml.utils.PrefixResolver
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_131]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_131]
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) ~[?:1.8.0_131]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_131]
    at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_131]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:1.8.0_131]
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_131]
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[?:1.8.0_131]
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[?:1.8.0_131]
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[?:1.8.0_131]
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[?:1.8.0_131]
    at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_131]
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[?:1.8.0_131]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_131]
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) ~[?:1.8.0_131]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_131]
    at com.gargoylesoftware.htmlunit.javascript.configuration.JavaScriptConfiguration.<clinit>(JavaScriptConfiguration.java:407) ~[htmlunit-2.21.jar:2.21]
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.<init>(JavaScriptEngine.java:129) ~[htmlunit-2.21.jar:2.21]
    at com.gargoylesoftware.htmlunit.WebClient.init(WebClient.java:239) ~[htmlunit-2.21.jar:2.21]
    at com.gargoylesoftware.htmlunit.WebClient.<init>(WebClient.java:213) ~[htmlunit-2.21.jar:2.21]
    at com.gargoylesoftware.htmlunit.WebClient.<init>(WebClient.java:204) ~[htmlunit-2.21.jar:2.21]
    at org.springframework.boot.test.web.htmlunit.LocalHostWebClient.<init>(LocalHostWebClient.java:40) ~[spring-boot-test-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration.mockMvcWebClientBuilder(MockMvcWebClientAutoConfiguration.java:55) ~[spring-boot-test-autoconfigure-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration$$EnhancerBySpringCGLIB$$90ad153.CGLIB$mockMvcWebClientBuilder$0(<generated>) ~[spring-boot-test-autoconfigure-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration$$EnhancerBySpringCGLIB$$90ad153$$FastClassBySpringCGLIB$$cf4a3653.invoke(<generated>) ~[spring-boot-test-autoconfigure-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration$$EnhancerBySpringCGLIB$$90ad153.mockMvcWebClientBuilder(<generated>) ~[spring-boot-test-autoconfigure-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120) ~[spring-boot-test-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) ~[spring-test-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) ~[spring-test-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    ... 27 more

回答1:

java.lang.ClassNotFoundException

ClassNotFoundException in Java is a subclass of java.lang.Exception and occurs when Java Virtual Machine tries to load a particular class and doesn't finds the requested class in classpath. It is a checked Exception and explicit Exception handling methods are required to what can possibly be throwing ClassNotFoundException either by using try-catch block or by using throws clause.

As per the Java Docs ClassNotFoundException comes in following cases:

  1. When we try to load a class by using Class.forName() method and .class file or binary of class is not available in classpath.
  2. When Classloader try to load a class by using findSystemClass() method.
  3. While using loadClass() method of class ClassLoader in Java.

ClassNotFoundExcepiton can arise only when JVM tries to load a class at run-time but nothing related to compile time which is unlike NoClassDefFoundError. This is because till run time JVM doesn't know about this Class and it can only be done by above specified method or by employing Reflection to read the name of class from some configuration and then load the class specified on those configuration file.


This usecase

The error does gives us a hint what is going wrong as follows :

Caused by: java.lang.ClassNotFoundException: org.apache.xml.utils.PrefixResolver

As per the pom.xml you have shared clearly the <version>x.y.z</version> tag is missing. You need to change the as follows :

  • selenium-api

    <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-api -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-api</artifactId>
        <version>3.10.0</version>
    </dependency>
    
  • selenium-htmlunit-driver

     <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-htmlunit-driver -->
     <dependency>
         <groupId>org.seleniumhq.selenium</groupId>
         <artifactId>selenium-htmlunit-driver</artifactId>
         <version>2.52.0</version>
     </dependency>
    

As you are using spring-boot 1.5.10 additionally you may also require to add either of the following <dependency> :

  • selenium-java

    <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.10.0</version>
    </dependency>
    
  • selenium-server

    <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-server -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-server</artifactId>
        <version>3.10.0</version>
    </dependency>