3

I get the error java.lang.NoSuchMethodError: java.time.Instant.<init>() when in a rest-API documentation (swagger) I try to do a post request with as body the following json:

{
  "accountId": "string",
  "name": "string",
  "value": "string",
  "expires": 0
}

this maps to the model:

AccountClientIdentifierEntity{
accountId   string
name    string
value   string
expires integer($int64)
}

Now in my Java code this expires attribute is actually an Instant, but it somehow gets parsed as an Integer here, so I guess my problem lies here, when I post with the "0" instead of an Instant. Can someone help me to fix this, or at least catch the error correctly?

Full code: Entity:

/**
 * The Class UserEntity.
 */
@XmlRootElement(name = "accountClientIdentifier")
@XmlType(propOrder = { "accountId", "name", "value", "expires"})
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AccountClientIdentifierEntity {

    public static void registerToContextProvider(){
        try {
            CustomContextProvider.registerClass(com.inteno.iopsys.plugin.restapi.entity.AccountClientIdentifierEntity.class);
        } catch (Exception e){
            Log.error("Could not register AccountClientIdentifierEntity: "+e.getMessage());
        }
    }

    /** The username. */
    private String accountId;

    /** The name. */
    private String name;

    /** The value. */
    private String value;

    /** expires. */
    private Instant expires;


    /**
     * Instantiates a new user entity.
     */
    public AccountClientIdentifierEntity() {

    }

    /**
     * Instantiates a new user entity.
     *
     * @param accountId
     *            the account ID
     * @param name
     *            the name
     * @param value
     *            the value
     */
    public AccountClientIdentifierEntity(String accountId, String name, String value) {
        this.accountId = accountId;
        this.name = name;
        this.value = value;
    }
  • getters & setters

service path:

@POST
    @Path("/identifiers")
    @ApiOperation(value = "Add a new account client identifier")
    @ApiResponses(value = {@ApiResponse(code = 201, message = "Created")})
    public Response createAccountClientId(
            @ApiParam(value = "The new identifier to create", required = true) AccountClientIdentifierEntity accountClientIdentifierEntity
    ) throws ServiceException {
        controller.createOrUpdateAccountClientIdentifier(accountClientIdentifierEntity);
        return Response.status(Response.Status.CREATED).build();
    }

Stacktrace:

2023.01.05 09:25:21 WARN  [Jetty-QTP-API-1-821]: HttpChannel.java:700 - /restapi/v1/account/identifiers
java.lang.NoSuchMethodError: java.time.Instant.<init>()
        at com.sun.xml.bind.v2.ClassFactory.tryGetDeclaredConstructor(ClassFactory.java:115) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.ClassFactory.create0(ClassFactory.java:76) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.createInstance(ClassBeanInfoImpl.java:255) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:672) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:158) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:547) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:526) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:45) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:216) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:150) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:385) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:364) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        at com.sun.jersey.json.impl.BaseJSONUnmarshaller.unmarshalJAXBElementFromJSON(BaseJSONUnmarshaller.java:111) ~[?:?]
        at com.sun.jersey.json.impl.BaseJSONUnmarshaller.unmarshalFromJSON(BaseJSONUnmarshaller.java:100) ~[?:?]
        at com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider.readFrom(JSONRootElementProvider.java:154) ~[?:?]
        at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:111) ~[?:?]
        at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:490) ~[?:?]
        at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123) ~[?:?]
        at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:86) ~[?:?]
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153) ~[?:?]
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203) ~[?:?]
        at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) ~[?:?]
        at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) ~[?:?]
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) ~[?:?]
        at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) ~[?:?]
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) ~[?:?]
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) ~[?:?]
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542) ~[?:?]        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473) ~[?:?]        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419) ~[?:?]
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409) ~[?:?]
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409) ~[?:?]
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558) ~[?:?]
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733) ~[?:?]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[jetty-servlet-api-4.0.6.jar:?]
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764) ~[jetty-servlet-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:508) ~[jetty-servlet-10.0.5.jar:10.0.5]        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1373) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:463) ~[jetty-servlet-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1295) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:51) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.Server.handle(Server.java:562) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:399) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:656) ~[jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:391) [jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282) [jetty-server-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:319) [jetty-io-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100) [jetty-io-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:538) [jetty-io-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:387) [jetty-io-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:161) [jetty-io-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100) [jetty-io-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.io.SocketChannelEndPoint$1.run(SocketChannelEndPoint.java:101) [jetty-io-10.0.5.jar:10.0.5]        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333) [jetty-util-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310) [jetty-util-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168) [jetty-util-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126) [jetty-util-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:378) [jetty-util-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:894) [jetty-util-10.0.5.jar:10.0.5]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1038) [jetty-util-10.0.5.jar:10.0.5]
        at java.lang.Thread.run(Thread.java:834) [?:?]
Caused by: java.lang.NoSuchMethodException: java.time.Instant.<init>()
        at java.lang.Class.getConstructor0(Class.java:3350) ~[?:?]
        at java.lang.Class.getDeclaredConstructor(Class.java:2554) ~[?:?]
        at com.sun.xml.bind.v2.ClassFactory.tryGetDeclaredConstructor(ClassFactory.java:107) ~[jaxb-runtime-2.3.2.jar:2.3.2]
        ... 65 more
2
  • Please share the complete stacktrace Commented Jan 5, 2023 at 9:46
  • Added to my original question Commented Jan 5, 2023 at 9:48

1 Answer 1

5

You're asking JAXB to put the peg (a number value received from the JSON and identifier by swagger as $int64) in the hole (the Instant expires; field in your AccountClientIdentifierEntity class).

Turns out, that's a square peg and a round hole. JAXB tries its best, and given that it has no idea what an Instant might be, is planning to construct one and perhaps find a set method maybe. That's not how Instant works, however; you're looking specifically for Instant.ofEpochSecond or ofEpochMilli, and we are now truly getting into the root issue here: What does that $int64 even mean? Is it seconds since 1970? milliseconds? Nanofurlongs? Perhaps it's days since 1902, using the decimal fraction for hours and seconds?

Asking JAXB to just take a flying wild stab at it seems unreasonable, and indeed, isn't a thing JAXB can do, nor will it ever. You must tell it what to do.

To do this, you tell JAXB that there is a specific unmarshaller available for that field.

An @XmlJavaTypeAdapter annotation should be able to do the job; you can annotate the expires field with it, passing a class reference to a class that implements XmlAdapter.

The jaxb-java-time-adapters project could be useful here; possibly only to look at the source to know what to do.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.