0
votes

I am new to JAXRS services. So for start i am writing a JAXRS application. In this application i'm writing custom java type through ParamConverterProvider and ParamConverter. I faced the following error when I click http://localhost:8080/advanced-jaxrs-01/webapi/date/12234003

Root Cause

org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization. [[FATAL] No injection source found for a parameter of type public java.lang.String com.practise.mohit.MyCustomdate.getRequestedDate(com.practise.mohit.MyDate) at index 0.; source='ResourceMethod{httpMethod=GET, consumedTypes=[], producedTypes=[text/plain], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=MethodHandler{handlerClass=class com.practise.mohit.MyCustomdate, handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@18e98015]}, handlingMethod=public java.lang.String com.practise.mohit.MyCustomdate.getRequestedDate(com.practise.mohit.MyDate), parameters=[Parameter [type=class com.practise.mohit.MyDate, source=dateString, defaultValue=null]], responseType=class java.lang.String}, nameBindings=[]}'] org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:410) org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:157) org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:280) org.glassfish.jersey.internal.Errors$2.call(Errors.java:289) org.glassfish.jersey.internal.Errors$2.call(Errors.java:286) org.glassfish.jersey.internal.Errors.process(Errors.java:315) org.glassfish.jersey.internal.Errors.process(Errors.java:297) org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286) org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:277) org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:262) org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167) org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:349) javax.servlet.GenericServlet.init(GenericServlet.java:158) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Unknown Source)

My pom.xml

  <dependencies>
  <dependency>
   <groupId>org.glassfish.jersey.bundles</groupId>
    <artifactId>jaxrs-ri</artifactId>
    <version>2.0</version>
    <!--   <scope>provided</scope> -->
</dependency>

  <dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>2.16</version>
    <scope>provided</scope>
</dependency>

<dependency>
   <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.16</version>
</dependency>

   </dependencies>

My ParamConverterProvider

@Provider
public class MyParamConverterProvider implements ParamConverterProvider{
    @Override
    public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
        if(rawType.equals(DateResource.class)){
           // return (ParamConverter<T>) new MyDate();
            return (ParamConverter<T>) new DateResource();
            //return (ParamConverter<T>) new ParamConverter<DateResource>();
        }
        return null;
    }

    }

My ParamConverter

public class DateResource implements ParamConverter<MyDate> {
@Override
    public MyDate fromString(String value) {
        // TODO Auto-generated method stub
         if (value == null || value.trim().isEmpty()) {
                return null;
            }

         MyDate dateParamModel = new MyDate();
        dateParamModel.setDateAsString(value);
        return  dateParamModel;

    }

    @Override
    public String toString(MyDate mo) {


            return ((MyDate) mo).getDateAsString();
    }

}

My Custom Java type class

public class MyDate {


    private String dateAsString;

    public String getDateAsString() {
        return dateAsString;
    }

    public void setDateAsString(String dateAsString) {
        this.dateAsString = dateAsString;
    }

    public LocalDateTime getDate() {
        LocalDateTime dateTime = null;
        try {
            dateTime = LocalDateTime.parse(dateAsString, DateTimeFormatter.ISO_DATE_TIME);
        } catch (DateTimeParseException ex) {
            System.err.println("Conversion of dateAsString: " + dateAsString + " using ISO date time failed.");
        }
        try {
            dateTime = LocalDateTime.parse(dateAsString, DateTimeFormatter.ISO_DATE);
        } catch (DateTimeParseException ex) {
            System.err.println("Conversion of dateAsString: " + dateAsString + " using ISO date failed.");
        }

        return dateTime;
    }
}

And finally my Resource

@Path("date/{dateString}")
public class MyCustomdate {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    //public String getRequestedDate(@PathParam("dateString") String dateString)
    public String getRequestedDate(@PathParam("dateString") MyDate myDate)
    {
        return "Got"+ myDate.getDate() ;
    }

}

And My main class

@ApplicationPath("webapi")
public class MyRestApiApp extends Application {

}

Please guide on this issue.

1
have you tried registering MyParamConverterProvider in the constructor of MyRestApiApp like register(MyParamConverterProvider.class)?Jan Gassen
@JanGassen yes i did now...but after this i'm having error A MultiException has 1 exceptions. They are: 1. java.lang.NoSuchMethodException: Could not find a suitable constructor in com.practise.mohit.MyRestApiApp class .... this means it is trying to instantiate my converter DateResource, which is not allowed..can you guide me on this nowMohit Darmwal
Does your class MyRestApiApp have a default-constructor with no arguments? And the the register call inside of it?Jan Gassen
@JanGassen yes, i declared it like....... MyRestApiApp() { ResourceConfig rc = new ResourceConfig(); rc.register(MyParamConverterProvider.class); }Mohit Darmwal
can you derive MyRestApiApp from ResourceConfig (which is a subclass of Application) and then just call register in the constructor? And can you maybe clarify which constructor couldn't be found? MyRestApiApp or DateResource ?Jan Gassen

1 Answers

0
votes
if(rawType.equals(DateResource.class)){

This is wrong. You need to be checking for the parameter type. What Jersey will do when validating the resources parameters is check all the ParamConverterProviders to see if they all return something other then null for that parameter type. Since you are checking the converter type instead of the parameter type, it returns null during the check for the MyDate parameter. That's when the ModelValidationExeption occurs.

Just change it to check for the parameter type you want to convert.

if(rawType.equals(MyDate.class)){

Also remove jaxrs-ri from your dependencies. You don't need it.