Null Pointer Exception in POST method in jersey - nullpointerexception

I am building a web project using jersey and hibernate. I am testing crud operations in postman. For POST method i get a null pointer exception and I don't know how to solve. Please help me. I am new in jersey.
Below is my code and my full stack trace.
BookRepository.com
package com.bookstrore.repository;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Transaction;
import org.hibernate.Session;
import org.hibernate.Query;
import com.bookstrore.model.Book;
import com.bookstrore.model.SessionUtil;
//import com.pluralsight.model.User;
public class BookRepositoryStub {
public void createBook(Book book) {
Session session = SessionUtil.getSession();
Transaction tx = session.beginTransaction();
createBook(session,book);
tx.commit();
session.close();
}
private void createBook(Session session, Book bo){
Book book=new Book();
book.setBook_id(bo.getBook_id());
book.setBook_title(bo.getBook_title());
book.setBook_author(bo.getBook_author());
book.setBook_description(bo.getBook_description());
book.setBook_price(bo.getBook_price());
session.save(book);
}
public List<Book> getBooks(){
Session session = SessionUtil.getSession();
Query query = session.createQuery("from Book");
List<Book> books = query.list();
session.close();
return books;
}
public int delete(int book_id){
Session session = SessionUtil.getSession();
Transaction tx = session.beginTransaction();
String hql = "delete from Book where book_id = :book_id";
Query query = session.createQuery(hql);
query.setInteger("book_id",book_id);
int rowCount = query.executeUpdate();
System.out.println("Rows affected: " + rowCount);
tx.commit();
session.close();
return rowCount;
}
public int update(int book_id, Book bo){
if(book_id <=0)
return 0;
Session session = SessionUtil.getSession();
Transaction tx = session.beginTransaction();
String hql = "update Book set book_title = :book_title, book_author = :book_author, book_description = :book_description, book_price = :book_price, where book_id = :book_id";
Query query = session.createQuery(hql);
query.setInteger("book_id", book_id);
query.setString("book_title",bo.getBook_title());
query.setString("book_author",bo.getBook_author());
query.setString("book_description",bo.getBook_description());
query.setInteger("book_price",bo.getBook_price());
int rowCount = query.executeUpdate();
System.out.println("Rows affected: " + rowCount);
tx.commit();
session.close();
return rowCount;
}
}
BookResource.java
package com.bookstrore;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.bookstrore.model.Book;
//import com.ebook.model.User;
//import com.ebook.repository.BookRepository;
import com.bookstrore.repository.BookRepositoryStub;
#Path("books")
public class BookResource {
//private BookRepository bookRepository=new BookRepositoryStub();
#GET
#Produces("application/json")
public List<Book> getBook() {
BookRepositoryStub book = new BookRepositoryStub();
List books = book.getBooks();
return books;
}
#DELETE
#Path("{bookId}")
#Consumes("application/json")
public Response delete(#PathParam("bookId") int book_id){
BookRepositoryStub book = new BookRepositoryStub();
int count = book.delete(book_id);
if(count==0){
return Response.status(Response.Status.BAD_REQUEST).build();
}
return Response.ok().build();
}
#PUT
#Path("{bookId}")
//#Consumes(MediaType.APPLICATION_JSON)
#Consumes("application/json")
public Response update(#PathParam("bookId") int book_id, Book bo){
BookRepositoryStub book = new BookRepositoryStub();
int count = book.update(book_id, bo);
if(count==0){
return Response.status(Response.Status.BAD_REQUEST).build();
}
return Response.ok().build();
}
#POST
#Path("book")
#Consumes("application/json")
//#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response createBook(Book bo){
bo.setBook_title(bo.getBook_title());
bo.setBook_author(bo.getBook_author());
bo.setBook_description(bo.getBook_description());
bo.setBook_price(bo.getBook_price());
BookRepositoryStub book = new BookRepositoryStub();
book.createBook(bo);
return Response.ok().build();
}
}
Book.java
package com.bookstrore.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="book")
public class Book {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int book_id;
#Column
private String book_title;
#Column
private String book_author;
#Column
private String book_description;
#Column
private int book_price;
public int getBook_id() {
return book_id;
}
public void setBook_id(int book_id) {
this.book_id = book_id;
}
public String getBook_title() {
return book_title;
}
public void setBook_title(String book_title) {
this.book_title = book_title;
}
public String getBook_author() {
return book_author;
}
public void setBook_author(String book_author) {
this.book_author = book_author;
}
public String getBook_description() {
return book_description;
}
public void setBook_description(String book_description) {
this.book_description = book_description;
}
public int getBook_price() {
return book_price;
}
public void setBook_price(int book_price) {
this.book_price = book_price;
}
}
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.bookstore</groupId>
<artifactId>BookStore</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>BookStore</name>
<build>
<finalName>BookStore</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.10.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
</dependencies>
<properties>
<jersey.version>2.22.1</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.bookstrore</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</web-app>
Stack Trace:
<pre>java.lang.NullPointerException
com.bookstrore.BookResource.createBook(BookResource.java:72)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
org.glassfish.jersey.internal.Errors.process(Errors.java:315)
org.glassfish.jersey.internal.Errors.process(Errors.java:297)
org.glassfish.jersey.internal.Errors.process(Errors.java:267)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
</pre>
I am looking forward for your help! Please! Thank you!

