Mapping errors in maven project - jersey

I am pretty new in restful application and maven ones. I have tried to create a web dynamic project application in maven using hibernate. But i face a 404 error problem. I think the problem is somewhere in my web.xml file. I would really appreciate if anyone could help. Below is my full code.
MyResource.java
import com.crud.dao.EmployeeDAO;
#Path("/employees")
public class MyResource {
#GET
#Produces("application/json")
public List<Employee> getEmployee() {
EmployeeDAO dao = new EmployeeDAO();
List employees = dao.getEmployees();
return employees;
}
#POST
#Path("/create")
#Consumes("application/json")
public Response addEmployee(Employee emp){
emp.setName(emp.getName());
emp.setAge(emp.getAge());
EmployeeDAO dao = new EmployeeDAO();
dao.addEmployee(emp);
return Response.ok().build();
}
#PUT
#Path("/update/{id}")
#Consumes("application/json")
public Response updateEmployee(#PathParam("id") int id, Employee emp){
EmployeeDAO dao = new EmployeeDAO();
int count = dao.updateEmployee(id, emp);
if(count==0){
return Response.status(Response.Status.BAD_REQUEST).build();
}
return Response.ok().build();
}
#DELETE
#Path("/delete/{id}")
#Consumes("application/json")
public Response deleteEmployee(#PathParam("id") int id){
EmployeeDAO dao = new EmployeeDAO();
int count = dao.deleteEmployee(id);
if(count==0){
return Response.status(Response.Status.BAD_REQUEST).build();
}
return Response.ok().build();
}
}
Employee.java
package com.crud.dao;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Employee {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column
private String name;
#Column
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
EmployeeDAO.java
public class EmployeeDAO {
public void addEmployee(Employee bean){
Session session = SessionUtil.getSession();
Transaction tx = session.beginTransaction();
addEmployee(session,bean);
tx.commit();
session.close();
}
private void addEmployee(Session session, Employee bean){
Employee employee = new Employee();
employee.setName(bean.getName());
employee.setAge(bean.getAge());
session.save(employee);
}
public List<Employee> getEmployees(){
Session session = SessionUtil.getSession();
Query query = session.createQuery("from Employee");
List<Employee> employees = query.list();
session.close();
return employees;
}
public int deleteEmployee(int id) {
Session session = SessionUtil.getSession();
Transaction tx = session.beginTransaction();
String hql = "delete from Employee where id = :id";
Query query = session.createQuery(hql);
query.setInteger("id",id);
int rowCount = query.executeUpdate();
System.out.println("Rows affected: " + rowCount);
tx.commit();
session.close();
return rowCount;
}
public int updateEmployee(int id, Employee emp){
if(id <=0)
return 0;
Session session = SessionUtil.getSession();
Transaction tx = session.beginTransaction();
String hql = "update Employee set name = :name, age=:age where id = :id";
Query query = session.createQuery(hql);
query.setInteger("id",id);
query.setString("name",emp.getName());
query.setInteger("age",emp.getAge());
int rowCount = query.executeUpdate();
System.out.println("Rows affected: " + rowCount);
tx.commit();
session.close();
return rowCount;
}
}
SessionUtil.java
package com.crud.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class SessionUtil {
private static SessionUtil instance=new SessionUtil();
private SessionFactory sessionFactory;
public static SessionUtil getInstance(){
return instance;
}
private SessionUtil(){
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
sessionFactory = configuration.buildSessionFactory();
}
public static Session getSession(){
Session session = getInstance().sessionFactory.openSession();
return session;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
<doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 2.22.1 2015-10-07 10:54:41"/>
<doc xmlns:jersey="http://jersey.java.net/" jersey:hint="This is simplified WADL with user and core resources only. To get full WADL with extended resources use the query parameter detail. Link: http://localhost:8080/jersey-webapp/webapi/application.wadl?detail=true"/>
<grammars/>
<resources base="http://localhost:8080/jerseypro/webapi/">
<resource path="/employees">
<method id="getEmployee" name="GET">
<response>
<representation mediaType="text/plain"/>
</response>
</method>
</resource>
</resources>
<servlet>
<servlet-name>jerseypro</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Define the ResourceConfig class -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.crud.jerseypro.MyResource</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Pro</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</application>
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jersey</groupId>
<artifactId>jerseypro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jerseypro</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<phase>
Employee
</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.crud.dao.Employee</mainClass>
<arguments>
<argument>
myArg1
</argument>
<argument>myArg2</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Thank you in advance!

One obvious thing is that you have the servlet mappings incorrect.
<servlet>
<servlet-name>jerseypro</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Define the ResourceConfig class -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.crud.jerseypro.MyResource</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Pro</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
You have your servlet name to be jerseypro but your servlet mapping is mapped to Jersey Pro. This should have given you an error on startup. Check your java logs to see what is going on.
Also your maven project configuration is not going to work. It looks like it is going to try and start the Employee class but that class does not have static main Method. This is also not going to work. Look into the tomcat7 maven plugin. It will start an http server to host your jersey code for testing. You can start it with mvn tomcat7:run. That should get you going.

Related

Optimistic locking Test in spring data JPA

I'm trying to test the optimistic locking mechanism in spring data jpa by loading a certain entity twice using findBy function, then updating the first one and asserting that when the second one is updated, it will throw an OptimisticLockingFailureException.
But the problem is that no exception is thrown and the second update is done successfully.
After investigation i found that findBy function hits the database only the first time and caches the returned entity. and when i call it again it returns cached entity. which means that both loaded entities are equal. so the first update reflects in both entities making the second entity does not have the stale data.
so, how do i force loading the second entity from the data base in the second findBy function call ?
Here is my code:-
Test class
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
#DataJpaTest
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class PersistenceTests {
#Autowired
private ProductRepository repository;
private ProductEntity savedEntity;
#DynamicPropertySource
static void databaseProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", () -> "jdbc:mysql://localhost:3306/code_snippet");
registry.add("spring.datasource.username", () -> "root");
registry.add("spring.datasource.password", () -> "System");
registry.add("spring.jpa.hibernate.ddl-auto", () -> "create-drop");
}
#BeforeEach
void setupDb() {
repository.deleteAll();
ProductEntity entity = new ProductEntity(1, "n", 1);
savedEntity = repository.save(entity);
assertEqualsProduct(entity, savedEntity);
}
#Test
void optimisticLockError() {
// Store the saved entity in two separate entity objects
ProductEntity entity1 = repository.findById(savedEntity.getId()).get();
ProductEntity entity2 = repository.findById(savedEntity.getId()).get();
// Update the entity using the first entity object
entity1.setName("n1");
repository.save(entity1);
// Update the entity using the second entity object.
// This should fail since the second entity now holds an old version number,
// i.e. an Optimistic Lock Error
assertThrows(OptimisticLockingFailureException.class, () -> {
entity2.setName("n2");
repository.save(entity2);
});
// Get the updated entity from the database and verify its new sate
ProductEntity updatedEntity = repository.findById(savedEntity.getId()).get();
assertEquals(1, (int) updatedEntity.getVersion());
assertEquals("n1", updatedEntity.getName());
}
private void assertEqualsProduct(ProductEntity expectedEntity, ProductEntity actualEntity) {
assertEquals(expectedEntity.getId(), actualEntity.getId());
assertEquals(expectedEntity.getVersion(), actualEntity.getVersion());
assertEquals(expectedEntity.getProductId(), actualEntity.getProductId());
assertEquals(expectedEntity.getName(), actualEntity.getName());
assertEquals(expectedEntity.getWeight(), actualEntity.getWeight());
}
}
Entity
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;
#Entity
#Table(name = "product")
public class ProductEntity {
#Id
#GeneratedValue
private Integer id;
#Version
private Integer version;
private int productId;
private String name;
private int weight;
public ProductEntity() {
}
public ProductEntity(int productId, String name, int weight) {
this.productId = productId;
this.name = name;
this.weight = weight;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
Repository
import java.util.Optional;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface ProductRepository extends PagingAndSortingRepository<ProductEntity, Integer> {
Optional<ProductEntity> findByProductId(int productId);
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.javaworld.codesnippet</groupId>
<artifactId>writing-persistence-tests</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>writing-persistence-tests</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</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>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Main Class
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class WritingPersistenceTestsApplication {
public static void main(String[] args) {
SpringApplication.run(WritingPersistenceTestsApplication.class, args);
}
}
The problem is that your test method is by default transactional. You can disable the transactional for this method by adding:
#Test
#Transactional(value = Transactional.TxType.NEVER)
Than you get in the second save ObjectOptimisticLockingFailureException

Spring Kafka Consumer consumed message as LinkedHashMap hence automatically converting BigDecimal to double

I am using annotation based spring kafka listener to consume the kafka messages, and code is as below
Consuming Employee Object
Class Employee{
private String name;
private String address;
private Object account;
//getters
//setters
}
Account object decides on runtime whether it's Saving Account or Current Account etc.
Class SavingAcc{
private BigDecimal balance;
}
Class CurrentAcc{
private BigDecimal balance;
private BigDecimal limit;
}
Saving & Current Account having BigDecimal Fields to store balance.
Hence while sending Employee object from Kafka producer, all the fields are correctly mapped and appears in correct format of BigDecimal, etc.
But while consuming the Employee object in another service, account object is appearing as LinkedHashMap and BigDecimal fields are converted to Double. which is causing issues.
As per my understanding, the main reason can be as
a) Declaration of account as Object type instead of specific type
b) Or the deserializer should be provided more specifically. [I have already give Employee.class as type to kafka receiver deserializer, so Employee fields are correctly mapped but account fields wrong].
#Bean
public ConsumerFactory<String, Employee> consumerFactory(){
return new DefaultKafkaConsumerFactory<>(consumerConfigs(), new StringDeserializer(), new JsonDeserializer<>(Employee.class));
}
Need help on how to map or how to get the account fields properly deserialize.
Use Generics and a custom JavaType method.
Class Employee<T> {
private String name;
private String address;
private T account;
//getters
//setters
}
JavaType withCurrent = TypeFactory.defaultInstance().constructParametricType(Employee.class, CurrentAcc.class);
JavaType withSaving = TypeFactory.defaultInstance().constructParametricType(Employee.class, SavingAcc.class);
public static JavaType determineType(String topic, byte[] data, Headers headers) {
// If it's a current account
return withCurrent;
// else
return withSaving;
}
If you construct the deserializer yourself use
deser.setTypeResolver(MyClass::determineType);
When configuring with properties.
spring.json.value.type.method=com.mycompany.MyCass.determineType
You have to inspect the data or headers (or topic) to determine which type you want.
EDIT
Here is a complete example. In this case, I pass a type hint in the Account object, but an alternative would be to set a header on the producer side.
#SpringBootApplication
public class JacksonApplication {
public static void main(String[] args) {
SpringApplication.run(JacksonApplication.class, args);
}
#Data
public static class Employee<T extends Account> {
private String name;
private T account;
}
#Data
public static abstract class Account {
private final String type;
protected Account(String type) {
this.type = type;
}
}
#Data
public static class CurrentAccount extends Account {
private BigDecimal balance;
private BigDecimal limit;
public CurrentAccount() {
super("C");
}
}
#Data
public static class SavingAccount extends Account {
private BigDecimal balance;
public SavingAccount() {
super("S");
}
}
#KafkaListener(id = "empListener", topics = "employees")
public void listen(Employee<Account> e) {
System.out.println(e);
}
#Bean
public NewTopic topic() {
return TopicBuilder.name("employees").partitions(1).replicas(1).build();
}
#Bean
public ApplicationRunner runner(KafkaTemplate<String, Employee> template) {
return args -> {
Employee<CurrentAccount> emp1 = new Employee<>();
emp1.setName("someOneWithACurrentAccount");
CurrentAccount currentAccount = new CurrentAccount();
currentAccount.setBalance(BigDecimal.ONE);
currentAccount.setLimit(BigDecimal.TEN);
emp1.setAccount(currentAccount);
template.send("employees", emp1);
Employee<SavingAccount> emp2 = new Employee<>();
emp2.setName("someOneWithASavingAccount");
SavingAccount savingAccount = new SavingAccount();
savingAccount.setBalance(BigDecimal.ONE);
emp2.setAccount(savingAccount);
template.send("employees", emp2);
};
}
private static final JavaType withCurrent = TypeFactory.defaultInstance()
.constructParametricType(Employee.class, CurrentAccount.class);
private static final JavaType withSaving = TypeFactory.defaultInstance()
.constructParametricType(Employee.class, SavingAccount.class);
public static JavaType determineType(String topic, byte[] data, Headers headers) throws IOException {
if (JsonPath.read(new ByteArrayInputStream(data), "$.account.type").equals("C")) {
return withCurrent;
}
else {
return withSaving;
}
}
}
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.properties.spring.json.value.type.method=com.example.demo.JacksonApplication.determineType
Result
JacksonApplication.Employee(name=someOneWithACurrentAccount, account=JacksonApplication.CurrentAccount(balance=1, limit=10))
JacksonApplication.Employee(name=someOneWithASavingAccount, account=JacksonApplication.SavingAccount(balance=1))
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jackson</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
EDIT2
And here is an example that conveys the type hint in a header instead...
#SpringBootApplication
public class JacksonApplication {
public static void main(String[] args) {
SpringApplication.run(JacksonApplication.class, args);
}
#Data
public static class Employee<T extends Account> {
private String name;
private T account;
}
#Data
public static abstract class Account {
}
#Data
public static class CurrentAccount extends Account {
private BigDecimal balance;
private BigDecimal limit;
}
#Data
public static class SavingAccount extends Account {
private BigDecimal balance;
}
#KafkaListener(id = "empListener", topics = "employees")
public void listen(Employee<Account> e) {
System.out.println(e);
}
#Bean
public NewTopic topic() {
return TopicBuilder.name("employees").partitions(1).replicas(1).build();
}
#Bean
public ApplicationRunner runner(KafkaTemplate<String, Employee> template) {
return args -> {
Employee<CurrentAccount> emp1 = new Employee<>();
emp1.setName("someOneWithACurrentAccount");
CurrentAccount currentAccount = new CurrentAccount();
currentAccount.setBalance(BigDecimal.ONE);
currentAccount.setLimit(BigDecimal.TEN);
emp1.setAccount(currentAccount);
template.send("employees", emp1);
Employee<SavingAccount> emp2 = new Employee<>();
emp2.setName("someOneWithASavingAccount");
SavingAccount savingAccount = new SavingAccount();
savingAccount.setBalance(BigDecimal.ONE);
emp2.setAccount(savingAccount);
template.send("employees", emp2);
};
}
private static final JavaType withCurrent = TypeFactory.defaultInstance()
.constructParametricType(Employee.class, CurrentAccount.class);
private static final JavaType withSaving = TypeFactory.defaultInstance()
.constructParametricType(Employee.class, SavingAccount.class);
public static JavaType determineType(String topic, byte[] data, Headers headers) throws IOException {
if (headers.lastHeader("accountType").value()[0] == 'C') {
return withCurrent;
}
else {
return withSaving;
}
}
public static class MySerializer extends JsonSerializer<Employee<?>> {
#Override
public byte[] serialize(String topic, Headers headers, Employee<?> emp) {
headers.add(new RecordHeader("accountType",
new byte[] { (byte) (emp.getAccount() instanceof CurrentAccount ? 'C' : 'S')}));
return super.serialize(topic, headers, emp);
}
}
}
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.producer.value-serializer=com.example.demo2.JacksonApplication.MySerializer
spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.properties.spring.json.value.type.method=com.example.demo2.JacksonApplication.determineType
This annotation solved my problem
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,include = JsonTypeInfo.As.PROPERTY,property = "#class")
private T account
it binds defined class for generic to the field

Entitymanager query always return an empty list using JPA on a JEE webapp

Im dealing with a problem since a long time on my JEE Project with Maven;
My entityManager.createQuery().getResultList() always return an empty list.
The database connection is ok, Ive got data in my tables and it works perfectly well using only JDBC. I think I tried almost everything that I saw on the internet, Im just propably missing a point...
I also tried with and without EJB and moving the librairies on the WEB-INF directory if Tomcat didnt recognize them.
I tried with JPQL request as below but also with the NamedQuery annotation and still the same result.
This is my code (DAO) :
public List<Conge> getLeaves(String username) {
EntityManagerFactory entityManagerFactory = null;
EntityManager entityManager = null;
List<Conge> listLeaves = new ArrayList<Conge>();
try {
entityManagerFactory = Persistence.createEntityManagerFactory("ProjetJEE");
entityManager = entityManagerFactory.createEntityManager();
List<Employe> a = entityManager.createQuery("select c.login from Employe c").getResultList();
System.out.println("a" + a); //always empty
} finally {
if ( entityManager != null ) entityManager.close();
if ( entityManagerFactory != null ) entityManagerFactory.close();
}
return listLeaves;
}
My Employe.java (Entity) :
package org.gdc.models;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
/**
* The persistent class for the Employe database table.
*
*/
#Entity
#NamedQuery(name="Employe.findAll", query="SELECT e FROM Employe e")
public class Employe implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String login;
private String adresse;
#Column(name="code_postal")
private String codePostal;
private String mail;
private String nom;
private String pnom;
#Column(name="solde_congés")
private int soldeCongés;
private String ville;
//bi-directional one-to-one association to Authentification
#OneToOne(mappedBy="employe")
private Authentification authentification;
//bi-directional many-to-one association to Conge
#OneToMany(mappedBy="employe")
private List<Conge> conges;
//bi-directional many-to-one association to Ref_Equipe
#ManyToOne
#JoinColumn(name="equipe")
private Ref_Equipe refEquipe;
//bi-directional many-to-one association to Ref_Fonction
#ManyToOne
#JoinColumn(name="fonction")
private Ref_Fonction refFonction;
//bi-directional many-to-one association to Rendez_vous
#OneToMany(mappedBy="employe")
private List<Rendez_vous> rendezVouses;
public Employe() {
}
public String getLogin() {
return this.login;
}
public void setLogin(String login) {
this.login = login;
}
public String getAdresse() {
return this.adresse;
}
public void setAdresse(String adresse) {
this.adresse = adresse;
}
public String getCodePostal() {
return this.codePostal;
}
public void setCodePostal(String codePostal) {
this.codePostal = codePostal;
}
public String getMail() {
return this.mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getNom() {
return this.nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPnom() {
return this.pnom;
}
public void setPnom(String pnom) {
this.pnom = pnom;
}
public int getSoldeCongés() {
return this.soldeCongés;
}
public void setSoldeCongés(int soldeCongés) {
this.soldeCongés = soldeCongés;
}
public String getVille() {
return this.ville;
}
public void setVille(String ville) {
this.ville = ville;
}
public Authentification getAuthentification() {
return this.authentification;
}
public void setAuthentification(Authentification authentification) {
this.authentification = authentification;
}
public List<Conge> getConges() {
return this.conges;
}
public void setConges(List<Conge> conges) {
this.conges = conges;
}
public Conge addConge(Conge conge) {
getConges().add(conge);
conge.setEmploye(this);
return conge;
}
public Conge removeConge(Conge conge) {
getConges().remove(conge);
conge.setEmploye(null);
return conge;
}
public Ref_Equipe getRefEquipe() {
return this.refEquipe;
}
public void setRefEquipe(Ref_Equipe refEquipe) {
this.refEquipe = refEquipe;
}
public Ref_Fonction getRefFonction() {
return this.refFonction;
}
public void setRefFonction(Ref_Fonction refFonction) {
this.refFonction = refFonction;
}
public List<Rendez_vous> getRendezVouses() {
return this.rendezVouses;
}
public void setRendezVouses(List<Rendez_vous> rendezVouses) {
this.rendezVouses = rendezVouses;
}
public Rendez_vous addRendezVous(Rendez_vous rendezVous) {
getRendezVouses().add(rendezVous);
rendezVous.setEmploye(this);
return rendezVous;
}
public Rendez_vous removeRendezVous(Rendez_vous rendezVous) {
getRendezVouses().remove(rendezVous);
rendezVous.setEmploye(null);
return rendezVous;
}
}
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ProjetJEE</groupId>
<artifactId>ProjetJEE</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Leave Management System</name>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>ejb-api</artifactId>
<version>3.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>12</release>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
And my persistence.xml :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="ProjetJEE"
transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>org.gdc.models.Authentification</class>
<class>org.gdc.models.Conge</class>
<class>org.gdc.models.CongePK</class>
<class>org.gdc.models.Employe</class>
<class>org.gdc.models.Ref_Equipe</class>
<class>org.gdc.models.Ref_Etat_Conge</class>
<class>org.gdc.models.Ref_Fonction</class>
<class>org.gdc.models.Ref_Motif_Conge</class>
<class>org.gdc.models.Ref_Type_Conge</class>
<class>org.gdc.models.Rendez_vous</class>
<class>org.gdc.models.Rendez_vousPK</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/ProjetJEE" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="mysql" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
<!-- <property name="eclipselink.logging.level" value="FINE" />
<property name="eclipselink.ddl-generation" value="create-tables" /> -->
</properties>
</persistence-unit>
</persistence>
On Eclipse with JEE, Maven, Mysql, Tomcat9, JPA
If you need something else to help me, let me know...
Thanks in advance
The only observation I have is that you are creating EntityManager from the factory and you are not injecting it. This way I think you will find problems during the application lifecycly. You have to handle by yourself the transactions (commit, rollback, etc). I see you are closing the connections in the final block, but I don't know if you have a transaction or you need to open a new one.
Please see: PersistenceUnit vs PersistenceContext
and https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/entity-context.html
I don't know why is the reason you are doing that way, but in your case I would do something like this:
public abstract class GenericDAO {
protected EntityManager entityManager;
#PersistenceContext(unitName="canvasEM")
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
}
#Repository
public class EmployeDAOImpl extends GenericDAO implements EmployesDAO{
public List<Employe> getEmployes() {
List<Employe> list = entityManager.createQuery("select c from Employe c").getResultList();
return list;
}
}
This is Spring, but I guess there is a way how to Inject the EntityManager directly in the EJB.

Repository save() is not working

I am currently playing around with spring-data-neo4j and have a really weird behaviour around persisting data.
I read the Getting Started guide and looked through the Good Relationships: The Spring Data Neo4j Guide Book. Loading existing nodes works, after getting rid of smaller issues and imperfections (like using spring-ogm 1.1.4 to get rid of the neo4j-server dependency).
Let's have a look on my code...
This is entity:
package sdn.test.model;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;
#NodeEntity
public class TestUser {
#GraphId
private Long id;
private String username;
private String password;
public TestUser() {
}
public TestUser(Long id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TestUser testUser = (TestUser) o;
if (getId() != null ? !getId().equals(testUser.getId()) : testUser.getId() != null) return false;
if (getUsername() != null ? !getUsername().equals(testUser.getUsername()) : testUser.getUsername() != null)
return false;
return getPassword() != null ? getPassword().equals(testUser.getPassword()) : testUser.getPassword() == null;
}
#Override
public int hashCode() {
int result = getId() != null ? getId().hashCode() : 0;
result = 31 * result + (getUsername() != null ? getUsername().hashCode() : 0);
result = 31 * result + (getPassword() != null ? getPassword().hashCode() : 0);
return result;
}
#Override
public String toString() {
return "TestUser{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
"}";
}
}
And this is my repository:
package sdn.test.repository;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import sdn.test.model.TestUser;
#Repository
public interface UserRepository extends GraphRepository<TestUser> {
#Query("MATCH (user:TestUser{username: {username}, password: {password}}) RETURN user")
TestUser findByUsernameAndPassword(#Param("username") String username, #Param("password") String password);
}
Here is the neo4j configuration:
package sdn.test.config;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.server.Neo4jServer;
import org.springframework.data.neo4j.server.RemoteServer;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableNeo4jRepositories("sdn.test.repository")
#EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration {
#Bean
#Override
public Neo4jServer neo4jServer() {
return new RemoteServer("http://localhost:7474", "neo4j", "test");
}
#Bean
#Override
public SessionFactory getSessionFactory() {
return new SessionFactory("sdn.test.model");
}
}
Everything together lives in a simple Spring Boot application and I try to do the entity creation in this test class:
package sdn.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sdn.test.config.Neo4jConfig;
import sdn.test.model.TestUser;
import sdn.test.repository.UserRepository;
import java.util.Date;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = {
Neo4jConfig.class})
public class SimpleNeo4jTests {
#Autowired
private UserRepository userRepository;
#Test
public void createNewUser() {
long timeOffset = (new Date()).getTime();
String username = "test" + timeOffset;
String password = "password#" + timeOffset;
TestUser newUser = new TestUser(timeOffset, username, password);
userRepository.save(newUser);
// Try to load the user
TestUser actualUser = userRepository.findByUsernameAndPassword(username, password);
assertThat(actualUser, equalTo(newUser));
}
}
Last but not least, here is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.h0lg.test</groupId>
<artifactId>simple-sdn4-test</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
There is no error thrown when I call userRepository.save() and checking the "remote" server confirms the red test result.
Explicitly giving the label name with #GraphEntity(label = "TestUser") doesn't help. Using transactions explicitly didn't help either.
Any ideas and hints are highly appreciated.
Looks like you're setting the #GraphId of your TestUser node entity via the test:
TestUser newUser = new TestUser(timeOffset, username, password);
public TestUser(Long id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
Application code should never assign a value to the #GraphId. Could you remove that and see if it helps?

how to run this JAXRS-program? what should i do?

I have already spent a month to run this program but did not find any solution.
This is a copied program. I just want to run it at any how.
I wanna run it as rest service. is there any mistake in it ?
Please help .
This is all i have in my project.
Thank you in advance !!
Here is my program :
Coustomer.java
package com.abhi.shek.idea.book;
public class Customer {
private int id;
private String firstName;
private String lastName;
private String street;
private String city;
private String state;
private String zip;
private String country;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
Here is my another class :
CustomerResource.java
package com.abhi.shek.idea.book;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ws.rs.Consumes;
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.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
#Path("/customers")
public class CustomerResource{
private Map<Integer, Customer> customerDB = new ConcurrentHashMap<Integer, Customer>();
private AtomicInteger idCounter = new AtomicInteger();
#POST
#Path("/create")
#Consumes("application/xml")
public Response createCustomer(InputStream is) {
Customer customer = readCustomer(is);
customer.setId(idCounter.incrementAndGet());
customerDB.put(customer.getId(), customer);
System.out.println("Created customer " + customer.getId());
return Response.created(
URI.create("/customers/" + customer.getId())).build();
}
#GET
#Path("{name}")
#Produces("MediaType.APPLICATION_JSON")
public StreamingOutput getCustomer(#PathParam("name")String name) {
final Customer customer = customerDB.get(name);
if (customer == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return new StreamingOutput() {
public void write(OutputStream outputStream)
throws IOException, WebApplicationException {
outputCustomer(outputStream, customer);
}
};
}
#PUT
#Path("{id}")
#Consumes("application/xml")
public void updateCustomer(#PathParam("id") int id, InputStream is) {
Customer update = readCustomer(is);
Customer current = customerDB.get(id);
if (current == null)
throw new WebApplicationException(Response.Status.NOT_FOUND);
current.setFirstName(update.getFirstName());
current.setLastName(update.getLastName());
current.setStreet(update.getStreet());
current.setState(update.getState());
}
protected void outputCustomer(OutputStream os, Customer cust)
throws IOException {
PrintStream writer = new PrintStream(os);
writer.println("<customer id=\"" + cust.getId() + "\">");
writer.println("<first-name>" + cust.getFirstName()
+ "</first-name>");
writer.println("<last-name>" + cust.getLastName()
+ "</last-name>");
writer.println("<street>" + cust.getStreet() + "</street>");
writer.println("<city>" + cust.getCity() + "</city>");
writer.println("<state>" + cust.getState() + "</state>");
writer.println("<zip>" + cust.getZip() + "</zip>");
writer.println("<country>" + cust.getCountry() + "</country>");
writer.println("</customer>");
}
protected Customer readCustomer(InputStream is) {
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
Document doc = builder.parse(is);
Element root = doc.getDocumentElement();
Customer cust = new Customer();
if (root.getAttribute("id") != null
&& !root.getAttribute("id").trim().equals("")) {
cust.setId(Integer.valueOf(root.getAttribute("id")));
}
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
if (element.getTagName().equals("first-name")) {
cust.setFirstName(element.getTextContent());
}
else if (element.getTagName().equals("last-name")) {
cust.setLastName(element.getTextContent());
}
else if (element.getTagName().equals("street")) {
cust.setStreet(element.getTextContent());
}
else if (element.getTagName().equals("city")) {
cust.setCity(element.getTextContent());
}
else if (element.getTagName().equals("state")) {
cust.setState(element.getTextContent());
}
else if (element.getTagName().equals("zip")) {
cust.setZip(element.getTextContent());
}
else if (element.getTagName().equals("country")) {
cust.setCountry(element.getTextContent());
}
}
return cust;
} catch (Exception e) {
throw new WebApplicationException(e,
Response.Status.BAD_REQUEST);
}
}
}
Here is my third program :
ShoppingApplication.java
package com.abhi.shek.idea.book;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;
#ApplicationPath("/services")
public class ShoppingApplication extends Application {
private Set<Object> singletons = new HashSet<Object>();
private Set<Class<?>> empty = new HashSet<Class<?>>();
public ShoppingApplication() {
singletons.add(new CustomerResource());
}
#Override
public Set<Class<?>> getClasses() {
return empty;
}
#Override
public Set<Object> getSingletons() {
return singletons;
}
}
Here is my pom.xml file :
<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.abhi.shek.idea.book</groupId>
<artifactId>JAXRS-Book</artifactId>
<version>0.0.1-SNAPSHOT</version>
<repositories>
<repository>
<id>maven2-repository.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
<layout>default</layout>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.9</version>
</dependency>
</dependencies>
And the last web.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com /xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>JAXRS-Book</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>com.abhi.shek.idea.book.ShoppingApplication</servlet-name>
<servlet-class>
org.glassfish.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.abhi.shek.idea.book.CustomerResource</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>com.abhi.shek.idea.book.ShoppingApplication</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Errors : On the console :
SEVERE: Servlet [RestClient] in web application [/JAXRS-RestClient] threw load() exception
java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
another error is :
com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.
at com.sun.jersey.server.impl.application.RootResourceUriRules.<init> (RootResourceUriRules.java:99)

Resources