I've got some Objectify test code running in JUnit and I'm getting this error:
java.lang.IllegalStateException: You have not started an Objectify context. You are probably missing the ObjectifyFilter. If you are not running in the context of an http request, see the ObjectifyService.run() method.
at com.googlecode.objectify.ObjectifyService.ofy(ObjectifyService.java:44)
at com.googlecode.objectify.impl.ref.LiveRef.<init>(LiveRef.java:31)
at com.googlecode.objectify.Ref.create(Ref.java:26)
at com.googlecode.objectify.Ref.create(Ref.java:32)
at com.netbase.followerdownloader.repository.DownloadTaskRepositoryImpl.create(DownloadTaskRepositoryImpl.java:35)
at com.netbase.followerdownloader.repository.DownloadTaskRepositoryImplTest.setUp(DownloadTaskRepositoryImplTest.java:45)
How do I resolve this for test code?
Jeff Schnitzer answered this here: https://groups.google.com/forum/#!topic/objectify-appengine/8HinahG7irg. That link points to https://groups.google.com/forum/#!topic/objectify-appengine/O4FHC_i7EGk where Jeff suggests the following quick and dirty workaround:
My #BeforeMethod starts an objectify context (ObjectifyService.begin())
My #AfterMethod closes the objectify context
Jeff suggests we use ObjectifyService.run() instead but admits it's more work.
Here's how my implementation looks:
public class DownloadTaskRepositoryImplTest {
// maximum eventual consistency (see https://cloud.google.com/appengine/docs/java/tools/localunittesting)
private final LocalServiceTestHelper helper =
new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()
.setDefaultHighRepJobPolicyUnappliedJobPercentage(100));
private Closeable closeable;
#Before
public void setUp() {
helper.setUp();
ObjectifyRegistrar.registerDataModel();
closeable = ObjectifyService.begin();
}
#After
public void tearDown() {
closeable.close();
helper.tearDown();
}
I also had this issue and noticed that I had not added the ObjectifyFilter to my web.xml
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I also had to include Objectify and guava jars in my WEB-INF>lib directory and include them in my build path.
I was facing the same error and this solusion worked for me
I have an app based on Endpoints that uses Objectify. When I leave it with the default/automatic scaling, everything works great. Once I enable basic scaling, though, I get the following exception when executing the endpoint method:
[INFO] java.lang.IllegalStateException: You have not started an Objectify context. You are probably missing the ObjectifyFilter. If you are not running in the context of an http request, see the ObjectifyService.run() method.
[INFO] at com.googlecode.objectify.ObjectifyService.ofy(ObjectifyService.java:44)
[INFO] at com.myco.myapp.dao.datastore.OfyService.ofy(OfyService.java:62)
The good news is that this goes away when you enable RequestDispatcher
support in the web.xml file like so. I think this is a documentation
issue, then, but I didn't know if everyone would agree if I edited the
Wiki page directly. Here is the proposed web.xml entry, which worked
for me:
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Improving michael-osofsky answer, I add this to my ofy helper class
public static void registerDataModel() {
try {
factory().register(Profile.class);
} catch (Exception e){
e.printStackTrace();
}
}
and remplace
ObjectifyRegistrar.registerDataModel();
for this
OfyService.registerDataModel();
OfyService.java
public static void registerDataModel() {
try {
factory().register(Profile.class);
} catch (Exception e){
e.printStackTrace();
}
}
As Jeff Schnitzer says in the link provided by Michael Osofsky:
In your tests you should have some notion of a 'request' even if it is just conceptual. If "each test is a request by itself", then you can use #Before/#After in conjunction with ObjectifyService.begin() to demarcate the requests. However, this is probably not actually how your tests work - it isn't how my tests work.
He then goes on to say:
This would be prettier with JDK8 closures but the idea is straightforward - you're wrapping some unit of work in a context which represents a request. It would probably be smart to add even more context like authentication in that wrapper too.
I came up with the following implementation of his idea. With the solution below, you can ensure each call to a servlet handler gets a fresh Objectify session while still making your servlet handler calls in a single line of code. It also decouples your tests from explicitly worrying about Objectify, and allows you to add additional non-Objectify context around your servlet handlers.
My solution below works with Objectify 5.1.22. I tried using Objectify 6+, but I had problems that seem to be related to this.
First, define a custom Supplier that is able to capture the exceptions thrown by a servlet handler.
#FunctionalInterface
public interface ServletSupplier<T> {
T get()
throws ServletException, IOException;
}
Next, define a wrapper method that accepts your new custom Supplier as an input, and wrap the call to ServletSupplier.get() in a try-with-resources block that calls ObjectifyService.begin(). You must also register your entity classes before calling ServletSupplier.get().
public <T> T runInServletContext(ServletSupplier<T> servletMethod)
throws ServletException, IOException {
try (Closeable session = ObjectifyService.begin()) {
ObjectifyService.register(MyObj.class);
return servletMethod.get();
}
}
Finally, anywhere in your tests that you call the servlet handler you should do so using the wrapper method.
MyObj myObjPost = runInServletContext(() -> getServlet().doPost(request, response));
// Assert results of doPost call.
MyObj myObjGet = runInServletContext(() -> getServlet().doGet(request, response));
// Assert results of doGet call.
Just in case someone ends up here (as I originally did) looking up the same problem but for the ktor "main.kt" server instead of unit tests...
After looking at the ObjectifyFilter source code, I added
val closer = ObjectifyService.begin()
... real service here ...
closer.close()
around my actual servlet code and that fixed the problem.
Related
I use Objectify 6.0.5, Ktor 1.2.6, com.google.appengine:appengine:1.9.60
I set up web.xml, bootstrapper by tutorial https://github.com/objectify/objectify/wiki/Setup
web.xml
...
<listener>
<listener-class>com.group.Bootstrapper</listener-class>
</listener>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
Boostrapper
class Bootstrapper : ServletContextListener {
override fun contextInitialized(sce: ServletContextEvent?) {
println(" contextInitialized")
ObjectifyService.init(
ObjectifyFactory()
)
ObjectifyService.register(User::class.java)
}
override fun contextDestroyed(sce: ServletContextEvent?) {}
}
When I call this method
fun save(entity: T) {
ofy().save().entity(entity)
}
I catch error
2020-01-05 17:55:09 ERROR Application:104 - Unhandled: GET - /test
java.lang.IllegalStateException: You must call ObjectifyService.init() before using Objectify
at com.google.common.base.Preconditions.checkState(Preconditions.java:511) ~[guava-28.1-android.jar:?]
at com.googlecode.objectify.ObjectifyService.factory(ObjectifyService.java:34) ~[objectify-6.0.5.jar:?]
at com.googlecode.objectify.ObjectifyService.ofy(ObjectifyService.java:51) ~[objectify-6.0.5.jar:?]
at com.group.dao.BaseDao.listAll(BaseDao.kt:15) ~[classes/:?]
at com.group.ApplicationKt$module$2$2.invokeSuspend(Application.kt:50) ~[classes/:?]
at com.group.ApplicationKt$module$2$2.invoke(Application.kt) ~[classes/:?]
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:268) ~[ktor-utils-jvm-1.2.6.jar:1.2.6]
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(PipelineContext.kt:141) ~[ktor-utils-jvm-1.2.6.jar:1.2.6]
at io.ktor.util.pipeline.SuspendFunctionGun.execute(PipelineContext.kt:161) ~[ktor-utils-jvm-1.2.6.jar:1.2.6]
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:27) ~[ktor-utils-jvm-1.2.6.jar:1.2.6]
at io.ktor.routing.Routing.executeResult(Routing.kt:147) ~[ktor-server-core-1.2.6.jar:1.2.6]
...
I run datastore using 'gcloud beta emulators datastore start'. It definitely run. May be is not connect to it?
When I run app use appengineRun, datastore also is run?
The Problem is that ktor uses coroutines. Coroutines run in a thread pool by default and the ObjectifyFilter is only active for the thread receiving the request. I use this workaround until I find something better:
get(path) {
withContext(Dispatchers.Unconfined) {
val content = page.doGet()
call.respond(content)
}
}
The Unconfined dispatcher runs the coroutine in the same thread who started it, at least until the first suspend.
When I use came-snmp resive snmp info which version is 3, it can't go to the process method.
#Component
public class SnmpCollect extends RouteBuilder {
#Override
public void configure() throws Exception {
from("snmp:0.0.0.0:162?protocol=udp&type=TRAP&snmpVersion=3&securityName=test").process(new Processor() {
#Override
public void process(Exchange arg0) throws Exception {
}
}
}
Camel xml config:
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="snmpCollect"/>
</camelContext>
But when the snmp info which version is 1 or 2 is coming, it can go to the process method.
What's wrong with it, and how to make it work for "snmpVersion=3" info?
Camel Version is 2.20.1
Let me try to answer your question by providing some info based in what I've found.
Seems that he requirements and interfaces from v1 and v2 version differ from v3, so it doesn't like to work just updating the version. The mainly difference, from what I've seen, is that you need to provide a security model to v3. I saw that you are passing it via parameters, but have you got the chance to check the security requirements?
When I use the TrapTest where is on the camel-snmp github “github.com/apache/camel/blob/master/components/camel-snmp/src/…”,it‘s ok.But when I change the snmpVersion to SnmpConstants.version3,it's also error
That's because the interface changed and the test should rely on ScopedPDU model instead of the base class PDU. Also the security model isn't set up in this test:
org.snmp4j.MessageException: Message processing model 3 returned error: Unsupported security model
Unfortunately there isn't any example using camel-snmp with v3, but you could take a look into this example using the inner component snmp4j.
I'am writing a simple . application deploying on Karaf 4.1.0. It's role is sending a rest request to REST API. When I start my bundle I have an error:
javax.ws.rs.ProcessingException: org.apache.cxf.interceptor.Fault: No message body writer has been found for class package.QueueSharedDTO, ContentType: application/json
at org.apache.cxf.jaxrs.client.WebClient.doResponse(WebClient.java:1149)
at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1094)
at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:894)
at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:865)
at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:428)
at org.apache.cxf.jaxrs.client.WebClient$SyncInvokerImpl.method(WebClient.java:1631)
at org.apache.cxf.jaxrs.client.WebClient$SyncInvokerImpl.method(WebClient.java:1626)
at org.apache.cxf.jaxrs.client.WebClient$SyncInvokerImpl.post(WebClient.java:1566)
at org.apache.cxf.jaxrs.client.spec.InvocationBuilderImpl.post(InvocationBuilderImpl.java:145)
at package.worker.service.implementation.ConnectionServiceImpl.postCheckRequest(ConnectionServiceImpl.java:114)
at package.worker.service.implementation.ConnectionServiceImpl.sendCheck(ConnectionServiceImpl.java:103)
at package.worker.module.QueueSharedListener.run(QueueSharedListener.java:37)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.cxf.interceptor.Fault: No message body writer has been found for class package.QueueSharedDTO, ContentType: application/json
at org.apache.cxf.jaxrs.client.WebClient$BodyWriter.doWriteBody(WebClient.java:1222)
at org.apache.cxf.jaxrs.client.AbstractClient$AbstractBodyWriter.handleMessage(AbstractClient.java:1091)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.jaxrs.client.AbstractClient.doRunInterceptorChain(AbstractClient.java:649)
at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1093)
... 11 more
Caused by: javax.ws.rs.ProcessingException: No message body writer has been found for class com.emot.dto.QueueSharedDTO, ContentType: application/json
at org.apache.cxf.jaxrs.client.AbstractClient.reportMessageHandlerProblem(AbstractClient.java:780)
at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(AbstractClient.java:494)
at org.apache.cxf.jaxrs.client.WebClient$BodyWriter.doWriteBody(WebClient.java:1217)
... 15 more
Initialization WebTarget:
private ConnectionServiceImpl() {
client = ClientBuilder.newClient();
client.property(
ClientProperties.CONNECT_TIMEOUT,
snifferProperties.getProperty(SnifferProperties.PARAM_REST_API_CONNECTION_TIMEOUT));
client.property(
ClientProperties.READ_TIMEOUT,
snifferProperties.getProperty(SnifferProperties.PARAM_REST_API_READ_TIMEOUT));
System.out.println(2);
webTarget = client.target(buildUrl());
}
Send requests :
private synchronized boolean postCheckRequest(String path, Object content) {
boolean result = true;
try {
Response response = webTarget
.path("check")
.path("add/one")
.request(MediaType.APPLICATION_JSON)
.post(Entity.json(content));
result = (response.getStatus() == 200);
} catch (Exception e) {
System.out.println("Error but working");
e.printStackTrace();
result = false;
}
return result;
}
I have always the problems with Karaf... i dont understand why it . couldn't working correctly...
The issue you are facing is mostly not a Karaf issue, but a typical issue you may face while working with some JAX-RS implementation in non-JavaEE environment.
Exception literally says that your implementation misses message body writer. Message body writer is the class which implements class javax.ws.rs.ext.MessageBodyWriter and is responsible for serializing your data objects to some format (like JSON). There is another class named javax.ws.rs.ext.MessageBodyReader, which does the opposite thing. All these classes are registered to JAX-RS framework as providers, extending its capabilities. Details are here: https://jersey.java.net/documentation/latest/message-body-workers.html
So, generally you must decide what you use for serializing/deserializing between your data objects and HTTP MediaType and register a proper JAX-RS provider.
With Jackson, for example, your problem can be easily solved by using one of its standard implementation: either com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider, if you use JAXB annotations, or com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider, if you prefer Jackson annotations. Add this class in providers section of your Blueprint descriptor:
<jaxrs:server id="restServer" address="/rest">
<jaxrs:serviceBeans>
....
</jaxrs:serviceBeans>
<jaxrs:providers>
....
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"/>
....
</jaxrs:providers>
</jaxrs:server>
edit seems not to be possible at the moment filed an issue.
i am using log4j2 in my apache camel application. In camel file names can be configured this way "?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz"
if i set log level to debug camel tries to log what it is doing but log4j seems to try to lookup/interpret the string with "date:" and throws an exception:
2014-11-24 11:29:19,218 ERROR Invalid date format: "now:yyyyMMdd-HHmmss", using default java.lang.IllegalArgumentExcepti
on: Illegal pattern character 'n'
at java.text.SimpleDateFormat.compile(Unknown Source)
at java.text.SimpleDateFormat.initialize(Unknown Source)
at java.text.SimpleDateFormat.<init>(Unknown Source)
at java.text.SimpleDateFormat.<init>(Unknown Source)
at org.apache.logging.log4j.core.lookup.DateLookup.formatDate(DateLookup.java:60)
at org.apache.logging.log4j.core.lookup.DateLookup.lookup(DateLookup.java:53)
at org.apache.logging.log4j.core.lookup.Interpolator.lookup(Interpolator.java:144)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.resolveVariable(StrSubstitutor.java:1008)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:926)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:816)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.replace(StrSubstitutor.java:385)
at org.apache.logging.log4j.core.pattern.MessagePatternConverter.format(MessagePatternConverter.java:71)
at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:36)
at org.apache.logging.log4j.core.layout.PatternLayout.toSerializable(PatternLayout.java:189)
at org.apache.logging.log4j.core.layout.PatternLayout.toSerializable(PatternLayout.java:53)
at org.apache.logging.log4j.core.layout.AbstractStringLayout.toByteArray(AbstractStringLayout.java:52)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:
104)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:97)
at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:428)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:407)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:365)
at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:112)
at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:1347)
at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1312)
at org.apache.logging.slf4j.Log4jLogger.debug(Log4jLogger.java:132)
at org.apache.camel.util.IntrospectionSupport.setProperty(IntrospectionSupport.java:518)
at org.apache.camel.util.IntrospectionSupport.setProperty(IntrospectionSupport.java:570)
at org.apache.camel.util.IntrospectionSupport.setProperties(IntrospectionSupport.java:454)
at org.apache.camel.util.EndpointHelper.setProperties(EndpointHelper.java:249)
at org.apache.camel.impl.DefaultComponent.setProperties(DefaultComponent.java:272)
at org.apache.camel.component.file.GenericFileComponent.createEndpoint(GenericFileComponent.java:67)
at org.apache.camel.component.file.GenericFileComponent.createEndpoint(GenericFileComponent.java:37)
at org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:123)
at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:514)
at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:547)
Is there a way to turn off this "date:" lookup? Why does it try to interpret stuff coming from log at all? I think it should not be touched in any way?!
Edit, very easy to reproduce in test:
public class LogTest {
private Logger log = LoggerFactory.getLogger(LogTest.class);
#Test
public void test() {
log.info("${date:now:buhu}");
}
}
It is crucial to us ${date:} - only "data:now" is working.
So this problem is completely independent from camel, but camel uses ${date:...} pattern for several things. Here is a simple route that reproduces the problem - the exception will be thrown on camel set up phase - no test code needed - logging level must be "debug"!:
public class LogTest extends CamelTestSupport{
private Logger log = LoggerFactory.getLogger(LogTest.class);
#Test
public void test() {
//log.info("${date:now:yyyyMMdd-HHmmss}");
}
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:a").to("file:./?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz");
}
};
}
}
This issue was fixed in 2.7 version of Log4j2.
The solution is to upgrade to that version (or higher) and add in the pattern attribute the option "{nolookups}" to %msg .
%msg{nolookups}
For example
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{1} %L %M %t - %msg{nolookups}%n%xEx%n" />
The problem can be avoided, if the simple-Expression is written as $simple{..} instead of ${..}. Then log4j2 won't use his Date-Lookup.
So, if you change your Route from:
from("direct:a").to("file:./?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz");
to:
from("direct:a").to("file:./?fileName=$simple{date:now:yyyyMMdd-HHmmss}ID.${id}.gz");
it should work, even if you debug Camel.
To disable the date lookup locally, you can add a "$" in front of the expression:
log.info("$${date:now:buhu}");
This will print ${date:now:buhu} instead of throwing an exception printing the stack trace.
As for how to avoid this using Camel, I'm not sure. The cleanest fix would probably be a log4j2 update to disable their DateLookup feature. A temporary fix is to disable DEBUG level logs from the org.apache.camel package:
<loggers>
<logger name="org.apache.camel" level="INFO" />
<root level="debug">
<appender-ref ref="Console" />
</root>
</loggers>
It's not ideal, but we can increase the log level if we ever need to debug Camel context creation since the log statements are not necessary for general everyday development.
The correct solution is now to upgrade the log4j-core library to 2.15.0 or above. At time of writing, the latest and current recommended version is 2.16.0.
The variable substitutions happening in logged messages here are symptoms of the same feature exploited in CVE-2021-44228, aka Log4Shell.
The feature is disabled by default in 2.15.0 and removed in 2.16.0.
It's not news to anyone by now, but it's really important to take steps to disable this feature, as a security measure, even if not using Apache Camel or encountering the issue as described.
As an aside, I found this question when searching for early warning signs of the Log4Shell vulnerability. I've quoted it in my write-up.
cannot figure out what is going on with this - trying to set up a route to just see cxf connect to a soap web service (I don't care about the actual data and don't expect the data to actually 'work', but it keeps throwing an exception I don't understand:
I wonder if I'm configuring it correctly.
I was thinking it might be a missing jar, but strated causing dependency conflicts when I tried to bring in other Jars
I'm using a maven dependency "camel-cxf" to load in all my jar configuration
"Reason: org.apache.cxf.bus.extension.ExtensionException: Could not load extension class org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl."
The exact error is
"Failed to create Producer for endpoint: Endpoint[cxf://http://wsf.cdyne.com/WeatherWS/Weather.asmx?dataFormat=MESSAGE&portName=WeatherSoap&serviceClass=prototypes.CxfExample%24GetWeatherInformationSoapIn&serviceName=Weather&wsdlURL=http%3A%2F%2Fwsf.cdyne.com%2FWeatherWS%2FWeather.asmx%3FWSDL]. Reason: org.apache.cxf.bus.extension.ExtensionException: Could not load extension class org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl."
The code I'm using to cause this is
camel.addComponent( "cxf", new CxfComponent() );
camel.addRoutes( new RouteBuilder() {
#Override
public void configure() throws Exception {
from( "timer://sometimer?delay=1s")
.to( "cxf://http://wsf.cdyne.com/WeatherWS/Weather.asmx"
+"?wsdlURL=http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL"
+"&dataFormat=MESSAGE"
+"&serviceClass=prototypes.CxfExample$GetWeatherInformationSoapIn"
+"&serviceName=Weather"
+"&portName=WeatherSoap"
);
}
});
camel.start();
Thread.sleep( 10000 );
camel.stop();
I think I have 'solved' it -
mvn:camel-cfx dependency is not enough
you need mvn:neethi dependency too
the AssertationBuildImpl class extends from a class that is not included in the jar-set for mvn:camel-cfx, which makes AssertationBuildImpl appear listed as a known class in the ide, but doesn't get class-loaded at runtime
this was a horrendous problem to track down, by analysing source-code of third-parties