Search code examples
javaspring-bootmicroservices

org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization


I'm developing spring boot microservices example from the link: https://dzone.com/articles/spring-boot-creating. In this project I simply updated the parent dependency to its latest version and other code files are unchanged. I faced the following error when I click http://localhost:8080/order?idCustomer=2&idProduct=3&amount=4

2016-09-09 11:46:20.888 ERROR 14152 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : StandardWrapper.Throwable

org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization.
[[FATAL] A resource model has ambiguous (sub-)resource method for HTTP method GET and input mime-types as defined by"@Consumes" and "@Produces" annotations at Java methods public java.util.List br.com.alexandreesl.handson.rest.ProductRest.getProducts() and public java.util.List br.com.alexandreesl.handson.rest.CustomerRest.getCustomers() at matching regular expression /. These two methods produces and consumes exactly the same mime-types and therefore their invocation as a resource methods will always fail.; source='org.glassfish.jersey.server.model.RuntimeResource@14c14bf']
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:555) ~[jersey-server-2.23.1.jar:na]
    at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:184) ~[jersey-server-2.23.1.jar:na]
    at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:350) ~[jersey-server-2.23.1.jar:na]
    at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:347) ~[jersey-server-2.23.1.jar:na]
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315) ~[jersey-common-2.23.1.jar:na]
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297) ~[jersey-common-2.23.1.jar:na]
    at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255) ~[jersey-common-2.23.1.jar:na]
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:347) ~[jersey-server-2.23.1.jar:na]
    at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:392) ~[jersey-container-servlet-core-2.23.1.jar:na]
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:177) ~[jersey-container-servlet-core-2.23.1.jar:na]
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:369) ~[jersey-container-servlet-core-2.23.1.jar:na]
    at javax.servlet.GenericServlet.init(GenericServlet.java:158) ~[tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1194) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:806) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:133) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:522) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1110) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_102]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_102]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.4.jar:8.5.4]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_102]

the updated pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

Application.java

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

ApplicationConfig.java

@Configuration
public class ApplicationConfig {
    @Named
    static class JerseyConfig extends ResourceConfig {
        public JerseyConfig() {
            this.packages("br.com.alexandreesl.handson.rest");
        }
    }

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

Order.java

public class Order {
    private long id;
    private long amount;
    private Date dateOrder;
    private Customer customer;
    private Product product;
    // setters and getters
}

OrderRest.java

@Named
@Path("/")
public class OrderRest {
    private long id = 1;

    @Inject
    private RestTemplate restTemplate;

    @GET
    @Path("order")
    @Produces(MediaType.APPLICATION_JSON)
    public Order submitOrder(@QueryParam("idCustomer") long idCustomer,
            @QueryParam("idProduct") long idProduct,
            @QueryParam("amount") long amount) {

        Customer customer = restTemplate.getForObject("http://localhost:8080/customer?id={id}", Customer.class, idCustomer);
        Product product = restTemplate.getForObject("http://localhost:8080/product?id={id}", Product.class,idProduct);

        Order order = new Order();
        order.setCustomer(customer);
        order.setProduct(product);
        order.setId(id);
        order.setAmount(amount);
        order.setDateOrder(new Date());
        id++;
        return order;
    }
}

Customer.java

public class Customer {
    private long id;
    private String name;
    private String email;
    // setters and getters
}

CustomerRest.java

@Named
@Path("/")
public class CustomerRest {
    private static List<Customer> customers = new ArrayList<Customer>();