I believe that there are two problems in your code that by changing them, your problem will be solved.
First of all, in your class "Book" you need to write the constructor with all the parameters, besides the id (that is auto-generated by hibernate), and also have a no-argument constructor. So add this:
And on the other hand, you have to declare your class "Book" as #XmlRootElement as you did with #Entity and #Table.
This video explains the why of all of this and it is also a great tutorial for beginners with web services and jersey:
https://www.youtube.com/watch?v=BaZdlJSts5A&list=PLqq-6Pq4lTTZh5U8RbdXq0WaYvZBz2rbn&index=14
Hope this helps! Your Book class should look like this:
#Entity
#Table(name="book")
#XmlRootElement
public class Book {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int book_id;
#Column
private String book_title;
#Column
private String book_author;
#Column
private String book_description;
#Column
private int book_price;
public Book(){ }
public Book(String title, String author, String description, int price){
book_title = title;
book_author = author;
book_description = description;
book_price = price;
}
public int getBook_id() {
return book_id;
}
public void setBook_id(int book_id) {
this.book_id = book_id;
}
public String getBook_title() {
return book_title;
}
public void setBook_title(String book_title) {
this.book_title = book_title;
}
public String getBook_author() {
return book_author;
}
public void setBook_author(String book_author) {
this.book_author = book_author;
}
public String getBook_description() {
return book_description;
}
public void setBook_description(String book_description) {
this.book_description = book_description;
}
public int getBook_price() {
return book_price;
}
public void setBook_price(int book_price) {
this.book_price = book_price;
}
}

Related

JAXB: Marshalling changes object type to String for XmlIDREF

