Accessing hdfs in java throws error - java

I can access hdfs in terminal via hdfs dfs -ls / and I get the address and port of the cluster by hdfs getconf -confKey fs.defaultFS (I refer to address and port in code below).
Trying to read files on hdfs in java gave me similar errors as decribed here (also discussed in this questions).
With the address I try the following in java
FileSystem fs;
BufferedReader br;
String line;
Path path = new Path("hdfs://<address>:<port>/somedata.txt");
try
{
/* --------------------------
* Option 1: Gave 'Wrong FS: hdfs://..., Expected file:///' error
Configuration configuration = new Configuration();
configuration.addResource(new Path("/etc/hadoop/conf/core-site.xml"));
configuration.addResource(new Path("/etc/hadoop/conf/hdfs-site.xml"));
fs = FileSystem.get(configuration);
* ---------------------------
*/
// --------------------------
// Option 2: Gives error stated below
Configuration configuration = new Configuration();
fs = FileSystem.get(new URI("hdfs://<address>:<port>"),configuration);
// --------------------------
LOG.info(fs.getConf().toString());
FSDataInputStream fsDataInputStream = fs.open(path);
InputStreamReader inputStreamReader = new InputStreamReader(fsDataInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
while((line=bufferedReader.readLine())!=null){
// some file processing code here.
}
bufferedReader .close();
}
catch (Exception e)
{
fail();
}
The error that option 2 gives me is
java.lang.NoSuchMethodError: org.apache.hadoop.hdfs.server.namenode.NameNode.getAddress(Ljava/lang/String;)Ljava/net/InetSocketAddress;
at org.apache.hadoop.hdfs.DistributedFileSystem.initialize(DistributedFileSystem.java:99)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:1446)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:67)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:1464)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:263)
at fwt.gateway.Test_Runner.checkLocationMasterindicesOnHDFS(Test_Runner.java:76)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
The fact that I can access the files from terminal is an indication for me that core-site.xml and hdfs-site.xml must be correct.
Thanks for the help!
EDIT 1:
The maven dependencies I use for the code below are the following
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>3.0.0-alpha4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.0.0-alpha4</version>
</dependency>

Update your POM to following:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>2.6.0-mr1-cdh5.4.2.1</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.8.1</version>
</dependency>
Never use alpha versions as they are likely to have a bugs.

You can use this in pom.xml file
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0</version>
</dependency>
I have used version 2.6.0. You can try any updated version.

Related

org.openqa.selenium.json.JsonOutput.write(Ljava/lang/Object;)Lorg/openqa/selenium/json/JsonOutput; due to java.io.IOException: Incomplete document

