The error[1] occurs when we use complex types in our GET querys. JAXRS understands simple data types. If we use complex types, we might need to have our own (de)serialisation for the complex types.
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import javax.money.Monetary;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
import org.javamoney.moneta.Money;
@Provider
public class MoneyConverterProvider implements ParamConverterProvider {
private final MoneyConverter converter = new MoneyConverter();
@Override
public ParamConverter getConverter(Class rawType, Type genericType, Annotation[] annotations) {
if (!rawType.equals(Money.class)) return null;
return (ParamConverter) converter;
}
public class MoneyConverter implements ParamConverter {
public Money fromString(String value) {
if (value == null ||value.isEmpty()) return null;
return Money.of(new BigDecimal(value), Monetary.getCurrency("AUD"));
}
public String toString(Money value) {
if (value == null) return "";
return value.toString();
}
}
}
[1]
0:42:46,435 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 86) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./apidb: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./apidb: java.lang.RuntimeException: RESTEASY003875: Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.QueryParam("money") on public javax.ws.rs.core.Response com.rest.autogen.SalesTransactionEndpoint.getItems(java.lang.Integer,java.lang.Integer,java.lang.String,java.lang.Long,java.lang.String, org.javamoney.moneta.Money) for basetype: org.javamoney.moneta.Money
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:85)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: java.lang.RuntimeException: RESTEASY003875: Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.QueryParam("money") on public javax.ws.rs.core.Response com.rest.autogen.SalesTransactionEndpoint.getItems(java.lang.Integer,java.lang.Integer,java.lang.String,java.lang.Long,java.lang.String,org.javamoney.moneta.Money) for basetype: org.javamoney.moneta.Money
at org.jboss.resteasy.core.StringParameterInjector.initialize(StringParameterInjector.java:220)
at org.jboss.resteasy.core.StringParameterInjector.(StringParameterInjector.java:64)
at org.jboss.resteasy.core.QueryParamInjector.(QueryParamInjector.java:30)
at org.jboss.resteasy.core.InjectorFactoryImpl.createParameterExtractor(InjectorFactoryImpl.java:86)
at org.jboss.resteasy.cdi.CdiInjectorFactory.createParameterExtractor(CdiInjectorFactory.java:52)
at org.jboss.resteasy.core.MethodInjectorImpl.(MethodInjectorImpl.java:44)
at org.jboss.resteasy.core.InjectorFactoryImpl.createMethodInjector(InjectorFactoryImpl.java:77)
at org.jboss.resteasy.cdi.CdiInjectorFactory.createMethodInjector(CdiInjectorFactory.java:58)
at org.jboss.resteasy.core.ResourceMethodInvoker.(ResourceMethodInvoker.java:99)
at org.jboss.resteasy.core.ResourceMethodRegistry.processMethod(ResourceMethodRegistry.java:281)
at org.jboss.resteasy.core.ResourceMethodRegistry.register(ResourceMethodRegistry.java:252)
at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:222)
at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:194)
at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:180)
at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:157)
at org.jboss.resteasy.core.ResourceMethodRegistry.addPerRequestResource(ResourceMethodRegistry.java:76)
at org.jboss.resteasy.spi.ResteasyDeployment.registration(ResteasyDeployment.java:434)
at org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:245)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.init(ServletContainerDispatcher.java:113)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.init(HttpServletDispatcher.java:36)
at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:117)
at org.wildfly.extension.undertow.security.RunAsLifecycleInterceptor.init(RunAsLifecycleInterceptor.java:78)
at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:103)
at io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start(ManagedServlet.java:231)
at
io.undertow.servlet.core.ManagedServlet.createServlet(ManagedServlet.java:132)
at io.undertow.servlet.core.DeploymentManagerImpl.start(DeploymentManagerImpl.java:526)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:101)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)