I am facing a problem when serializing an object. The object is a representation of a stack. The Stack can either consist of individual Layers or a sequence of Layers stored in a LayerSequence. So, Layer and LayerSequence implement Stackable and the Stack holds a List of Stackable. Since Layer and LayerSequence are stored independently of Stack, I use XmlIDREF to reference them by a name.
To help JAXB resolving the interface implementations, I define
#XmlElementWrapper(name="layers")
#XmlElements({
#XmlElement(name="layer", type=Layer.class)
,#XmlElement(name="layerSequence", type=LayerSequence.class)
})
#XmlIDREF
private List<S> layers;
When serializing with a generic Stack<? extends Stackable> the type is not transferred as I would have expected. The type is changed to a String containing the XmlID. The result is:
<stack name="stack">
<layers>
<layer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">layer</layer>
</layers>
</stack>
For a specific example, where I know, that only Layers and no LayerSequences are used and I define
#XmlElementWrapper(name="layers")
#XmlElements({
#XmlElement(name="layer", type=Layer.class)
})
#XmlIDREF
private List<S> layers;
the type is properly defined as expected:
<stack name="stack">
<layers>
<layer>layer</layer>
</layers>
</stack>
The same works the other way around for LayerSequence.
What am I missing here? Is this a problem because LayerSequence itself uses Layers? How can I circumvent this?
MWE
Code
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlIDREF;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
public class Main
{
public static void main(String[] args) throws PropertyException, JAXBException{
LayerValueImpl layerValue1 = new LayerValueImpl("layerValue");
Layer<LayerValueImpl> layer = new Layer<>("layer",layerValue1);
List<Layer<? extends AbstractLayerValue>> layers = new ArrayList<>();
layers.add(layer);
Stack<? extends Stackable> stack = new Stack<>("stack",layers);
//
JAXBContext jc = JAXBContext.newInstance(Stack.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(stack, System.out);
}
public static interface Identifiable<
T extends Identifiable
>
{
public void setName(String name);
public String getName();
}
public static interface Stackable<
T extends Stackable
>
extends
Identifiable<T>
{
#XmlAttribute
#XmlID
#Override
public String getName();
}
#XmlTransient
#XmlAccessorType(XmlAccessType.FIELD)
public static abstract class AbstractLayerValue<
T extends AbstractLayerValue
>
implements
Identifiable<T>
{
#XmlAttribute
#XmlID
private String name;
public AbstractLayerValue() {}
public AbstractLayerValue(
String name
) {
this.name = name;
}
#Override
public void setName(String v){this.name = v;}
#Override
public String getName(){return name;}
}
#XmlRootElement
public static class LayerValueImpl
extends
AbstractLayerValue<
LayerValueImpl
>
{
public LayerValueImpl() {}
public LayerValueImpl(String name) {
super(name);
}
}
#XmlTransient
#XmlAccessorType(XmlAccessType.FIELD)
public static abstract class AbstractLayerSuperClass<
T extends AbstractLayerSuperClass
>
implements
Identifiable<T>
{
#XmlAttribute
#XmlID
private String name;
public AbstractLayerSuperClass() {}
public AbstractLayerSuperClass(
String name
) {
this.name = name;
}
#Override
public void setName(String v){this.name = v;}
#Override
public String getName(){return name;}
}
#XmlRootElement
#XmlSeeAlso({
LayerValueImpl.class
})
public static class Layer<
V extends AbstractLayerValue
>
extends
AbstractLayerSuperClass<
Layer<V>
>
implements
Stackable<Layer<V>>
{
private V value;
public Layer() {}
public Layer(
String name
,V value
) {
super(
name
);
this.value = value;
}
public void setValue(V v){this.value = v;}
public V getValue(){return value;}
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public static class LayerSequence
implements
Stackable<LayerSequence>
{
#XmlAttribute
#XmlID
private String name;
private List<Layer<? extends AbstractLayerValue>> layers;
public LayerSequence() {}
public LayerSequence(
String name
,List<Layer<? extends AbstractLayerValue>> layers
) {
this.name = name;
this.layers = layers;
}
#Override
public void setName(String v){this.name = v;}
#Override
public String getName(){return name;}
public void setLayers(List<Layer<? extends AbstractLayerValue>> v){this.layers = v;}
public List<Layer<? extends AbstractLayerValue>> getLayers(){return layers;}
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public static class Stack<
S extends Stackable
>
implements
Identifiable<Stack<S>>
{
#XmlAttribute
#XmlID
private String name;
#XmlElementWrapper(name="layers")
#XmlElements({
#XmlElement(name="layer", type=Layer.class)
,#XmlElement(name="layerSequence", type=LayerSequence.class)
})
//#XmlElementRefs({
// #XmlElementRef(type=Layer.class, name="layer"),
// #XmlElementRef(type=LayerSequence.class, name="layerSequence")
//})
#XmlIDREF
private List<S> layers;
public Stack() {}
public Stack(
String name
,List<S> layers
) {
this.name = name;
this.layers = layers;
}
#Override
public void setName(String v){this.name = v;}
#Override
public String getName(){return name;}
public void setLayers(List<S> v){this.layers = v;}
public List<S> getLayers(){return layers;}
}
}
POM
<?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>de.mr</groupId>
<artifactId>test</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<!-- PROPERTIES -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- System -->
<java.version>16</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.plugin.compiler.version>3.8.1</maven.plugin.compiler.version>
<maven.plugin.enforcer.version>3.0.0-M2</maven.plugin.enforcer.version>
<maven.plugin.jar.version>3.2.0</maven.plugin.jar.version>
<maven.plugin.release.version>2.5.3</maven.plugin.release.version>
<!-- Log4j2 -->
<log4j.api.version>2.13.1</log4j.api.version>
<log4j.core.version>2.13.1</log4j.core.version>
<!-- Lombok -->
<lombok.version>1.18.22</lombok.version>
<maven.plugin.lombok.version>1.18.20.0</maven.plugin.lombok.version>
<!-- Stuff for JAXB -->
<javax.xml.bind.jaxb-api.version>2.4.0-b180830.0359</javax.xml.bind.jaxb-api.version>
<javax.activation.activation.version>1.1</javax.activation.activation.version>
<org.glassfish.jaxb.jaxb-runtime.version>2.3.0-b170127.1453</org.glassfish.jaxb.jaxb-runtime.version>
<maven.plugin.jaxb2.version>2.5.0</maven.plugin.jaxb2.version>
<maven.plugin.jaxb2.locale>en</maven.plugin.jaxb2.locale>
<maven.plugin.jaxb2.clearOutputDir>true</maven.plugin.jaxb2.clearOutputDir>
<maven.plugin.jaxb2.createJavaDocAnnotations>false</maven.plugin.jaxb2.createJavaDocAnnotations>
</properties>
<!-- DEPENDENCIES -->
<dependencies>
<!-- -->
<!-- 3rd party -->
<!-- -->
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- Log4j2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.api.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.core.version}</version>
</dependency>
<!-- Stuff for JAXB -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${javax.xml.bind.jaxb-api.version}</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>${javax.activation.activation.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>${org.glassfish.jaxb.jaxb-runtime.version}</version>
</dependency>
</dependencies>
<!-- BUILD -->
<build>
<!-- PLUGINS -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.plugin.compiler.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>${maven.plugin.enforcer.version}</version>
<executions>
<execution>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
<configuration>
<rules>
<requireJavaVersion>
<version>${java.version}</version>
</requireJavaVersion>
</rules>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>${maven.plugin.release.version}</version>
<configuration>
<localCheckout>true</localCheckout>
<pushChanges>false</pushChanges>
</configuration>
</plugin>
<!-- Delombok -->
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>${maven.plugin.lombok.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
<configuration>
<encoding>UTF-8</encoding>
<addOutputDirectory>false</addOutputDirectory>
<sourceDirectory>src/main/java</sourceDirectory>
<withoutUnicodeEscape>true</withoutUnicodeEscape>
</configuration>
</plugin>
<!-- Generate a XSD schema -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>${maven.plugin.jaxb2.version}</version>
<executions>
<execution>
<id>schemagen</id>
<goals>
<goal>schemagen</goal>
</goals>
</execution>
</executions>
<configuration>
<sources>
<source>src/main/java/de/mr/test/jaxbschemagenlombok</source>
</sources>
<outputDirectory>${project.build.directory}/generated-sources/schemas</outputDirectory>
<clearOutputDir>${maven.plugin.jaxb2.clearOutputDir}</clearOutputDir>
<createJavaDocAnnotations>${maven.plugin.jaxb2.createJavaDocAnnotations}</createJavaDocAnnotations>
<locale>${maven.plugin.jaxb2.locale}</locale>
</configuration>
</plugin>
</plugins>
<!-- THIS IS THE FINAL NAME OF THE JAR -->
<finalName>${project.artifactId}-${project.version}</finalName>
</build>
</project>

Cannot connect to mongoDB using Spring Data Reactive and Spring Boot 2.0

I get the following error every time I trying to connect to MongoDB using Spring Data Reactive and Spring Boot 2.0.
Caused by: java.lang.UnsupportedOperationException: No SSL support in java.nio.channels.AsynchronousSocketChannel. For SSL support use com.mongodb.connection.netty.NettyStreamFactoryFactory
at com.mongodb.connection.AsynchronousSocketChannelStreamFactory.<init>(AsynchronousSocketChannelStreamFactory.java:41)
at com.mongodb.async.client.MongoClients.getStreamFactory(MongoClients.java:228)
at com.mongodb.async.client.MongoClients.create(MongoClients.java:177)
at com.mongodb.async.client.MongoClients.create(MongoClients.java:123)
at com.mongodb.reactivestreams.client.MongoClients.create(MongoClients.java:103)
at com.mongodb.reactivestreams.client.MongoClients.create(MongoClients.java:53)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoClientFactory.createNetworkMongoClient(ReactiveMongoClientFactory.java:123)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoClientFactory.createMongoClient(ReactiveMongoClientFactory.java:69)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration.reactiveStreamsMongoClient(ReactiveMongoAutoConfiguration.java:67)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration$$EnhancerBySpringCGLIB$$94536095.CGLIB$reactiveStreamsMongoClient$1(<generated>)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration$$EnhancerBySpringCGLIB$$94536095$$FastClassBySpringCGLIB$$2171f816.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
at org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration$$EnhancerBySpringCGLIB$$94536095.reactiveStreamsMongoClient(<generated>)
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.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1246)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1093)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:534)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:250)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1128)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:833)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:740)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:466)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1246)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1093)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:534)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:250)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1128)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:833)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:740)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:466)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1246)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1093)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:534)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1604)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1349)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:250)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1128)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:570)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:358)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1337)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:865)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:809)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:404)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:347)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:128)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:102)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:47)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:243)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:226)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:245)
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:189)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
The error message tells me to use NettyStreamFactoryFactory for SSL support. Does anyone have any examples on how to do this? The database I am trying to connect to is MongoDB Atlas, it strictly require a SSL connection.
Below is the rest of my code:
#SpringBootApplication
public class FlixMovieApiReactiveApplication {
public static void main(String[] args) {
SpringApplication.run(FlixMovieApiReactiveApplication.class, args);
}
// Add Data
#Bean
public CommandLineRunner initDatabase(MovieRepository repository) {
// entire process blocking, done in beginning
Flux<Movie> movieList = Flux.just(
new Movie("movie1", "1", "movie1"),
new Movie("movie2", "1", "movie2"),
new Movie("movie3", "5", "movie3"),
new Movie("movie4", "1", "movie4"),
new Movie("movie5", "3", "movie5"),
new Movie("movie6", "1", "movie6"),
new Movie("movie7", "2", "movie7"),
new Movie("movie8", "3", "movie8"),
new Movie("movie9", "1", "movie9"),
new Movie("movie10", "2", "movie10"),
new Movie("movie11", "1", "movie11"),
new Movie("movie12", "3", "movie12"),
new Movie("movie13", "1", "movie13"),
new Movie("movie14", "4", "movie14"),
new Movie("movie15", "1", "movie15"),
new Movie("movie16", "4", "movie16")
);
// delete then insert data. blockLast(), allows something to subscribe to pipeline, block for last emitted element
// data is written to the database.
return args -> repository.deleteAll().thenMany(repository.save(movieList)).blockLast();
}
}
#RestController
public class MovieRestController {
#Autowired
private MovieService movieService;
#GetMapping(value = "/movies")
public Flux<ResponseEntity<Movie>> list() {
return movieService.list().map(m -> new ResponseEntity<>(m, HttpStatus.OK));
}
#GetMapping(value = "/moviesByRating")
public Flux<ResponseEntity<Movie>> findByRating(
#RequestParam(value = "rating", required = false) final String rating) {
return movieService.findByRating(rating)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK));
}
#GetMapping("/movies/{movieId}")
public Mono<ResponseEntity<Movie>> read(
#PathVariable("movieId") final String movieId) {
return movieService.read(movieId)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
#DeleteMapping("/movies/{movieId}")
public Mono<ResponseEntity<Movie>> delete(
#PathVariable("movieId") final String movieId) {
return movieService.delete(movieId)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
#PutMapping("/movies/{movieId}")
public Mono<ResponseEntity<Movie>> update(
#PathVariable("movieId") final String movieId,
#RequestBody final MovieRequest movieRequest) {
return movieService.update(movieId, movieRequest)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
#PostMapping("/movies")
public Mono<ResponseEntity<Movie>> create(
#RequestBody final Mono<MovieRequest> movieRequest) {
return movieService.create(movieRequest)
.map(m -> new ResponseEntity<>(m, HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
}
#Service
public class MovieServiceImpl implements MovieService {
#Autowired
private MovieRepository movieRepository;
#Override
public Flux<Movie> list(){
return movieRepository.findAll();
}
#Override
public Flux<Movie> findByRating(final String rating){
return movieRepository.findByRating(rating);
}
#Override
public Mono<Movie> update(String id, MovieRequest movieRequest) {
return movieRepository.findOne(id).map(existingMovie -> {
if(movieRequest.getDescription() != null){
existingMovie.setDescription(movieRequest.getDescription());
}
if(movieRequest.getRating() != null){
existingMovie.setRating(movieRequest.getRating());
}
if(movieRequest.getTitle() != null) {
existingMovie.setTitle(movieRequest.getTitle());
}
return existingMovie;
}).then(movieRepository::save);
}
#Override
public Mono<Movie> create(Mono<MovieRequest> movieRequest) {
return movieRequest.map(newMovie -> {
Movie movie = new Movie();
if(newMovie.getDescription() != null){
movie.setDescription(newMovie.getDescription());
}
if(newMovie.getRating() != null){
movie.setRating(newMovie.getRating());
}
if(newMovie.getTitle() != null) {
movie.setTitle(newMovie.getTitle());
}
return movie;
}).then(movieRepository::save);
}
#Override
public Mono<Movie> read(String id) {
return movieRepository.findOne(id);
}
#Override
public Mono<Movie> delete(String id) {
return movieRepository.findOne(id)
.flatMap(oldValue -> movieRepository.delete(id).then(Mono.just(oldValue)))
.singleOrEmpty();
}
}
#Repository
public interface MovieRepository extends ReactiveMongoRepository<Movie, String> {
Flux<Movie> findByRating(String rating);
}
#Document
public class Movie {
#Id
private String id;
private String title;
private String rating;
private String description;
public Movie(String title, String rating, String description) {
this.title = title;
this.rating = rating;
this.description = description;
}
public Movie() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
---
spring:
data:
mongodb:
uri: mongodb://admin:xxxxxx#movie-shard-00-00-xfzg4.mongodb.net:27017,movie-shard-00-01-xfzg4.mongodb.net:27017,movie-shard-00-02-xfzg4.mongodb.net:27017/movie?ssl=true&replicaSet=Movie-shard-0&authSource=admin
management:
context-path: /admin
server:
port: 8080
Below is the 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.flix.movie</groupId>
<artifactId>flix-movie-api-reactive</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>flix-movie-api-reactive</name>
<description>Demo project for Spring Boot using Non-Blocking Reactive Spring Web MVC and Spring Data MongoDB</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</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>
<docker.image.prefix>flix</docker.image.prefix>
<docker.spotify.plugin.version>0.4.5</docker.spotify.plugin.version>
<swagger.version>2.4.0</swagger.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-dependencies-web-reactive</artifactId>
<version>0.1.0.BUILD-SNAPSHOT</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>
<!-- Package as a docker image -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.spotify.plugin.version}</version>
<configuration>
<serverId>docker-hub</serverId>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
Try
in connection String
xxxx?ssl=true&sslInvalidHostNameAllowed=true&streamType=netty
or Via MongoClientSettings
EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); // make sure application shuts this down
#Bean
public MongoClient getClient()
{
return MongoClients.create(MongoClientSettings.builder()
.clusterSettings(ClusterSettings.builder()
.hosts(Arrays.asList(new ServerAddress()))
.build())
.streamFactoryFactory(NettyStreamFactoryFactory.builder()
.eventLoopGroup(eventLoopGroup).build())
.sslSettings(SslSettings.builder()
.enabled(true)
.build())
.build());
}
#PreDestroy
public void shutDownEventLoopGroup() {
eventLoopGroup.shutdownGracefully();
}
Reference
This sounds like a Spring Data Mongo and/or Spring Boot issue.
At first it seems Spring Boot is giving the appropriate information to the Spring Data Mongo client configuration.
Could you create an issue on the dedicated issue tracker for Spring Data Mongo?
As mp911de mentioned above, adding Netty dependency in your pom will solve the problem.
For me, adding the spring-boot-starter-webflux resolved the issue.
It's the MongoClient who is responsible for managing the connection. In your case it is the default unprotected one, so if you have security enabled on your Mongo instance he will bounce back.
#Configuration
#EnableReactiveMongoRepositories
class MongoConfig : AbstractReactiveMongoConfiguration() {
override fun reactiveMongoClient(): MongoClient = MongoClients.create()
override fun getDatabaseName(): String = "mydb"
}
This is my configuration for reactive mongo in spring boot 2 M4. You can customize your client via MongoClients methods or appropriate constructor.

Could not initialize class org.eclipse.persistence.jaxb.BeanValidationHelper while trying to get JSON response

I am making application using JAVA EE,JAX-RS,JPA,GLASSFISH. Response is working properly in case of MediaType.APPLICATION_XML. It's not working in MediaType.APPLICATION_JSON.
Here is my pojo class
#Entity
#XmlRootElement
public class Book {
private int id;
private String name;
private String publication;
private String price;
#Id
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "publication")
public String getPublication() {
return publication;
}
public void setPublication(String publication) {
this.publication = publication;
}
#Basic
#Column(name = "price")
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Book book = (Book) o;
if (id != book.id) return false;
if (name != null ? !name.equals(book.name) : book.name != null) return false;
if (publication != null ? !publication.equals(book.publication) : book.publication != null) return false;
if (price != null ? !price.equals(book.price) : book.price != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (publication != null ? publication.hashCode() : 0);
result = 31 * result + (price != null ? price.hashCode() : 0);
return result;
}
}
Here is the 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.rajesh</groupId>
<artifactId>Library</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Resource class for endpoint
#Path("books")
public class BookResource {
#GET
#Path("{bookId}")
#Produces({MediaType.APPLICATION_JSON})
public Response getBookById(#PathParam("bookId") int id) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("abc");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Book book = entityManager.find(Book.class, id);
if (book == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
return Response.status(Response.Status.OK).entity(book).build();
}
}
This is a bug in Glassfish: https://github.com/javaee/glassfish/issues/21440
It probably won't be fixed, you should switch to http://www.payara.fish/ which is patched and updated version of Glassfish (has even commercial support if needed).
This bug is fixed in Payara.
Place the "org.eclipse.persistence.moxy.jar" into
$GLASSFISHINSTALL/glassfish/modules
Then restart the glassfish
Problem had been occurred due to version of Glassfish 4.1.1.It appears there is a bug in Eclipse Link . I am using Glassfish 4.1.0 for temporary solution.
I had the same error, but my mistake was pretty funny.
I had my pom.xml pointing to EE7 API as follows:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
Meanwhile, I forgot that Glassfish 4.x implements EE6 not EE7....
I downloaded Eclipse Glassfish 5.1.0 then I was sorted!

PowerMockito.whenNew isn't working

Update. Check working example in the end.
I've got a class:
package test;
public class ClassXYZ {
private final String message;
public ClassXYZ() {
this.message = "";
}
public ClassXYZ(String message) {
this.message = message;
}
#Override
public String toString() {
return "ClassXYZ{" + message + "}";
}
}
and a test:
package test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
public class MockClassXYZ {
#Test
public void test() throws Exception {
PowerMockito.whenNew(ClassXYZ.class).withNoArguments().thenReturn(new ClassXYZ("XYZ"));
System.out.println(new ClassXYZ());
}
}
but it still creates a real class and prints:
ClassXYZ{}
What am I doing wrong?
P.S. Maven deps:
<dependencies>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.5.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.5.6</version>
<scope>test</scope>
</dependency>
</dependencies>
Working example:
package test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassXYZ.class)
public class MockClassXYZ {
#Test
public void test() throws Exception {
ClassXYZ mockXYZ = mock(ClassXYZ.class);
when(mockXYZ.toString()).thenReturn("XYZ");
PowerMockito.whenNew(ClassXYZ.class).withNoArguments().thenReturn(mockXYZ);
ClassXYZ obj = new ClassXYZ();
System.out.println(obj);
}
}
You are missing a #PrepareForTest(ClassXYZ.class) on your test class, see the documentation here or here. From the first link:
Mock construction of new objects
Quick summary
Use the #RunWith(PowerMockRunner.class) annotation at the class-level
of the test case.
Use the #PrepareForTest(ClassThatCreatesTheNewInstance.class) annotation at
the class-level of the test case.
[...]
Also note that there's no point of mocking the constructor if you ask the mocking framework to return a real instance of the mocked class.

Jackson #Deserializer doesn't work

This is a duplicated question of this
POJO
#Entity
#Table(name = "pet")
public class Pet {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long petId;
private String petName;
private Date birthday;
#JsonSerialize(using = Serializer.class)
public Date getBirthday() {
return birthday;
}
#JsonDeserialize(using = Deserializer.class)
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Long getPetId() {
return petId;
}
public void setPetId(Long petId) {
this.petId = petId;
}
public String getPetName() {
return petName;
}
public void setPetName(String petName) {
this.petName = petName;
}
}
Serializer
public class Serializer extends JsonSerializer<Date> {
#Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
System.out.println("Serializer");
}
}
Deserializer
public class Deserializer extends JsonDeserializer<Date> {
#Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
System.out.println("Deserializer works.");
return new Date();
}
}
Maven Dependency
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.2</version>
</dependency>
update: controller code
#Transactional
#Controller
public class Demo {
#Resource
private Dao dao;
#ResponseBody
#RequestMapping("/test")
public String tester(Pet pet){
dao.saveOrUpdate(pet);
return "success";
}
#ResponseBody
#RequestMapping("/test2")
public List<Pet> tester2(){
List<Pet> pets = dao.query(Pet.class);
return pets;
}
}
however only Serializer will be invoked everytime, Deserializer doesn't take any effect, I can't see where is wrong, could anybody help me?
Thanks.