DefaultDataBufferFactory cannot be cast to class NettyDataBufferFactory - java

I have a spring-boot project with spring-cloud gateway. When I make a http request, I am getting this error. I have been working on trying to solve this issue for days, but I could not manage to solve it.
java.lang.ClassCastException: class org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast to class org.springframework.core.io.buffer.NettyDataBufferFactory (org.springframework.core.io.buffer.DefaultDataBufferFactory and org.springframework.core.io.buffer.NettyDataBufferFactory are in unnamed module of loader 'app')
These are versions which I am using for the apllication.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
This is my pom.xml for the service.
<properties>
<!-- Spring -->
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
This is how I am modifying gateway filter.
#Slf4j
public class ModifyHttpMethodGatewayFilter extends
AbstractGatewayFilterFactory<ModifyHttpMethodGatewayFilter.Config> {
public ModifyHttpMethodGatewayFilter() {
super(ModifyHttpMethodGatewayFilter.Config.class);
}
#Override
public GatewayFilter apply(ModifyHttpMethodGatewayFilter.Config config) {
return (exchange, chain) -> {
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
builder.method(config.getMethod());
ServerHttpRequest request = builder.build();
if (!config.getMethod().equals(HttpMethod.GET)) {
// Create request body if missing from a GET request
String bodyString = getRequestBody(request);
DataBuffer bodyDataBuffer = stringDataBuffer(bodyString);
HttpHeaders headers = request.getHeaders();
Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
request = new ServerHttpRequestDecorator(request) {
#Override
public Flux<DataBuffer> getBody() {
return bodyFlux;
}
#Override
public HttpHeaders getHeaders() {
return headers;
}
};
}
return chain.filter(exchange.mutate().request(request).build());
};
}
public static class Config {
#NotEmpty
protected HttpMethod method;
public HttpMethod getMethod() {
return method;
}
public Config setMethod(HttpMethod method) {
this.method = method;
return this;
}
}
}
stringDataBuffer method.
public static DataBuffer stringDataBuffer(String value) {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
}

Related

Spring microservice: Servlet.service() for servlet [jsp] threw exception

