I have a Quarkus app that uses Apache-Camel and runs fine locally. When I build it and try to run the docker container then I get the following error:
ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): java.lang.ClassNotFoundException: org.apache.camel.http.base.HttpOperationFailedException at org.apache.camel.quarkus.core.CamelQuarkusClassResolver.resolveMandatoryClass(CamelQuarkusClassResolver.java:68) at org.apache.camel.reifier.errorhandler.ErrorHandlerReifier.createExceptionClasses(ErrorHandlerReifier.java:197) at org.apache.camel.reifier.errorhandler.ErrorHandlerReifier.addExceptionPolicy(ErrorHandlerReifier.java:177) at org.apache.camel.reifier.errorhandler.ErrorHandlerReifier.configure(ErrorHandlerReifier.java:220) at org.apache.camel.reifier.errorhandler.DefaultErrorHandlerReifier.createErrorHandler(DefaultErrorHandlerReifier.java:53) at org.apache.camel.impl.DefaultModelReifierFactory.createErrorHandler(DefaultModelReifierFactory.java:65) at org.apache.camel.reifier.errorhandler.ErrorHandlerRefReifier.createErrorHandler(ErrorHandlerRefReifier.java:36) at org.apache.camel.impl.DefaultModelReifierFactory.createErrorHandler(DefaultModelReifierFactory.java:65) at org.apache.camel.reifier.ProcessorReifier.wrapInErrorHandler(ProcessorReifier.java:751) at org.apache.camel.reifier.ProcessorReifier.wrapChannelInErrorHandler(ProcessorReifier.java:732) at org.apache.camel.reifier.ProcessorReifier.wrapChannel(ProcessorReifier.java:711) at org.apache.camel.reifier.ProcessorReifier.wrapChannel(ProcessorReifier.java:617) at org.apache.camel.reifier.ProcessorReifier.wrapProcessor(ProcessorReifier.java:613) at org.apache.camel.reifier.ProcessorReifier.makeProcessor(ProcessorReifier.java:860) at org.apache.camel.reifier.ProcessorReifier.addRoutes(ProcessorReifier.java:585) at org.apache.camel.reifier.RouteReifier.doCreateRoute(RouteReifier.java:236) at org.apache.camel.reifier.RouteReifier.createRoute(RouteReifier.java:74) at org.apache.camel.impl.DefaultModelReifierFactory.createRoute(DefaultModelReifierFactory.java:49) at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:887) at org.apache.camel.impl.DefaultModel.addRouteDefinitions(DefaultModel.java:190) at org.apache.camel.impl.DefaultCamelContext.addRouteDefinitions(DefaultCamelContext.java:344) at org.apache.camel.builder.RouteBuilder.populateRoutes(RouteBuilder.java:676) at org.apache.camel.builder.RouteBuilder.addRoutesToCamelContext(RouteBuilder.java:529) at org.apache.camel.impl.engine.AbstractCamelContext.addRoutes(AbstractCamelContext.java:1175) at io.quarkus.arc.impl.EventImpl$Notifier.notifyObservers(EventImpl.java:323) at io.quarkus.arc.impl.EventImpl$Notifier.notify(EventImpl.java:305) at io.quarkus.arc.impl.EventImpl.fire(EventImpl.java:73) at io.quarkus.arc.runtime.ArcRecorder.fireLifecycleEvent(ArcRecorder.java:130) at io.quarkus.arc.runtime.ArcRecorder.handleLifecycleEvents(ArcRecorder.java:99) at io.quarkus.deployment.steps.LifecycleEventsBuildStep$startupEvent1144526294.deploy_0(Unknown Source) at io.quarkus.deployment.steps.LifecycleEventsBuildStep$startupEvent1144526294.deploy(Unknown Source) at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source) at io.quarkus.runtime.Application.start(Application.java:101) at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:103) at io.quarkus.runtime.Quarkus.run(Quarkus.java:67) at io.quarkus.runtime.Quarkus.run(Quarkus.java:41) at io.quarkus.runtime.Quarkus.run(Quarkus.java:120) at io.quarkus.runner.GeneratedMain.main(Unknown Source)
My gradle dependencies are
dependencies { implementation 'io.quarkus:quarkus-container-image-docker' implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}") implementation enforcedPlatform("${quarkusPlatformGroupId}:quarkus-camel-bom:${quarkusPlatformVersion}") implementation 'io.quarkus:quarkus-arc' implementation 'io.quarkus:quarkus-config-yaml' implementation 'io.quarkus:quarkus-smallrye-jwt' implementation 'io.quarkus:quarkus-smallrye-health' implementation 'io.quarkus:quarkus-smallrye-metrics' implementation 'io.quarkus:quarkus-smallrye-openapi' implementation 'io.quarkus:quarkus-smallrye-jwt-build' implementation 'io.quarkus:quarkus-jackson' implementation 'io.quarkus:quarkus-resteasy-jackson' implementation 'io.quarkus:quarkus-resteasy' implementation 'org.apache.camel.quarkus:camel-quarkus-file' implementation 'org.apache.camel.quarkus:camel-quarkus-core' implementation 'org.apache.camel.quarkus:camel-quarkus-base64' implementation 'org.apache.camel.quarkus:camel-quarkus-ahc' implementation 'org.apache.camel.quarkus:camel-quarkus-jackson' implementation 'org.apache.camel.quarkus:camel-quarkus-ftp' implementation 'org.apache.camel.quarkus:camel-quarkus-rest' implementation 'org.apache.camel.quarkus:camel-quarkus-http' implementation group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.3.1' testImplementation 'io.quarkus:quarkus-junit5' testImplementation 'io.rest-assured:rest-assured' compileOnly 'org.projectlombok:lombok:1.18.16'
}
When I run it with “quarkus dev” in IntelliJ Terminal I have no problems. Do I try to run the container I get the error. Why does it happen? I have no clue how to solve it.
Edit:
Where the HttpException ist handled:
onException(HttpOperationFailedException.class) .process(new HttpExceptionHandler()) .maximumRedeliveries(5) .redeliveryDelay(1000L) .backOffMultiplier(2) .retryAttemptedLogLevel(LoggingLevel.WARN) .handled(true) .stop();
The Handler itself:
import org.apache.camel.Exchange; import org.apache.camel.component.file.FileConstants; import org.apache.camel.http.base.HttpOperationFailedException; import org.jboss.logging.Logger; public class HttpExceptionHandler implements org.apache.camel.Processor { private static final Logger LOG = Logger.getLogger(HttpExceptionHandler.class); @Override public void process(Exchange exchange) { HttpOperationFailedException failedException = exchange.getProperty( Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class); ... }
}
Advertisement
Answer
When using onException
in your routes, the class that you define needs to be registered for reflection in order for it to work in native mode.
So if you have .onException(HttpOperationFailedException.class)
, then HttpOperationFailedException
needs to be registered for reflection. For example:
@RegisterForReflection(targets = HttpOperationFailedException.class) public class Routes extends RouteBuilder { public void configure() { // Route configuration goes here } }
There’s some more information in the Camel Quarkus user guide about this:
I opened an issue to improve things for the future so that HttpOperationFailedException
does not need to be manually registered.