I'm creating a new test framework from scratch using Spring Boot 2 and Appium. To write the tests I'm using JUnit which is already included in Spring Boot's spring-boot-starter-test POM along with many others. I added Appium to my POM and it now looks like this:
<?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>com.automationexperiment</groupId>
<artifactId>one</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>6.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
As for my tests, I have a DriverSetup class that looks like this:
#RunWith(SpringRunner.class)
#SpringBootTest
public class DriverSetup {
protected AndroidDriver<AndroidElement> driver;
#Before
public void setUp() throws MalformedURLException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "6.0.1");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "DeviceName");
capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.google.android.gm");
capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".ConversationListActivityGmail");
URL myUrl = new URL("http://127.0.0.1:4723/wd/hub");
this.driver = new AndroidDriver<AndroidElement>(myUrl, capabilities);
this.driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
}
}
Finally, I have another class that extends from DriverSetup to make sure driver initialization is done before every test. It looks like this:
#RunWith(SpringRunner.class)
#SpringBootTest
public class FirstTryTest extends DriverSetup {
public FirstTryTest() { }
#Test
public void test() {
System.out.println("test");
}
}
I just want to make sure I can reach the test in my FirstTryTest, but every time the code initializes the AndroidDriver with the URL and the DesiredCapabilities, I get the following error:
java.lang.NoSuchMethodError: org.openqa.selenium.json.JsonOutput.write(Ljava/lang/Object;)Lorg/openqa/selenium/json/JsonOutput;
at io.appium.java_client.remote.NewAppiumSessionPayload.writeTo(NewAppiumSessionPayload.java:265)
at io.appium.java_client.remote.AppiumCommandExecutor$1.createSession(AppiumCommandExecutor.java:175)
at io.appium.java_client.remote.AppiumCommandExecutor.createSession(AppiumCommandExecutor.java:209)
at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:231)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:601)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:42)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:219)
at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:142)
at io.appium.java_client.DefaultGenericMobileDriver.<init>(DefaultGenericMobileDriver.java:38)
at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:84)
at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:94)
at io.appium.java_client.android.AndroidDriver.<init>(AndroidDriver.java:93)
at com.automationexperiment.one.driversetup.DriverSetup.setUp(DriverSetup.java:31)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at com.microsoft.java.test.runner.JUnit4TestReference.run(JUnit4TestReference.java:51)
at com.microsoft.java.test.runner.CustomizedJUnitCoreRunner.run(CustomizedJUnitCoreRunner.java:45)
at com.microsoft.java.test.runner.JUnitLauncher.execute(JUnitLauncher.java:26)
at com.microsoft.java.test.runner.JUnitLauncher.main(JUnitLauncher.java:15)
Suppressed: java.io.IOException: Incomplete document
at com.google.gson.stream.JsonWriter.close(JsonWriter.java:559)
at org.openqa.selenium.json.JsonOutput.close(JsonOutput.java:39)
at io.appium.java_client.remote.NewAppiumSessionPayload.writeTo(NewAppiumSessionPayload.java:288)
... 41 more
I've tried using an older version of Appium (5.0.4) but it didn't work. I'd like to emphasize the end of the StackTrace. An IOException is mentioned while in other questions with similar errors script fails due to a
org.openqa.selenium.json.JsonException`.
This error message:
java.lang.NoSuchMethodError: org.openqa.selenium.json.JsonOutput.write(Ljava/lang/Object;)Lorg/openqa/selenium/json/JsonOutput;
.
Suppressed: java.io.IOException: Incomplete document
...implies that java.lang.NoSuchMethodError was raised by the JVM.
You have mentioned about using an older version of Appium v5.0.4
It's pretty tough to analyze the error in absence of the following information pertaining to your Test Environment:
Appium server version
Desktop OS/version
Mobile platform/version under test
Real device or emulator/simulator
As per the discussions Error while running Appium script with AndroidDriver and iOS :Could not initialize the ios capabilities with 6.0.0 this error seems to be coming from the NumberCoercer Class which have been modified in Selenium RemoteDriver v3.12.0 to accept Port as Integer while earlier it was accepting String.
Solution
Update to the latest Appium Java Client v6.1.0
Update to the latest (atleast) Selenium v3.12.0
#SrinivasanTarget mentions one important aspect that:
Appium's Java client comes along with Selenium Dependency so we don't recommend to exclude selenium and add as separate dependency as it may raise conflicts at times.
Here you will find a relevant discussion on java.lang.NoSuchMethodError: org.openqa.selenium.json.JsonOutput.write(Ljava/lang/Object;Ljava/lang/reflect/Type;)

Spring boot mock CREATED POST response

Completely new to spring-boot.
I am trying to write a test for my POST method that returns a response of CREATED with the path of the resource. I am coming across all sorts of problems for something that I was assuming is very straight forward. In the code bellow is my current test class which seems to be crashing with a
ClassNotFoundException
on the first line of my method.
#RunWith(SpringRunner.class)
#WebMvcTest(AResource.class)
public class AResourceTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private AResource aResourceMock;
#Test
public void testPOST() throws Exception {
Response.ResponseBuilder created = Response.created(UriBuilder.fromPath("/123").build());
when(aResourceMock.create(123)).thenReturn(created.build());
mockMvc.perform(MockMvcRequestBuilders
.request(HttpMethod.POST, "/account")
.content("{\t\"id\": \"123\"}"))
.andExpect(MockMvcResultMatchers.status().isCreated());
}
}
Any idea how to properly mock my response? Thanks
EDIT:
stacktrace bellow
java.lang.RuntimeException: java.lang.ClassNotFoundException: com.sun.ws.rs.ext.RuntimeDelegateImpl
at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:122)
at javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:91)
at javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:69)
at javax.ws.rs.core.UriBuilder.fromPath(UriBuilder.java:111)
at com.powerman.RestController.AResourceTest.canPOST(AResourceTest.java:34)
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:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.ClassNotFoundException: com.sun.ws.rs.ext.RuntimeDelegateImpl
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)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at javax.ws.rs.ext.FactoryFinder.newInstance(FactoryFinder.java:62)
at javax.ws.rs.ext.FactoryFinder.find(FactoryFinder.java:155)
at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:105)
... 34 more
I will add my dependencies in case they help at all:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.0.1.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.17.1</version>
</dependency>
</dependencies>
I'm not sure what you are trying to do and why you would want to mock the Response. When you are running a a test for your resources, generally wha you want to do is run integration tests. What this entails is making an actual request to the endpoint using a client library. MockMvc only works when you are using Spring MVC as the REST framework. But in your case, you are using Jersey (I assume, based on the jax-rs tag in your post.
As far as the client library, you can use the Jersey/JAX-RS Client API or you can use Spring Boot's TestRestTemplate, like they do in the official Spring Boot/Jersey sample project. For checking the created URI for the POST/Created resource, what you should be doing is checking the Location header in the response. This is was is set on the server side when you do Response.created(URI). For example, say this is your resource
#Path("customers")
public class CustomersResource {
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response createCustomer(Customer customer, #Context UriInfo uriInfo) {
int customerId = // create customer and get the resource id
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(Integer.toString(customerId));
return Response.created(builder.build()).build();
}
}
Jersey will automatically set the Location to value of the URI passed to created()
Then (if you're using the Jersey Client), then your test might look something like
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ExampleResourceTest {
#LocalServerPort
private int port;
private Client client = ClientBuilder.newClient();
#Test
public void testCustomerLocationOnPost() {
Customer customer = new Customer("Jane", "Doe");
URI resourceUri = UriBuilder.fromUri("http://localhost")
.port(port).path("api").path("customers").build();
Response response = client.target(resourceUri).request().post(Entity.json(customer));
// test that we get the correct status code
assertThat(response.getStatus())
.isEqualTo(Response.Status.CREATED.getStatusCode());
// test that the location header is correct.
assertThat(response.getHeaderString(HttpHeaders.LOCATION))
.isEqualTo(UriBuilder.fromUri(resourceUri).path("123").build().toString());
}
}
As far as the dependencies, to use Jersey with Spring Boot you need to use the spring-boot-started-jersey dependency. Also get rid of the jersey-core dependency you have. See the linked project above for complete example.
Try adding to your pom.xml:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.27</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.27</version>
<scope>provided</scope>
</dependency>

Tests do not run when dependency on mockito-core present

I've added mockito-core to my dependencies but I seem to be unable to run tests (errors when running) unless I also add powermock-api-mockito to the dependencies. I start getting errors immediately after I put in the mockito-core dependency - no other changes are necessary (e.g. I don't need to add code that uses Mockito to start seeing errors).
Dependency I want to add:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
Dependency I seem to need to include along:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
Without the above second dependency, I get the following errors. Again, this is purely dependency changes, no code changes:
java.lang.NoClassDefFoundError: org/hamcrest/TypeSafeMatcher
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
And this:
java.lang.NoClassDefFoundError: org/junit/internal/matchers/StacktracePrintingMatcher
at org.junit.matchers.JUnitMatchers.isThrowable(JUnitMatchers.java:103)
at org.junit.rules.ExpectedExceptionMatcherBuilder.build(ExpectedExceptionMatcherBuilder.java:27)
at org.junit.rules.ExpectedException.handleException(ExpectedException.java:252)
at org.junit.rules.ExpectedException.access$000(ExpectedException.java:106)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:241)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
This should be solved by using mockito-all instead of mockito-core. It would have all the dependency required by mockito. hamcrest and junit are part of it.
Mockito-core 1.10.19 has no dependencies to the powermock-api-mockito. The only dependencies it has are following runtime dependencies:
org.hamcrest » hamcrest-core 1.1
org.objenesis » objenesis 2.1
Maybe these are conflicting with another library you have in your dependencies tree. Try to analyze your dependency tree using:
mvn dependency:tree
https://mvnrepository.com/artifact/org.mockito/mockito-core/1.10.19

ExceptionMapper not working in JerseyTest framework

I had made an RESTFUL-API for an specific object and using javax.validation.Constraints for validation, when I execute the app it works as expected and ExceptionMapper class is been executed correctly but when I try to automatize tests with JerseyFramework the ExceptionMapper is not executed or handled. So it works in app but not when i test it.
Main Class that launch app
package com.carlos.zerga.server;
public class App {
public static void main( String[] args ) throws Exception {
AppResourceConfig config = new AppResourceConfig();
ServletHolder jerseyServlet
= new ServletHolder(new ServletContainer(config));
Server server = new Server(8081);
ServletContextHandler context
= new ServletContextHandler(server, "/");
context.addServlet(jerseyServlet, "/*");
server.start();
server.join();
}
}
ResourceConfig for App
package com.carlos.zerga.server;
public class AppResourceConfig extends ResourceConfig{
public AppResourceConfig() {
register(new PropertiesBinder());
register(EntityValidationExceptionMapper.class);
packages(true,"com.carlos.zerga.properties");
}
}
ExceptionMapper for ValidationExceptions
package com.carlos.zerga.properties.presentation.handler;
#Provider
public class EntityValidationExceptionMapper implements
ExceptionMapper<BeanValidationException> {
public Response toResponse(BeanValidationException e) {
return Response.status(200).
type(MediaType.APPLICATION_JSON_TYPE).
entity(buildResponse((ConstraintViolationException) e.getInternalException())).
build();
}
private ExceptionResponse buildResponse(ConstraintViolationException e)
{
ArrayList<String> messages = new ArrayList<String>();
for(ConstraintViolation constraintViolation:e.getConstraintViolations())
{
messages.add(constraintViolation.getMessage());
}
return new ExceptionResponse(200, messages,e.getClass().getSimpleName());
}
}
Resouce Class
package com.carlos.zerga.properties.presentation;
#Path("property")
public class PropertiesApiResource {
#POST
#Path("new")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Property createProperty(Property property)
{
return property;
}
//LOT OF OTHER ROUTES
......
}
Test Case
package com.carlos.zerga.test.properties.presentation;
#RunWith(DataProviderRunner.class)
public class PropertiesApiResourceTest extends JerseyTest {
#Override
protected Application configure() {
return new ResourceConfig()
.register(new PropertiesBinder())
.register(new EntityValidationExceptionMapper())
.register(new ConstraintValidationException())
.packages(true,"com.carlos.zerga.properties");
}
//Here comes the error
#Test
#UseDataProvider("provideInvalidPropertiesPSR_PA")
public void testInValidPropertyCreation(Property property)
{
Response response=target("property/new").request(MediaType.APPLICATION_JSON).method("POST",Entity.json(property));
assertEquals(response.getMediaType(),MediaType.APPLICATION_JSON_TYPE);
String exceptionResponse=response.readEntity(String.class);
System.out.print(exceptionResponse);
}
POM.xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2-metadata-generator</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>com.tngtech.java</groupId>
<artifactId>junit-dataprovider</artifactId>
<version>1.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-bean-validation</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-jetty-connector</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<jersey.version>2.26-b03</jersey.version>
<jetty.version>9.2.14.v20151106</jetty.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
When I send by postman it returns me what I want:
{"errorCode":200,"errors":["Bathroom : Amount bathrooms can't be empty"],"errorDescription":"ConstraintViolationException"}
But when I run the tests returns me:
javax.ws.rs.ProcessingException:
Exception Description: Constraints violated on marshalled bean:
com.carlos.zerga.properties.domain.entity.Property#3caeaf62
-->Violated constraint on property bathRooms: "Bathroom : Minimun amout of bathrooms is 3".
-->Violated constraint on property bedRooms: "Bathroom : Minimun amout of bathrooms is 3".
Internal Exception: javax.validation.ConstraintViolationException
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:262)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:759)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:756)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:407)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:756)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:443)
at com.carlos.zerga.test.properties.presentation.PropertiesApiResourceTest.testInValidPropertyCreation(PropertiesApiResourceTest.java:93)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at com.tngtech.java.junit.dataprovider.DataProviderFrameworkMethod.invokeExplosively(DataProviderFrameworkMethod.java:77)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: Exception [EclipseLink-7510] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6): org.eclipse.persistence.exceptions.BeanValidationException
Exception Description: Constraints violated on marshalled bean:
com.carlos.zerga.properties.domain.entity.Property#3caeaf62
-->Violated constraint on property bathRooms: "Bathroom : Minimun amout of bathrooms is 3".
-->Violated constraint on property bedRooms: "Bathroom : Minimun amout of bathrooms is 3".
Internal Exception: javax.validation.ConstraintViolationException
at org.eclipse.persistence.exceptions.BeanValidationException.constraintViolation(BeanValidationException.java:53)
at org.eclipse.persistence.jaxb.JAXBBeanValidator.buildConstraintViolationException(JAXBBeanValidator.java:391)
at org.eclipse.persistence.jaxb.JAXBBeanValidator.validate(JAXBBeanValidator.java:275)
at org.eclipse.persistence.jaxb.JAXBMarshaller.validateAndTransformIfNeeded(JAXBMarshaller.java:604)
at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:494)
at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:957)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1126)
at org.glassfish.jersey.client.ClientRequest.doWriteEntity(ClientRequest.java:517)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:499)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:393)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:253)
... 34 more
Caused by: javax.validation.ConstraintViolationException
at org.eclipse.persistence.jaxb.JAXBBeanValidator.buildConstraintViolationException(JAXBBeanValidator.java:389)
... 47 more
If you look carefully at the stacktrace, you will see that this error is actually happening on the client side, even before the request gets to the server. The reason is that you are using MOXy, which uses JAXB, and the JAXB bean validation is enabled by default. You can see in the stacktrace that the JAXBBeanValidator is being envoked, and that it is happening on the client side marshalling of the entity.
There are a couple solutions:
Configure MOXy to disable bean validation
Don't use MOXy
Configure MOXy to disable bean validation
To configure MOXy, you can use a MoxyJsonConfig. You should actually do this on the server side also so that you don't get double validation on the server. The bean validation provided by Jersey is different from that provided by MOXy.
In Test.java
#Override
public void configureClient(ClientConfig config) {
config.register(new MoxyJsonConfig().setFormattedOutput(true)
.property(MarshallerProperties.BEAN_VALIDATION_MODE, BeanValidationMode.NONE)
.resolver());
}
The configureClient method is a method on the JerseyTest that you can override to configure the Client. You can register the same MoxyJsonConfig with the ResourceConfig also for the server side.
Don't use MOXy
My solution would be to just get rid of MOXy, and use Jackson instead. Just change the following dependency to the Jackson on below it
<!-- remove this -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- use this -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
And also add #Valid tag to:
Resource.java
...... MORE ROUTES
#POST
#Path("new")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Property createProperty(#Valid Property property){
return property;
}
...... MORE ROUTES
You will not have this problem with Jackson as Jackson doesn't do any bean validation. Aside from this problem, my personal opinion is that Jackson is just a much better overall library for JSON anyway.
Note: If you turn off the MOXy validation (whether through configuration or by using Jackson), you would no longer be trying to catch a BeanValidationException (which is a MOXy) class, but instead you can directly catch ConstraintViolationException.

No such method error while using RestAssuredMockMvc

I'm using RestAssuredMockMvc for unit testing spring mvc controllers.
This is my code:
import com.xyz.api.controller.UserController;
import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc;
import org.junit.Before;
import org.junit.Test;
import javax.servlet.http.HttpServletResponse;
import static org.hamcrest.Matchers.equalTo;
public class UserControllerRest {
private String userName = "xyz#example.com";
private String expectedResult = "Hello " + userName;
#Before
public void initialize() {
RestAssuredMockMvc.standaloneSetup(new UserController());
}
#Test
public void checkResponseAndBody() throws Exception {
RestAssuredMockMvc.given().param("userName", userName).when().get("/users").print();
RestAssuredMockMvc.given().param("userName", userName).when().get("/users").then().assertThat().statusCode(200).and().body(equalTo(expectedResult));
}
}
The first statement in checkResponseAndBody() prints: Hello xyz#example.com
But the second line gives the following error:
java.lang.NoSuchMethodError: com.jayway.restassured.internal.ValidatableResponseOptionsImpl.<init>(Ljava/lang/String;Lcom/jayway/restassured/internal/ResponseParserRegistrar;Lcom/jayway/restassured/config/RestAssuredConfig;Lcom/jayway/restassured/response/Response;Lcom/jayway/restassured/response/ExtractableResponse;)V
at com.jayway.restassured.module.mockmvc.internal.ValidatableMockMvcResponseImpl.<init>(ValidatableMockMvcResponseImpl.java:37)
at com.jayway.restassured.module.mockmvc.internal.MockMvcRestAssuredResponseImpl.then(MockMvcRestAssuredResponseImpl.java:36)
at com.giddh.api.restassured.UserControllerRest.checkResponseAndBody(UserControllerRest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
I've seen the examples and even tried using the same code but still the error persists. How can I solve this?
You've probably not added all dependencies to your classpath. As indicated by the download page you also need to download and put the contents of rest-assured-2.5.0-dist.zip in your classpath.
If you're using Maven it should be enough to just depend on the spring-mock-mvc module:
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>spring-mock-mvc</artifactId>
<version>${rest-assured.version}</version>
<scope>test</scope>
</dependency>
Or gradle:
testCompile "com.jayway.restassured:spring-mock-mvc:${rest-assured.version}"
This happened to me when using restassured with Maven (Surprisingly, Gradle did not give me this problem, it handled it well unlike Maven).
For me, it was a dependency conflict. I had Apache Phoenix as dependency in my pom.xml
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix</artifactId>
<version>4.13.2-cdh5.11.2</version>
This Apache Phoenix jar depends on httpclient version 4.0.1 jar which overrides the version which my restassured jar depends on (which is httpclient version 4.3.5) . Maven had excluded this later version (4.5.3) by default.
To solve this, I added exclusion for the older version under my Apache Phoenix pom section which looked like this:
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>4.13.2-cdh5.11.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
That way the version of httpclient in my restassured jar superceded and everything worked fine.

Categories

Resources