I work with a Spring microservice and received the following errors,
2020-01-20 09:58:22.504 ERROR 13758 --- [nio-8080-exec-1] o.a.c.c.C.[.[localhost].[/].[jsp] : Servlet.service() for servlet [jsp] threw exception
java.lang.ClassNotFoundException: org.apache.tomcat.util.security.Escape
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_211]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_211]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_211]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_211]
at org.apache.jasper.compiler.JspUtil.getExprInXml(JspUtil.java:85) ~[tomcat-embed-jasper-9.0.29.jar:9.0.29]
at org.apache.jasper.compiler.PageDataImpl$SecondPassVisitor.printAttributes(PageDataImpl.java:736) ~[tomcat-embed-jasper-9.0.29.jar:9.0.29]
In the browser, its provided the error,
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Jan 20 09:58:22 BDT 2020
There was an unexpected error (type=Internal Server Error, status=500).
org/apache/tomcat/util/security/Escape
I provide a few code snippets from the respective micro-service,
#SpringBootApplication
#EnableCircuitBreaker
#EnableDiscoveryClient
#EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}
The controller class,
#Controller
#Transactional
#RequestMapping("/website/vehicles")
public class VehicleController {
#Autowired
private VehicleRepository data;
#Autowired
private PositionTrackingExternalService externalService;
#PostMapping(value = "/newVehicle.html")
public String newVehicle(Vehicle vehicle) {
data.save(vehicle);
return "redirect:/website/vehicles/list.html";
}
#PostMapping(value = "/deleteVehicle.html")
public String deleteVehicle(#RequestParam Long id) {
data.delete(id);
return "redirect:/website/vehicles/list.html";
}
#GetMapping(value = "/newVehicle.html")
public ModelAndView renderNewVehicleForm() {
Vehicle newVehicle = new Vehicle();
return new ModelAndView("newVehicle", "form", newVehicle);
}
#GetMapping(value = "/list.html")
public ModelAndView vehicles() {
List<Vehicle> allVehicles = data.findAll();
return new ModelAndView("allVehicles", "vehicles", allVehicles);
}
...... ..... ...... ..... ...... .....
...... ..... ...... ..... ...... .....
}
The feign client,
#FeignClient(name = "fleetman-position-tracker")
public interface RemotePositionMicroserviceCalls {
#GetMapping(value = "/vehicles/{name}")
public Position getLatestPositionForVehicle(#PathVariable(value = "name") String name);
}
The service classes,
#Service
public class PositionTrackingExternalService {
#Autowired
private ObjectProvider<RemotePositionMicroserviceCalls> remoteService;
#Autowired
private VehicleRepository repository;
#HystrixCommand(fallbackMethod = "handleExternalServiceDown")
public Position getLatestPositionForVehicleFromRemoteMicroservice(String name) {
Position response = remoteService.getObject().getLatestPositionForVehicle(name);
response.setUpToDate(true);
return response;
}
public Position handleExternalServiceDown(String name) {
// Read the last known position for this vehicle
Position position = new Position();
Vehicle vehicle = repository.findByName(name);
position.setLat(vehicle.getLat());
position.setLongitude(vehicle.getLongitude());
position.setTimestamp(vehicle.getLastRecordedPosition());
position.setUpToDate(false);
return position;
}
}
The project structure,
As requested, the pom.xml file is provided below,
<?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.transport.visualizer</groupId>
<artifactId>transport-visualizer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>TransportVisualizer</name>
<description>Vehicle Transport Visualizer</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<includes>
<include>application.properties</include>
</includes>
</resource>
</resources>
</build>
</project>
What's the issue here and how do I solve it?
Change your jasper dependency as
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
The dependency should be configured as with scope provided:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>

Mysql client NoSuchMethodError

All of a sudden I receive this message when I try to deploy my Vertx application:
GRAVE: Unhandled exception java.lang.NoSuchMethodError:
'void io.vertx.sqlclient.impl.SocketConnectionBase.(io.vertx.core.impl.NetSocketInternal,
boolean, int, int, int, io.vertx.core.Context)' at
io.vertx.mysqlclient.impl.MySQLSocketConnection.(MySQLSocketConnection.java:46)
at
io.vertx.mysqlclient.impl.MySQLConnectionFactory.lambda$connect$0(MySQLConnectionFactory.java:115)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:131)
Here's the dependencies of my pom file:
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-auth-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>4.0.0-milestone3</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mysql-client</artifactId>
<version>4.0.0-milestone3</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-templ-freemarker</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
And this is the code that deploys the HTTP server and the database:
#Override
public void start(Promise<Void> promise) throws Exception {
// Deploy the database
Promise<String> dbVerticleDeployment = Promise.promise();
vertx.deployVerticle(new DatabaseVerticle(), dbVerticleDeployment);
// When the database has been deployed, proceed with the server
dbVerticleDeployment.future().compose(s -> {
// Deploy the HTTPS server
Promise<String> httpVerticleDeployment = Promise.promise();
vertx.deployVerticle(new HttpsServerVerticle(), httpVerticleDeployment);
// Return the future to notify the completion
return httpVerticleDeployment.future();
}).setHandler(stringAsyncResult -> {
// Error handling
if (stringAsyncResult.succeeded())
promise.complete();
else
promise.fail(stringAsyncResult.cause());
});
}
I don't think that the error is on the code but it's something related to maven imports. I probably have messed up versions?
Here's the database
package com.rosanna.mkscoreboards.database;
import com.rosanna.mkscoreboards.database.service.DatabaseService;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.mysqlclient.MySQLConnectOptions;
import io.vertx.mysqlclient.MySQLPool;
import io.vertx.serviceproxy.ServiceBinder;
import io.vertx.sqlclient.PoolOptions;
import java.util.HashMap;
public class DatabaseVerticle extends AbstractVerticle {
// Database connection constants
private static final String HOST_NAME = "localhost";
private static final String DATABASE_NAME = "mkscoreboards";
private static final String DB_USERNAME = "root";
private static final String DB_PASSWORD = "temp_pass";
private static final int MAX_POOL_SIZE = 20;
// Queries
private static HashMap<SqlQuery, String> queries = new HashMap<>();
// Event but identifier
public static final String MKSCOREBOARDS_QUEUE = "mkscoreboards.queue";
#Override
public void start(Promise<Void> promise) throws Exception {
// Connection setup
var connectOptions = new MySQLConnectOptions()
.setPort(3306)
.setHost(HOST_NAME)
.setDatabase(DATABASE_NAME)
.setUser(DB_USERNAME)
.setPassword(DB_PASSWORD);
var poolOptions = new PoolOptions().setMaxSize(MAX_POOL_SIZE);
// Load the queries
initQueries();
// Create the pooled client
var client = MySQLPool.pool(vertx, connectOptions, poolOptions);
DatabaseService.create(client, queries, ready -> {
if (ready.succeeded()) {
var binder = new ServiceBinder(vertx);
binder.setAddress(MKSCOREBOARDS_QUEUE).register(DatabaseService.class, ready.result());
promise.complete();
} else {
promise.fail(ready.cause());
}
});
}
private void initQueries() {
if (queries.size() == 0) {
queries.put(
SqlQuery.LIST_AVAILABLE_GAMES,
"SELECT * FROM games;"
);
}
}
}
Here's the database service, taken from "Gentle guide to Vertx application"
#ProxyGen
#VertxGen
public interface DatabaseService {
#GenIgnore
static DatabaseService create(MySQLPool dbClient, HashMap<SqlQuery, String> sqlQueries, Handler<AsyncResult<DatabaseService>> readyHandler) {
return new DatabaseServiceImpl(sqlQueries, dbClient, readyHandler);
}
#GenIgnore
static DatabaseService createProxy(Vertx vertx, String address) {
return new DatabaseServiceVertxEBProxy(vertx, address);
}
#Fluent
DatabaseService listAllGames(Handler<AsyncResult<JsonArray>> resultHandler);
}
and
public class DatabaseServiceImpl implements DatabaseService {
private final HashMap<SqlQuery, String> sqlQueries;
private final MySQLPool client;
public DatabaseServiceImpl(HashMap<SqlQuery, String> sqlQueries, MySQLPool client, Handler<AsyncResult<DatabaseService>> readyHandler) {
this.sqlQueries = sqlQueries;
this.client = client;
client.getConnection(result -> {
if (result.failed()) {
readyHandler.handle(Future.failedFuture(result.cause()));
} else {
readyHandler.handle(Future.succeededFuture(this));
}
});
}
#Override
public DatabaseService listAllGames(Handler<AsyncResult<JsonArray>> resultHandler) {
//TODO
return null;
}
}
I have ended up with the fact that this error is related to a bug in vert.x; I have now this error:
java.lang.NoClassDefFoundError: io/vertx/core/impl/NetSocketInternal
at
io.vertx.mysqlclient.impl.MySQLConnectionFactory.lambda$connect$0(MySQLConnectionFactory.java:114)
And the pom is now the following (compare it with the pom in the question for comparing).
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-auth-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mysql-client</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-templ-freemarker</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
There must be issues with vertx itself because all versions are the same, I am using vertx 4
use
<!-- https://mvnrepository.com/artifact/io.vertx/vertx-mysql-client -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mysql-client</artifactId>
<version>4.1.2</version>
</dependency>
or the latest
can you check that the various versions of the vertx components you are using are the same ?

java.lang.NoSuchMethodError: org.json.JSONObject.<init>(Ljava/lang/Object;)V

I have a basic SpringBoot 2.1.5.RELEASE app. Using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file with some RestControllers.
In 1 of the controller this is the body I send:
{
"depositHotel": "xxx",
"destinationHotel": "aaa",
"depositHotelAmount": "0.2",
"destinationHotelAmount": "4",
"destinationAddress": [{
"address": "asdf",
"tag": ""
}],
"refundAddress": [{
"address": "pio",
"tag": ""
}]
}
so I create this class to send it as a RequestBody:
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"address",
"tag"
})
public class Address {
public Address() {
super();
}
public Address(String address) {
super();
this.address = address;
}
#JsonProperty("address")
private String address;
#JsonProperty("tag")
private Object tag;
#JsonProperty("address")
public String getAddress() {
return address;
}
#JsonProperty("address")
public void setAddress(String address) {
this.address = address;
}
#JsonProperty("tag")
public Object getTag() {
return tag;
}
#JsonProperty("tag")
public void setTag(Object tag) {
this.tag = tag;
}
}
and
public class HotelswitchHotelOrderRequestBody {
public static class Builder {
private String depositHotel;
private String destinationHotel;
private Float depositHotelAmount;
private Float destinationHotelAmount;
private Address destinationAddress;
private Address refundAddress;
public Builder(String depositHotel, String destinationHotel) {
this.depositHotel = depositHotel;
this.destinationHotel = destinationHotel;
}
public Builder withDepositHotelAmount (Float depositHotelAmount) {
this.depositHotelAmount = depositHotelAmount;
return this;
}
public Builder withDestinationHotelAmount (Float destinationHotelAmount) {
this.destinationHotelAmount = destinationHotelAmount;
return this;
}
public Builder toDestinationAddress (Address destinationAddress) {
this.destinationAddress = destinationAddress;
return this;
}
public Builder toRefundAddress (Address refundAddress) {
this.refundAddress = refundAddress;
return this;
}
public HotelswitchHotelOrderRequestBody build(){
HotelswitchHotelOrderRequestBody order = new HotelswitchHotelOrderRequestBody();
order.depositHotel = this.depositHotel;
order.depositHotelAmount = this.depositHotelAmount;
order.destinationAddress = this.destinationAddress;
order.destinationHotel = this.destinationHotel;
order.destinationHotelAmount = this.destinationHotelAmount;
order.refundAddress = this.refundAddress;
return order;
}
}
private String depositHotel;
private String destinationHotel;
private Float depositHotelAmount;
private Float destinationHotelAmount;
private Address destinationAddress;
private Address refundAddress;
private HotelswitchHotelOrderRequestBody () {
//Constructor is now private.
}
public String getDepositHotel() {
return depositHotel;
}
public void setDepositHotel(String depositHotel) {
this.depositHotel = depositHotel;
}
public String getDestinationHotel() {
return destinationHotel;
}
public void setDestinationHotel(String destinationHotel) {
this.destinationHotel = destinationHotel;
}
public Float getDepositHotelAmount() {
return depositHotelAmount;
}
public void setDepositHotelAmount(Float depositHotelAmount) {
this.depositHotelAmount = depositHotelAmount;
}
public Float getDestinationHotelAmount() {
return destinationHotelAmount;
}
public void setDestinationHotelAmount(Float destinationHotelAmount) {
this.destinationHotelAmount = destinationHotelAmount;
}
public Address getDestinationAddress() {
return destinationAddress;
}
public void setDestinationAddress(Address destinationAddress) {
this.destinationAddress = destinationAddress;
}
public Address getRefundAddress() {
return refundAddress;
}
public void setRefundAddress(Address refundAddress) {
this.refundAddress = refundAddress;
}
}
and
public test postOrder ( HotelswitchHotelOrderRequestBody order) {
HttpEntity<String> entity = new HttpEntity<String>(new JSONObject(order).toString(), headers());
ResponseEntity<OrderResponse> response = new RestTemplate()
.exchange(URL,
HttpMethod.POST, entity, new ParameterizedTypeReference<OrderResponse>() {});
return response.getBody();
}
But i have this error:
java.lang.NoSuchMethodError: org.json.JSONObject.<init>(Ljava/lang/Object;)V
at io.bonanza.backend.service.Hotelswitch.HotelswitchHotelService.postOrder(HotelswitchHotelService.java:132)
at io.bonanza.backend.service.Hotelswitch.HotelswitchHotelServiceTests.testPostOrder(HotelswitchHotelServiceTests.java:151)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.googlecode.libphonenumber</groupId>
<artifactId>libphonenumber</artifactId>
<version>8.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Spring Security -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-test -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<!-- <version>4.5.4</version> -->
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
</dependency>
<!-- Firebase dependencies -->
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-firestore</artifactId>
<version>0.26.0-beta</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
</dependencies>
It looks like you have more than one org.json:json dependency on your classpath.
Looking at it:
org.springframework.boot:spring-boot-starter-test depends on
com.jayway.jsonpath:json-path which in turn brings
org.json:json which is may be newer/older than the version on which
io.jsonwebtoken jjwt 0.9.1 is dependent on
You could try excluding this transitive dependency from spring-boot-starter-test/io.jsonwebtoken:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
</exclusions>
</dependency>
OR/AND
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
<exclusions>
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
</exclusions>
</dependency>
But it's possible that there is something within json-path which depends on something from the older json library, which is no longer in the newer version, so proceed with caution and test everything thoroughly.
There is also a chance that something else brings org.json:json.
To verify, please run mvn dependency:tree and search in the produced output for org.json:json.
Please check this link :
spring-boot issue 8706
Exclusion of android-json from spring-boot-starter-test worked for me.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
I found this on another page. I tried the checked answer here and it didn't work with mine, but when I inserted this into my pom file it worked. I'm running unit tests with mockito and one of the endpoints uses JSONObject.put and was giving me the no such method error.
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
Your destinationAddress and refundAddress are passed as list of address or address array in the JSON while in the HotelswitchHotelOrderRequestBody your destinationAddress and refundAddress are refered to as single Address Element. Update your pojo or JSON and try again. This might be an issue.
You need to convert your POJO to JSONObject using ObjectMapper or include json dependency
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
The issue should be the destinationAddress and refundAddress is mismatch between your JSON and POJO.
Try to change your JSON like this:
{
"depositHotel": "xxx",
"destinationHotel": "aaa",
"depositHotelAmount": "0.2",
"destinationHotelAmount": "4",
"destinationAddress": {
"address": "asdf",
"tag": ""
},
"refundAddress": {
"address": "pio",
"tag": ""
}
}
If you dont want to change your JSON, change your Builder POJO to use Address[] instead of Address object.
You should not need the JSONobject
HttpEntity<HotelswitchHotelOrderRequestBody> entity = new HttpEntity<HotelswitchHotelOrderRequestBody>(order, headers());
if all you want to do is to convert your object to a string then use an object mapper.
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(car)

