Skip to content
Advertisement

Camel Quarkus ClassNotFoundException: HttpOperationFailedException

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:

https://camel.apache.org/camel-quarkus/2.11.x/user-guide/native-mode.html#using-onexception-clause-in-native-mode

I opened an issue to improve things for the future so that HttpOperationFailedException does not need to be manually registered.

https://github.com/apache/camel-quarkus/issues/3971

Advertisement