    static {
        Customer customer1 = new Customer();
        customer1.setId(1);
        customer1.setNome("Customer 1");
        customer1.setEmail("[email protected]");

        Customer customer2 = new Customer();
        customer2.setId(2);
        customer2.setNome("Customer 2");
        customer2.setEmail("[email protected]");

        Customer customer3 = new Customer();
        customer3.setId(3);
        customer3.setNome("Customer 3");
        customer3.setEmail("[email protected]");

        Customer customer4 = new Customer();
        customer4.setId(4);
        customer4.setNome("Customer 4");
        customer4.setEmail("[email protected]");

        Customer customer5 = new Customer();
        customer5.setId(5);
        customer5.setNome("Customer 5");
        customer5.setEmail("[email protected]");

        customers.add(customer1);
        customers.add(customer2);
        customers.add(customer3);
        customers.add(customer4);
        customers.add(customer5);
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Customer> getCustomers() {
        return customers;
    }

    @GET
    @Path("customer")
    @Produces(MediaType.APPLICATION_JSON)
    public Customer getCustomer(@QueryParam("id") long id) {
        Customer cli = null;
        for (Customer c : customers) {
            if (c.getId() == id)
                cli = c;
        }
        return cli;
    }
}

Product.java

public class Product {
    private long id;
    private String sku;
    private String description;
    // setters and getters
}

ProductRest.java

@Named
@Path("/")
public class ProductRest {
    private static List<Product> products = new ArrayList<Product>();

    static {
        Product product1 = new Product();
        product1.setId(1);
        product1.setSku("abcd1");
        product1.setDescription("Product1");
        Product product2 = new Product();
        product2.setId(2);
        product2.setSku("abcd2");
        product2.setDescription("Product2");
        Product product3 = new Product();
        product3.setId(3);
        product3.setSku("abcd3");
        product3.setDescription("Product3");
        Product product4 = new Product();
        product4.setId(4);
        product4.setSku("abcd4");
        product4.setDescription("Product4");
        products.add(product1);
        products.add(product2);
        products.add(product3);
        products.add(product4);
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Product> getProducts() {
        return products;
    }

    @GET
    @Path("product")
    @Produces(MediaType.APPLICATION_JSON)
    public Product getProduct(@QueryParam("id") long id) {
        Product prod = null;
        for (Product p : products) {
            if (p.getId() == id)
                prod = p;
        }
        return prod;
    }
}

Please guide on this issue.


Solution

  • I was able to solve this issue. you need to make some changes in mapping request URL. I wonder how code in the block is working without error.

    As per my understanding one possible cause is that you have two or more applicable mappings for that URL call. CustomerRest.java and ProductRest.java both were mapped to /.

    @Path("/")
    

    And

    @Path("/")
    

    The Jersey have no way of telling what method is actually supposed to be called and gives this error.

    You need to correct following files: OrderRest.java

    @Named
    @Path("/")
    public class OrderRest {
        private long id = 1;
    
        @Inject
        private RestTemplate restTemplate;
    
        @GET
        @Path("order")
        @Produces(MediaType.APPLICATION_JSON)
        public Order submitOrder(@QueryParam("idCustomer") long idCustomer,
                @QueryParam("idProduct") long idProduct,
                @QueryParam("amount") long amount) {
    
            Customer customer = restTemplate.getForObject("http://localhost:8080/customer/getCustomer?id={id}", Customer.class, idCustomer);
            Product product = restTemplate.getForObject("http://localhost:8080/product/getProduct?id={id}", Product.class,idProduct);
    
            Order order = new Order();
            order.setCustomer(customer);
            order.setProduct(product);
            order.setId(id);
            order.setAmount(amount);
            order.setOrderDate(new Date());
            id++;
            return order;
        }
    }
    

    In CustomerRest.java - use this

    @GET
        @Path("/getCustomer")
        @Produces(MediaType.APPLICATION_JSON)
        public Customer getCustomer(@QueryParam("id") long id) {
            Customer cli = null;
            for (Customer c : customers) {
                if (c.getId() == id)
                    cli = c;
            }
            return cli;
        }
    

    In ProductRest - use this

    @GET
        @Path("/getProduct")
        @Produces(MediaType.APPLICATION_JSON)
        public Product getProduct(@QueryParam("id") long id) {
            Product prod = null;
            for (Product p : products) {
                if (p.getId() == id)
                    prod = p;
            }
            return prod;
        }
    

    Here is the output: enter image description here