Null Autowired Spring Bean (Cassandra Repository) in Service

I am getting a NullPointerException on an autowired bean in a service class. The class I'm trying to autowire is a Cassandra Repository.
My main class Application.java
#SpringBootApplication
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
My Cassandra configuration CassandraConfig.java
#Configuration
#EnableCassandraRepositories(basePackages = "com.myretail")
public class CassandraConfig extends AbstractCassandraConfiguration {
#Override
protected String getKeyspaceName() {
return "myretail";
}
#Bean
public CassandraClusterFactoryBean cluster() {
CassandraClusterFactoryBean cluster =
new CassandraClusterFactoryBean();
cluster.setContactPoints("127.0.0.1");
cluster.setPort(9042);
return cluster;
}
#Bean
public CassandraMappingContext cassandraMapping()
throws ClassNotFoundException {
return new BasicCassandraMappingContext();
}
#Bean
public ProductService productService() {
return new ProductService();
}
}
My repository (dao) ProductPriceRepository.java
public interface ProductPriceRepository extends CassandraRepository<ProductPrice> {
#Query("select * from productprice where productId = ?0")
ProductPrice findByProductId(String productId);
}
My service class ProductService.java
#Path("/product")
#Component
public class ProductService {
#Autowired
ProductPriceRepository productPriceRepository;
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Product getTargetProduct(#PathParam("id") String productId) {
String urlString = "https://api.vendor.com/products/v3/" + productId + "?fields=descriptions&id_type=TCIN&key=43cJWpLjH8Z8oR18KdrZDBKAgLLQKJjz";
JSONObject json = null;
try {
json = new JSONObject(JsonReader.getExternalJsonResponse(urlString));
} catch (JSONException e) {
e.printStackTrace();
}
Product product = new Product();
product.setId(productId);
try {
JSONObject productCompositeResponse = json.getJSONObject("product_composite_response");
JSONArray items = productCompositeResponse.getJSONArray("items");
JSONObject item = items.getJSONObject(0);
JSONObject onlineDescription = item.getJSONObject("online_description");
product.setName(onlineDescription.getString("value"));
} catch (JSONException e) {
e.printStackTrace();
}
ProductPrice productPrice = productPriceRepository.findByProductId(productId);
product.setProductPrice(productPrice);
return product;
}
}
My pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myretail</groupId>
<artifactId>MyRetail</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>MyRetail</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-cassandra</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.cassandraunit</groupId>
<artifactId>cassandra-unit-spring</artifactId>
<version>2.1.9.2</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.cassandraunit</groupId>
<artifactId>cassandra-unit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.cassandraunit</groupId>
<artifactId>cassandra-unit-shaded</artifactId>
<version>2.1.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hectorclient</groupId>
<artifactId>hector-core</artifactId>
<version>2.0-0</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>my-tomcat</server>
<path>/myRetail</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
It is my understanding that the annotations should pick up the repository and create the bean based off of the #EnableCassandraRepositories annotation. The #Autowired ProductPriceRepository in ProductService.java is always null though when I run this on tomcat. HOWEVER, if I run a junit test against the service call, the bean is properly created, the object is not null, and the tests pass (via #ContextConfiguration annotation).
I've looked at a couple different patterns that I thought might help, but none of them have worked. I can't create an implementation of my interface because Cassandra handles that internally and I'm forced to implement the Cassandra methods.
I feel like something is just slightly off with the annotations somewhere. Any ideas?
The problem is with your pom.xml
For spring-boot Cassandra application, you have to include below dependencies and parent pom in pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
</dependencies>

