简体   繁体   中英

Guice configuration error: Could not find a suitable constructor

I am using GUICE for dependency injection for a RESTful API build using Dropwizard. This is the error I am getting:

com.google.inject.ConfigurationException: Guice configuration errors:

1) Could not find a suitable constructor in com.api.analytics.visitor.web.VisitorParams. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private. at com.api.analytics.visitor.web.VisitorParams.class(VisitorParams.java:27) while locating com.api.analytics.visitor.web.VisitorParams for parameter 0 at com.api.analytics.visitor.web.v1.VisitorResource.(VisitorResource.java:68) while locating com.api.analytics.visitor.web.v1.VisitorResource

Here is how my resource is setup:

package com.api.analytics.visitor.web.v1;

//imports

@Path("/visitor")
@Produces({MediaType.APPLICATION_JSON, ExtraMediaTypes.PROTOBUF})
@Consumes(MediaType.APPLICATION_JSON)
public class VisitorResource {
  private final ContactsManager contactsManager;
  private final ActivityFetcher.Provider activityFetcherProvider;
  private final VisitSourceMapper visitSourceMapper;
  private final TimeZoneClient timeZoneClient;
  private final GatesClient gatesClient;
  private final Value<Integer> smallScanLimit;
  private final Provider<Integer> portalIdProvider;
  private final VisitorParams visitorParams;

  @Inject
  public VisitorResource(@Bind({Bind.Params.QUERY}) VisitorParams visitorParams,
                         ContactsManager contactsManager,
                         ActivityFetcher.Provider activityFetcherProvider,
                         VisitSourceMapper visitSourceMapper,
                         TimeZoneClient timeZoneClient,
                         GatesClient gatesClient,
                         @Named("analytics.activities.fetch.small.scan.limit") Value<Integer> smallScanLimit,
                         @StashedHubId Provider<Integer> portalIdProvider) {
    this.contactsManager = contactsManager;
    this.activityFetcherProvider = activityFetcherProvider;
    this.visitSourceMapper = visitSourceMapper;
    this.timeZoneClient = timeZoneClient;
    this.gatesClient = gatesClient;
    this.smallScanLimit = smallScanLimit;
    this.portalIdProvider = portalIdProvider;
    this.visitorParams = visitorParams;
  }

  @Timed
  @GET
  @Path("/{identity}/activities")
  public List<Activity> getActivitiesGet(@PathParam("identity") String identity) throws Exception {
    return getActivities(identity);
  }

  //other methods
}

Here is my VisitorParams class:

package com.api.analytics.visitor.web;

//imports

public class VisitorParams {
  private final Optional<Long> start;
  private final Optional<Long> end;
  private final Set<ActivityType> activityTypes;
  private final Optional<Integer> limit;
  private final boolean reversed;
  private final Set<Long> vids;

  @JsonCreator
  public VisitorParams (@JsonProperty("start") Optional<Long> start,
                        @JsonProperty("end") Optional<Long> end,
                        @JsonProperty("type") Optional<Set<ActivityType>> activityTypes,
                        @JsonProperty("limit") Optional<Integer> limit,
                        @JsonProperty("reversed") @DefaultValue("false") boolean reversed,
                        @JsonProperty("vid") Optional<Set<Long>> vids) {
    this.start = start;
    this.end = end;
    this.activityTypes = activityTypes.or(Collections.emptySet());
    this.limit = limit;
    this.reversed = reversed;
    this.vids = vids.or(Collections.emptySet());
  }

  public Optional<Long> getStart() {
    return this.start;
  }

  //other getters
}

One thing I did try was adding a constructor in my VisitorParams class like this:

public VisitorParams () {}

When I did that, I get errors about how some variables might not have been initialized.

So what am I doing wrong here to cause this configuration error? I'm pretty new to using Guice and Dropwizard, so let me know if you need any other information. Thanks!

Read the message: VisitorParams doesn't have a zero-arg constructor, or a constructor annotated with @Inject .

Add @Inject to the constructor:

@Inject
@JsonCreator
public VisitorParams ( ...

I ended up removing the VisitorParams visitorParams from the VisitorResource constructor and moving it to the individual methods like so:

//imports

@Path("/visitor")
@Produces({MediaType.APPLICATION_JSON, ExtraMediaTypes.PROTOBUF})
@Consumes(MediaType.APPLICATION_JSON)
public class VisitorResource {
  //other variables
  private final VisitorParams visitorParams;

  @Inject
  public VisitorResource(/*other variables*/) {
    this.contactsManager = contactsManager;
    this.activityFetcherProvider = activityFetcherProvider;
    this.visitSourceMapper = visitSourceMapper;
    this.timeZoneClient = timeZoneClient;
    this.gatesClient = gatesClient;
    this.smallScanLimit = smallScanLimit;
    this.portalIdProvider = portalIdProvider;
    //removed visitorParams here
  }

  @Timed
  @GET
  @Path("/{identity}/activities")
  //moved it to the methods
  public List<Activity> getActivitiesGet(@PathParam("identity") String identity, @Bind({Bind.Params.QUERY}) VisitorParams visitorParams) throws Exception {
    this.visitorParams = visitorParams;
    return getActivities(identity);
  }

  //other methods
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM