I'm having an issue with mockito and powermock, I can mock an abstract class with a final static method with no problems. When trying to mock an Interface as with WebIServerSession I'm getting the stacktrace below. I've had a look at other issues in powermock github repo and it seems to be related with the jvm version. I've already upgraded to the latest 1.8 java version as stated in https://github.com/mockito/mockito/issues/636 and I'm still getting the same error. Might it be related with Powermock compatibility with Mockito 2?
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
import static org.powermock.api.mockito.PowerMockito.whenNew;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
#BeforeMethod
public void setup() throws Exception {
mockStatic(ResourceBundle.class);
mockStatic(WebObjectsFactory.class);
WebObjectsFactory webObjectsFactory = mock(WebObjectsFactory.class);
WebIServerSession webIServerSession = mock(WebIServerSession.class);
PowerMockito.when(WebObjectsFactory.getInstance()).thenReturn(webObjectsFactory);
PowerMockito.when(webObjectsFactory.getIServerSession()).thenReturn(webIServerSession);
whenNew(ThreadLocal.class).withNoArguments().thenReturn(errorContainer);
MockitoAnnotations.initMocks(this);
}
#Test
public void shouldBeTrue() {
assertTrue(true);
}
Maven dependencies:
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-testng</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-reflect</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
</dependencies>
Stacktrace:
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: interface com.microstrategy.web.objects.WebIServerSession.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
Java : 1.8
JVM vendor name : Oracle Corporation
JVM vendor version : 25.191-b12
JVM name : Java HotSpot(TM) 64-Bit Server VM
JVM version : 1.8.0_191-b12
JVM info : mixed mode
OS name : Mac OS X
OS version : 10.14.1
Underlying exception : java.lang.IllegalArgumentException: Could not create type
at com.myproject.SSOESMTest.setup(SSOESMTest.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:59)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:458)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:222)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:523)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: java.lang.IllegalArgumentException: Could not create type
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:154)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:365)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:174)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:376)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:32)
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMockType(SubclassByteBuddyMockMaker.java:71)
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:42)
at org.powermock.api.mockito.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:50)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:116)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:69)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:46)
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:138)
... 28 more
Caused by: java.lang.NoClassDefFoundError: com/microstrategy/utils/xml/SAXSupport
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.getDeclaredMethods(Class.java:1975)
at net.bytebuddy.description.method.MethodList$ForLoadedMethods.<init>(MethodList.java:109)
at net.bytebuddy.description.type.TypeDescription$ForLoadedType.getDeclaredMethods(TypeDescription.java:8426)
at net.bytebuddy.description.type.TypeDescription$Generic$OfNonGenericType.getDeclaredMethods(TypeDescription.java:3654)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:634)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.analyze(MethodGraph.java:596)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:632)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.analyze(MethodGraph.java:596)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:632)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.analyze(MethodGraph.java:596)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:632)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.compile(MethodGraph.java:567)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$AbstractBase.compile(MethodGraph.java:465)
at net.bytebuddy.dynamic.scaffold.MethodRegistry$Default.prepare(MethodRegistry.java:463)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:198)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:189)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3394)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:3583)
at org.mockito.internal.creation.bytebuddy.SubclassBytecodeGenerator.mockClass(SubclassBytecodeGenerator.java:94)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:37)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:34)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:152)
... 39 more
Caused by: java.lang.ClassNotFoundException: com.microstrategy.utils.xml.SAXSupport
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:202)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:89)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:79)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 63 more
Test ignored.
===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 1
Configuration Failures: 1, Skips: 2
===============================================
Process finished with exit code 0
The exception is most likely to occur due to the version of Mockito used.
Try by replacing the current version of mockito-core with below dependency.
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.22.0</version>
<scope>test</scope>
</dependency>
Ignore the warning of overriding managed version in pom.xml
Make sure your interface visibility is public.
I am not sure that it will be the solution in your case. I got the same issue when I was testing in Android Studio.
My solution was replace core-mockito with
androidTestImplementation "org.mockito:mockito-android:2.25.0"
Then it started working perfect.
It may be solution for those who are testing for Android Studio and having the same issue.
add
#RunWith(MockitoJUnitRunner.class)
I also experienced this problem when trying to mock a non-public interface, and the error message didn't make sense, as all my tests in another suite passed correctly while mocking the same interface.
In my case I had to downgrade the Mockito Core library and revert it again to make it work. Here are the steps I took:
Find the Mockito Core dependency in the module level build.gradle file entry:
testImplementation 'org.mockito:mockito-core:2.25.0'
Downgrade to another valid version, in my example 2.23.0:
testImplementation 'org.mockito:mockito-core:2.23.0'
Do a Gradle sync and wait for completion
Revert the Mockito Core dependency to the same version you had before (or newer):
testImplementation 'org.mockito:mockito-core:2.25.0'
Sync the project again
Run the tests again
I had a similar issue. I was surprisingly having:
Mockito cannot mock this class: interface javax.servlet.ServletContext.
This was only when I ran my test in my IDE (IntelliJ Idea). If I tried to run it via maven command - it passed.
To make the test work in IntelliJ Idea I just changed the configurations:
Set Shorten command line to JAR manifest.
It's Strange but after adding below line in build.gradle file it work for me
androidTestImplementation "org.mockito:mockito-android:$mockitoAndroid"
I also have this problem by using IDEA, finally choose Shorten command line: "JAR manifest" solved
annotate your test class like this
#RunWith(PowerMockRunner.class)
#PrepareForTest({ResourceBundle.class, WebObjectsFactory.class, AnyOtherClassThatContainsStaticMethod.class, . . .})
ref: https://github.com/powermock/powermock/wiki/mockstatic
Related
i'm trying to generate class stubs for a wsdl with Intellij-Idea 2017.2.5 (Webservices -> Generate code from wsdl...) using JDK-9
I'm getting this exception and i wonder how to tell intellij to pass "--add-modules java.activation" to complete the operation.
(i guess i should run wsimport from the command line...)
Exception in thread "main" java.lang.NoClassDefFoundError: javax/activation/DataSource
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.<clinit>(RuntimeBuiltinLeafInfoImpl.java:461)
at com.sun.xml.bind.v2.model.impl.RuntimeTypeInfoSetImpl.<init>(RuntimeTypeInfoSetImpl.java:65)
at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:133)
at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:85)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.<init>(ModelBuilder.java:156)
at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.<init>(RuntimeModelBuilder.java:93)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:455)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:303)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:142)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1174)
at com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo.getJAXBContext(BindInfo.java:335)
at com.sun.tools.xjc.reader.internalizer.SCDBasedBindingSet.apply(SCDBasedBindingSet.java:235)
at com.sun.tools.xjc.ModelLoader.createXSOM(ModelLoader.java:541)
at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:269)
at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:95)
at com.sun.tools.ws.processor.modeler.wsdl.JAXBModelBuilder.bind(JAXBModelBuilder.java:142)
at com.sun.tools.ws.processor.modeler.wsdl.WSDLModeler.buildJAXBModel(WSDLModeler.java:2244)
at com.sun.tools.ws.processor.modeler.wsdl.WSDLModeler.internalBuildModel(WSDLModeler.java:191)
at com.sun.tools.ws.processor.modeler.wsdl.WSDLModeler.buildModel(WSDLModeler.java:137)
at com.sun.tools.ws.wscompile.WsimportTool.buildWsdlModel(WsimportTool.java:391)
at com.sun.tools.ws.wscompile.WsimportTool.run(WsimportTool.java:204)
at com.sun.tools.ws.wscompile.WsimportTool.run(WsimportTool.java:179)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.sun.tools.ws.Invoker.invoke(Invoker.java:135)
at com.sun.tools.ws.WsImport.main(WsImport.java:57)
Caused by: java.lang.ClassNotFoundException: javax.activation.DataSource
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
... 28 more
Based on your error message, you need to add the following dependency in your pom.xml
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
From SDK 9, for JAXB to work for web services you need to also have the following dependencies if you do not already have them as they are not part of the SDK.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
I guess it can be useful. I have these additional packages in my soap project when switch from Java 8 to 10. Gradle:
compile "javax.xml.bind:jaxb-api:2.3.0"
compile "javax.activation:activation:1.1"
compile "com.sun.xml.bind:jaxb-impl:2.3.0"
compile "com.sun.xml.bind:jaxb-core:2.3.0"
compile "com.sun.xml.ws:rt:2.3.0"
compile "com.sun.xml.ws:jaxws-rt:2.3.0"
Just for other people with the same exception coming here:
This problem can also occur if you use a web server such as tomcat and if you need the activation jar to be present there as well. One possible solution is to put it in the lib folder of tomcat (or to use the common.loader functionality).
I had the same problem. After changing the project jdk, it works for me.
Change project jdk to 8.
This is my first selenium script using TestNG and Maven.
Created a simple "Hello World" code and a selenium test code which just checks the title of google page.
Selenium Code Below with TestNG:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.Test;
public class HelloTest {
#Test
public void testOne() {
//WebDriver d=new FirefoxDriver();
System.setProperty("webdriver.gecko.driver","D:\\Firefox Driver\\geckodriver-v0.17.0-win64\\geckodriver.exe");
WebDriver d=new FirefoxDriver();
d.get("https://www.google.com");
System.out.println("This is first TestNG");
}
}
This is working absolutely fine when run through eclipse - Run As - Test NG test.
But when ran through Maven - mvn clean install from cmd prompt, i am getting below error
T E S T S
-------------------------------------------------------
Running HelloTest
Configuring TestNG with: TestNG652Configurator
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.94 sec <<< FAILURE! - in HelloTest
testOne(HelloTest) Time elapsed: 0.032 sec <<< FAILURE!
java.lang.NoClassDefFoundError: org/openqa/selenium/firefox/FirefoxDriver
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at HelloTest.testOne(HelloTest.java:11)
It is showing error at WebDriver d=new FirefoxDriver();. Not sure where the issue is. Added all jar files , checked the build path and all the jar were there. Below is my POM file.
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo.micky</groupId>
<artifactId>MavenDemoTwo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
<type>jar</type>
<version>15.0</version>
</dependency>
</dependencies>
</project>
Any help is deeply appreciated.
What is NoClassDefFoundError
NoClassDefFoundError in Java occurs when JVM is not able to find a particular class at runtime which was available at compile time. For example, if we have resolved a method call from a Class or accessing any static member of a Class and that Class is not available during runtime then JVM will throw NoClassDefFoundError.
The error you are seeing is :
java.lang.NoClassDefFoundError: org/openqa/selenium/firefox/FirefoxDriver
This clearly indicates that Selenium is trying to resolve the particular FirefoxDriver Class at runtime from org/openqa/selenium/firefox/FirefoxDriver which is not available.
What went wrong :
This situation occurs if there are presence of multiple sources to resolve the Classes and Methods through JDK/Maven/Gradle.
From the pom.xml it is pretty clear that you have added multiple dependencies for FirefoxDriver Class as follows:
<artifactId>selenium-java</artifactId>:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.12.0</version>
<scope>test</scope>
</dependency>
<artifactId>selenium-firefox-driver</artifactId>:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>3.12.0</version>
</dependency>
<artifactId>selenium-server</artifactId>:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.12.0</version>
</dependency>
Additionally you have also added all jar files.
From all the above mentioned points it's clear that the related Class or Methods were resolved from one source at Compile Time which was not available during Run Time.
Solution :
Here are a few steps to solve NoClassDefFoundError :
While using a Build Tool e.g. Maven or Gradle, remove all the External JARs from the Java Build Path. Maven or Gradle will download all the dependencies mentioned in the configuration file (e.g. pom.xml) to resolve the Classes and Methods.
If using Selenium JARs within a Java Project add only required External JARs within the Java Build Path and remove the unused and duplicate External JARs.
If you are using FirefoxDriver use either of the <artifactId>selenium-java</artifactId> or <artifactId>selenium-server</artifactId>. Avoid using both at the same time.
Remove the unwanted and duplicated from pom.xml
Clean your Project Workspace through your IDE and Rebuild your project with required dependencies only.
Use CCleaner tool to wipe off all the OS chores before and after the execution of your Test Suite.
If your base Web Client version is too old, then uninstall it through Revo Uninstaller and install a recent GA and released version of Web Client.
Take a System Reboot.
While you execute a Maven Project always perform the folling in sequence:
maven clean
maven install
maven test
You can find related discussions in:
Exception in thread “main” java.lang.NoClassDefFoundError: org/openqa/selenium/WebDriver
How to solve java.lang.NoClassDefFoundError? Selenium
java.lang.NoClassDefFoundError: com/google/common/base/Function
I was using eclipse 09-2019 which is the latest one with latest JDK installed 13, and latest selenium jar files 3.141.59, I installed other JDKs to work around to solve this issue after trying all answers on similar question. Then after 4 days trying, installed eclipse neon version(https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/neon/3/eclipse-java-neon-3-win32-x86_64.zip&mirror_id=105) and used Selenium-Java 3.5.2 jar files (https://jar-download.com/artifacts/org.seleniumhq.selenium/selenium-java/3.5.2/source-code) and now it is working perfectly Alhamdullilah.
Also I don't know what was the errors root cause exactly or at all, but now it is solved.
Wish if that help You
I have a spring-boot based application, using embedded tomcat. I have no problem when deploying via mvn spring-boot:run goal, but I have a problems when I try to deploy using intelliJ spring-boot plugins. Important note, we have modified the default pom, turning our app into a war that could be deployed into a full tomcatTraditional Deployment, but this in development mode will be better to just deploy the app using the embedded tomcat. The problem is that basically we ended with this message when trying to run the spring boot app from intelliJ
Caused by: java.lang.IllegalStateException: Failed to introspect annotated methods on class org.springframework.boot.web.support.SpringBootServletInitializer
at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:163) ~[spring-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.retrieveBeanMethodMetadata(ConfigurationClassParser.java:380) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:314) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:198) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:167) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]
... 17 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContext
at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_144]
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_144]
at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_144]
at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:152) ~[spring-core-4.3.8.RELEASE.jar:4.3.8.RELEASE]
... 22 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_144]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_144]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) ~[na:1.8.0_144]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_144]
... 26 common frames omitted
Do you have any ideas of why is this happening ? and how can we solve it ?
EDIT:
I am using IntelliJ IDEA 2017.2 (just in case the build is idea-IU-172.3317.76), and as a SSCCE, lets use the getting-started example of spring-boot, and lets apply the changes proposed for Traditional Deployment (the first link) we will have the following files
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-spring-boot</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Then we will have the Application.java
package hello;
import java.util.Arrays;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
And I didn' modify the HelloController.java but just for completeness:
package hello;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
public class HelloController {
#RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
This example runs without problem using mvn spring-boot:run but doesn't run when using the spring-boot intelliJ's plug-in
Note - this answer references Spring documentation for v 1.5.6.RELEASE (current release)
Analyses:
Running the main class from IJ is like executing your app from command line. As such, the classpath will include only compile and runtime scoped dependencies. Provided means that it'll be needed during compilation, but you expect the JDK or the container to provide it for your app at runtime:
provided
This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
On the other hand, the spring-boot-maven-plugin uses a different classpath to execute the run goal:
By default, both the repackage and the run goals will include any provided dependencies that are defined in the project. A boot-based project should consider provided dependencies as container dependencies that are required to run the application.
Conclusion and solutions:
So it's a classpath configuration issue. As you mentioned, for war packaging or traditional deployment, you should exclude the embedded servlet container. However, to be able to run the app during development, you want the embedded container.
As a solution or work around, you have at least the following 2 options:
1) Remove the <scope>provided</scope> from the spring-boot-starter-tomcat dependency declaration. If you wanted to, you could remove that dependency altogether, as Tomcat is the default container used by spring-boot-starter-web, but perhaps it's best to leave it and add a comment, so you won't forget about it when releasing
2) A neat trick that works with IJ and would make it easier to not forget to uncomment provided before production release, is to leave the dependency as it is now, and add a maven dev profile which you can activate from IJ. This way, by default it will be provided and it can be safely packaged into a war, and only when developing and manually activating the profile it will be included. After adding the profile, reimport your maven project so you can select the profile:
<profiles>
<profile>
<id>dev</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
if you are using maven project then you need to add javax.servlet-api dependency.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
you can also download jar from http://central.maven.org/maven2/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar
I try to add Cucumber to test my Java project, I wrote a feature file:
Feature: I visit the website
Scenario: I read the home page
Given I am on the "home" page
I wrote a class to run the cukes
import cucumber.api.CucumberOptions;
/**
* See https://cucumber.io/docs/reference/jvm#junit-runner
*/
#RunWith(Cucumber.class)
#CucumberOptions(glue = {"classpath:stepdefinitions"},features = {"src/test/features"})
public class RunCukesTest {
}
And the step definition: (I've the feeling that I'm missing annotations here)
package com.myproject.test.stepdefinitions;
import cucumber.api.PendingException;
import cucumber.api.java8.En;
public class WebSteps implements En {
public WebSteps() {
Given("^I am on the \"([^\"]*)\" page$", (String page) -> {
System.out.println(page);
});
}
}
So whatever I put in glue = {}, the step is not found. With glue = {"classpath:stepdefinitions"} or glue = {"stepdefinitions"} the test is green and I have the "You can implement missing steps with the snippets below" message (the step is not found). If I put the full package path, either glue = {"com.myproject.test.stepdefinitions"} or glue = {"classpath:com.myproject.test.stepdefinitions"}
I have a stack trace:
java.lang.NoClassDefFoundError: org/springframework/test/context/ContextHierarchy
at cucumber.runtime.java.spring.SpringFactory.annotatedWithSupportedSpringRootTestAnnotations(SpringFactory.java:198)
at cucumber.runtime.java.spring.SpringFactory.dependsOnSpringContext(SpringFactory.java:187)
at cucumber.runtime.java.spring.SpringFactory.addClass(SpringFactory.java:61)
at cucumber.runtime.java.JavaBackend.loadGlue(JavaBackend.java:96)
at cucumber.runtime.Runtime.<init>(Runtime.java:91)
at cucumber.runtime.Runtime.<init>(Runtime.java:69)
at cucumber.runtime.Runtime.<init>(Runtime.java:65)
at cucumber.api.junit.Cucumber.createRuntime(Cucumber.java:78)
at cucumber.api.junit.Cucumber.<init>(Cucumber.java:58)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:29)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:21)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:70)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.ClassNotFoundException: org.springframework.test.context.ContextHierarchy
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 26 more
Here is what I added in my pom.xml:
<!-- Tests with cucumber -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java8</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
<!-- Dependency Injection with Spring https://cucumber.io/docs/reference/java-di#spring -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-spring</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
<!-- JUnit Runner : https://cucumber.io/docs/reference/jvm#running -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
My project uses Spring 4.
You are not missing an annotation. You are missing content in your classpath.
I would start with simplifying the setup bit. You are using Maven and therefore I would place the sample feature file in the same package as the RunCukesTest class. If RunCukesTest lives in the package com.myproject.test, then would this mean:
src/test/resources/com/myproject/test
I think you currently are using src/test/features for your feature files. That is not a path that is included in your classpath by Maven. Not unless you explicit adds it, which you don't show us if you do or not.
Moving the feature file should allow you to remove the #CucumberOptions and remove one potential source of problems.
I would then implement the step in a class in the same package as RunCukesTest. I would use the snippets provided when you run your build, mvn test. And finally do the system.out.println() you have to really know that the expected method indeed is executed. The snippets are probably the pre Java 8 way of doing things.
With this working, I would try to get the Java 8 steps working.
More details can be seen in the source code for Cucumber:
https://github.com/cucumber/cucumber-jvm/tree/master/java8/src/test/java/cucumber/runtime/java8/test
The error suggests you are missing Spring dependencies; you must address this before looking into why the step definitions are not found. You haven't posted the full list of deps in your project, but you should at least have these dependencies in your pom:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
You may need to update the version.
Add a plugin to Runnerclass plugin={"pretty","html:format"}. I use as below:
#RunWith(Cucumber.class)
#CucumberOptions(
plugin={"pretty","html:format"},
features = "Features/name.feature",glue={"stepdefinitions path in eclipse"})
public class RunnerClass {
}
also when you want to parametrise HOME variable, it should be like < Home > instead of Home. Also not sure why did you add String parameter in step definition, please delete and try.
I am building a small proof of concept Spring Boot app which is supposed to connect to a Neo4j instance and perform some basic operations on a couple of different Nodes. If I have the main application class wired to create an embedded Neo4j service using the following code, everything works fine. (this is based on the working example https://spring.io/guides/gs/accessing-neo4j-data-rest/)
#Bean(destroyMethod = "shutdown")
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabase("target/hello.db");
}
This is the only code sample I can find though for connecting to a Neo4j server from spring boot. If I try connecting to a remote server, the code fails to start with the exception at the end of this question. Our plan is to run a centralized Neo4j instance which is obviously a common production requirement.
How can or should I configure my bean to connect to a remote Neo4j database or is anyone aware of a solid working example of this kind of setup?
Thanks!
My pom.xml includes the following:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-rest</artifactId>
<version>3.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I have seen several references to using SpringCypherRestGraphDatabase so I have this being handled in my Main application class is as follows:
import org.neo4j.graphdb.GraphDatabaseService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.rest.SpringCypherRestGraphDatabase;
#SpringBootApplication
#EnableNeo4jRepositories
public class ProfileServiceApplication extends Neo4jConfiguration {
public ProfileServiceApplication() {
setBasePackage("profile");
}
#Bean
public GraphDatabaseService graphDatabaseService() {
return new SpringCypherRestGraphDatabase("http://localhost:7474/db/data/","neo4j","password");
}
public static void main(String[] args) {
SpringApplication.run(ProfileServiceApplication.class, args);
}
}
When I try to run with this configuration, I get the following error:
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.graphdb.GraphDatabaseService]: Circular reference involving containing bean 'profileServiceApplication' - consider declaring the factory method as static for independence from its containing instance. Factory method 'graphDatabaseService' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/neo4j/core/UpdateableState
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
Please share your application as github-project for testing. Perhaps it is also a dependency issue of the spring-boot-starter? Which boot version are you using??
Perhaps you can check mvn dependency:tree if there is any older version of SDN pulled in and if so, update the neo4-version-property for the spring-boot-starter.
Example application is here:
http://neo4j.com/developer/java/#_using_spring_data_neo4j
and it is also in the docs as you correctly saw:
http://docs.spring.io/spring-data/data-neo4j/docs/3.3.0.RELEASE/reference/html/#using_spring_data_neo4j_as_a_neo4j_server_client
The reference which you are giving doesn't contain Neo4j URL.
Hence Here is Application.properties file to connect to your Neo4j.
spring.data.neo4j.uri=bolt://localhost
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=Your_Password
Start your Neo4j Database as a console application which will run on localhost:7474 port most probably.
command to start:
neo4j console
Also check the dependency. As the latest version work with only
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>