There was an unexpected error (type=Not Acceptable, status=406) for Spring #RestController, spring-boot

I'm trying to return xml from my #RestController method -
#RestController
public class MCSController {
.
.
#RequestMapping(value = "/encoders", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML })
public List<EncoderVO> getEncoders() {
List<EncoderVO> encoders = null;
try {
encoders = infoService.listEncoders();
} catch (MCSException e) {
logger.error("Error in listing encoders : " + e.getMessage());
}
return encoders;
}
Here is my EncoderVO.java -
#XmlRootElement
public class EncoderVO {
#XmlElement
private Long id;
#XmlElement
private String name;
#XmlElement
private Boolean flagActive;
public EncoderVO() {
}
public EncoderVO(Long id, String name, Boolean flagActive) {
super();
this.id = id;
this.name = name;
this.flagActive = flagActive;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getFlagActive() {
return flagActive;
}
public void setFlagActive(Boolean flagActive) {
this.flagActive = flagActive;
}
}
This is my pom.xml file -
<?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.test</groupId>
<artifactId>mcs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
</parent>
<properties>
<aws.sdk-version>1.9.1</aws.sdk-version>
<liquibase.version>3.3.0</liquibase.version>
</properties>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
<exclusions>
<exclusion>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- Aws SDK Dependencies -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-elastictranscoder</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sqs</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sns</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-datapipeline</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cloudfront</artifactId>
<version>${aws.sdk-version}</version>
</dependency>
</dependencies>
</project>
Below is my Application class -
#SpringBootApplication(exclude = { SpringBootWebSecurityConfiguration.class, LiquibaseAutoConfiguration.class })
#ComponentScan(basePackages = { "com.test.ott.mcs" })
#EnableAspectJAutoProxy
#EnableJms
#EntityScan("com.test.ott.mcs.entities")
#EnableJpaRepositories("com.test.ott.mcs.repository")
public class MCSApplication {
#Bean
JmsListenerContainerFactory<?> jmsContainerFactory(ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
// A core poll size of 3 threads and a maximum pool size of 10 threads
factory.setConcurrency("3-10");
return factory;
}
// Using factory pattern with spring annotation
#Bean
public FactoryBean serviceLocatorFactoryBean() {
ServiceLocatorFactoryBean factoryBean = new ServiceLocatorFactoryBean();
factoryBean.setServiceLocatorInterface(EncodingAPIFactory.class);
return factoryBean;
}
public static void main(String args[]) {
SpringApplication.run(MCSApplication.class, args);
}
}
When I hit the url /encoders in browser, i get the below error -
There was an unexpected error (type=Not Acceptable, status=406). Could
not find acceptable representation
The jackson related jars in my calsspath are -
jackson-core-asl : 1.9.13
jackson-jaxrs : 1.9.13
jackson-mapper-asl : 1.9.13
jackson-annotations : 2.6.3
jackson-core : 2.6.3
jackson-module-jaxb-annotations : 2.2.3
jackson-jaxrs-json-provider : 2.2.3
jackson-jaxrs-base : 2.5.4
jackson-databind : 2.6.3
So, I have MappingJackson2HttpMessageConverter in my classpath.
Please suggest. Thanks in advance.
There is a solution that will work out-of-the-box, similarly to JAX-RS but with a bit worse output. The solution uses jackson-dataformat-xml. Add dependency to your project:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
Response will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<List>
<item>
<id>1</id>
<name>testEncoder1</name>
<flagActive>true</flagActive>
</item>
<item>
<id>2</id>
<name>testEncoder2</name>
<flagActive>true</flagActive>
</item>
<item>
<id>3</id>
<name>testEncoder3</name>
<flagActive>true</flagActive>
</item>
</List>
For further details please look at Spring MVC Way (jackson-dataformat-xml)
try
http://localhost:8080/mcs-0.0.1-SNAPSHOT/encoders.
mcs is the name of the application and
0.0.1-SNAPSHOT the version.
If it doesn't works you have to add a global path into the RequestController. Something like:
#RestController
#RequestMapping(value = "/mcs")
public class MCSController {
.
.
#RequestMapping(value = "/encoders", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML })
public List<EncoderVO> getEncoders() {
and this request:
http://localhost:8080/mcs-0.0.1-SNAPSHOT/mcs/encoders
i hope it helps you.
Cheers
Add this dependecy in you POM.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
problem is with version of this jar. so please try out this solution

Categories

Resources