Build a Custom Tokenizer for elasticsearch - elasticsearch

I'm building a custom tokenizer in response to this: Performance of doc_values field vs analysed field
None of this API appears to be documented (?), so I'm going off of code samples from other plugins/tokenizers, but when I restart elastic having deployed my tokenizer I get this error constantly in the logs:
[2017-09-20 08:45:37,412][WARN ][indices.cluster ] [Samuel Silke] [[storm-crawler-2017-09-11][3]] marking and sending shard failed due to [failed to create index]
[storm-crawler-2017-09-11] IndexCreationException[failed to create index]; nested: CreationException[Guice creation errors:
1) Could not find a suitable constructor in com.cameraforensics.elasticsearch.plugins.UrlTokenizerFactory. Classes must have either one (and only one) constructor annotated with #Inject or a zero-argument constructor that is not private.
at com.cameraforensics.elasticsearch.plugins.UrlTokenizerFactory.class(Unknown Source)
at org.elasticsearch.index.analysis.TokenizerFactoryFactory.create(Unknown Source)
at org.elasticsearch.common.inject.assistedinject.FactoryProvider2.initialize(Unknown Source)
at _unknown_
1 error];
at org.elasticsearch.indices.IndicesService.createIndex(IndicesService.java:360)
at org.elasticsearch.indices.cluster.IndicesClusterStateService.applyNewIndices(IndicesClusterStateService.java:294)
at org.elasticsearch.indices.cluster.IndicesClusterStateService.clusterChanged(IndicesClusterStateService.java:163)
at org.elasticsearch.cluster.service.InternalClusterService.runTasksForExecutor(InternalClusterService.java:610)
at org.elasticsearch.cluster.service.InternalClusterService$UpdateTask.run(InternalClusterService.java:772)
at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.runAndClean(PrioritizedEsThreadPoolExecutor.java:231)
at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.run(PrioritizedEsThreadPoolExecutor.java:194)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.elasticsearch.common.inject.CreationException: Guice creation errors:
1) Could not find a suitable constructor in com.cameraforensics.elasticsearch.plugins.UrlTokenizerFactory. Classes must have either one (and only one) constructor annotated with #Inject or a zero-argument constructor that is not private.
at com.cameraforensics.elasticsearch.plugins.UrlTokenizerFactory.class(Unknown Source)
at org.elasticsearch.index.analysis.TokenizerFactoryFactory.create(Unknown Source)
at org.elasticsearch.common.inject.assistedinject.FactoryProvider2.initialize(Unknown Source)
at _unknown_
1 error
at org.elasticsearch.common.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:360)
at org.elasticsearch.common.inject.InjectorBuilder.injectDynamically(InjectorBuilder.java:172)
at org.elasticsearch.common.inject.InjectorBuilder.build(InjectorBuilder.java:110)
at org.elasticsearch.common.inject.InjectorImpl.createChildInjector(InjectorImpl.java:157)
at org.elasticsearch.common.inject.ModulesBuilder.createChildInjector(ModulesBuilder.java:55)
at org.elasticsearch.indices.IndicesService.createIndex(IndicesService.java:358)
... 9 more
My tokenizer is built for v2.3.4, and the TokenizerFactory looks like this:
public class UrlTokenizerFactory extends AbstractTokenizerFactory {
#Inject
public UrlTokenizerFactory(Index index, IndexSettingsService indexSettings, #Assisted String name, #Assisted Settings settings){
super(index, indexSettings.getSettings(), name, settings);
}
#Override
public Tokenizer create() {
return new UrlTokenizer();
}
}
I genuinely don't know what I'm doing wrong. Have I deployed it incorrectly? It appears to be using my classes according to the logs...
I've only deployed it to one of my es nodes (4-node cluster). The /_cat/plugins?v endpoint gives this:
name component version type url
Samuel Silke urltokenizer 2.3.4.0 j
As there's little or no documentation on this process, I've got this far by copying constructs as created in plugins by other people.
The error I'm seeing doesn't make sense. My TokenizerFactory looks just like everyone else's for this version of elastic. What am I doing wrong or, possibly, not doing that I should be to make this work?

Turns out I was missing an Environment variable. It should have been this:
public UrlTokenizerFactory(Index index, IndexSettingsService indexSettings, Environment env, #Assisted String name, #Assisted Settings settings){
...
I found a similar one here in the end: https://github.com/codelibs/elasticsearch-analysis-kuromoji-neologd/blob/2.3.x/src/main/java/org/codelibs/elasticsearch/kuromoji/neologd/index/analysis/KuromojiTokenizerFactory.java

Related

Problem with Protostream and UUID in Infinispan 13.0.0.Final

I'm using Infinispan 13.0.0.final with the default marshaller (protobuf). When I try to use UUID fields in my datatypes
data class CounterState(
#get:ProtoField(number = 1) var index: Long? = null,
#get:ProtoField(number = 2) var uuid: UUID? = null
)
I get the following error at build time:
.../gradle-kotlin-protobuf/build/tmp/kapt3/stubs/main/io/radiosphere/ProtoSchema.java:8: error: org.infinispan.protostream.annotations.ProtoSchemaBuilderException: The class java.util.UUID must be instantiable using an accessible no-argument constructor.
public abstract interface ProtoSchema extends org.infinispan.protostream.GeneratedSchema {
It seems like I'm not allowed to use UUID in my types unless I generate a protoschema for it, but since UUID is a class outside of my control I can't do this.
Previous questions on the topic have gotten the suggestion to use the JavaSerializationMarshaller, but I want to solve this while still using the Protostream Marshaller. It has also been suggested that this would be fixed in version 12.0.0 here.
An example of this not working can be found here. Note that this project will not build because of the annotation processing failing as mentioned above. If it would build the proof that it is working would be shown by running the main project (ie. not the tests).
The question becomes: What do I need to do to configure UUID to be usable in my protobuf marshalled classes in Infinispan 13? Both for embedded and for a program using the hotrod client?
EDIT:
Based on a given answer I have also tried doing the following:
#AutoProtoSchemaBuilder(
includeClasses = [UUIDAdapter::class, CounterState::class],
schemaPackageName = "tutorial")
interface ProtoSchema : GeneratedSchema {
}
This makes the build work, but when starting Quarkus I get the following error:
Caused by: org.infinispan.protostream.DescriptorParserException: Duplicate type id 1005 for type org.infinispan.protostream.commons.UUID. Already used by tutorial.UUID
at org.infinispan.protostream.descriptors.ResolutionContext.checkUniqueTypeId(ResolutionContext.java:151)
at org.infinispan.protostream.descriptors.ResolutionContext.addGenericDescriptor(ResolutionContext.java:97)
at org.infinispan.protostream.descriptors.FileDescriptor.collectDescriptors(FileDescriptor.java:313)
at org.infinispan.protostream.descriptors.FileDescriptor.resolveDependencies(FileDescriptor.java:245)
at org.infinispan.protostream.descriptors.FileDescriptor.resolveDependencies(FileDescriptor.java:210)
at org.infinispan.protostream.descriptors.ResolutionContext.resolve(ResolutionContext.java:57)
at org.infinispan.protostream.impl.SerializationContextImpl.registerProtoFiles(SerializationContextImpl.java:127)
at org.infinispan.protostream.types.java.CommonTypesSchema.registerSchema(CommonTypesSchema.java:49)
at org.infinispan.client.hotrod.RemoteCacheManager.registerSerializationContextInitializer(RemoteCacheManager.java:422)
at org.infinispan.client.hotrod.RemoteCacheManager.registerDefaultSchemas(RemoteCacheManager.java:437)
at org.infinispan.client.hotrod.RemoteCacheManager.initializeProtoStreamMarshaller(RemoteCacheManager.java:409)
at org.infinispan.client.hotrod.RemoteCacheManager.actualStart(RemoteCacheManager.java:365)
at org.infinispan.client.hotrod.RemoteCacheManager.start(RemoteCacheManager.java:334)
at org.infinispan.client.hotrod.RemoteCacheManager.<init>(RemoteCacheManager.java:192)
at org.infinispan.client.hotrod.RemoteCacheManager.<init>(RemoteCacheManager.java:149)
at io.quarkus.infinispan.client.runtime.InfinispanClientProducer.initialize(InfinispanClientProducer.java:68)
If I instead change to use dependsOn like this:
#AutoProtoSchemaBuilder(
includeClasses = [CounterState::class],
dependsOn = [org.infinispan.protostream.types.java.CommonTypes::class, org.infinispan.protostream.types.java.CommonContainerTypes::class],
schemaPackageName = "tutorial")
I'm back to the build failing with:
error: org.infinispan.protostream.annotations.ProtoSchemaBuilderException: The class java.util.UUID must be instantiable using an accessible no-argument constructor.
public abstract interface ProtoSchema extends org.infinispan.protostream.GeneratedSchema {
It seems to be like Quarkus and the Annotation processor are getting in each others way here when it comes to having a simple working solution for UUID marshalling.
You have to include the org.infinispan.protostream.types.java.util.UUIDAdapter class in your annotation:
#AutoProtoSchemaBuilder(includeClasses = [CounterState::class, UUIDAdapter::class] , schemaPackageName = "tutorial")
For more info, check the documentation page.

JMeter ConcurrencyThreadGroup object creation throws java.lang.ExceptionInInitializerError error

I am trying to upgrade my JMeter DSL implementation to the latest JMeter version(5.4.3). But I got an issue with ConcurrencyThreadGroup object creation, it throws an exception. See the below exception
Using following versions
JMeter 5.4.3
jmeter-plugins-standard 1.4.0
Method implementation
public ConcurrencyThreadGroup getConcurrencyThreadGroup(String name, String targetConcurrency,
String rampUpTime, String rampUpStepCount, String timeUnit, String holdTargetTime,
boolean setEnabled
) {
ConcurrencyThreadGroup concurrencyThreadGroup = new ConcurrencyThreadGroup();
concurrencyThreadGroup.setName(name);
concurrencyThreadGroup.setTargetLevel(targetConcurrency);
concurrencyThreadGroup.setRampUp(rampUpTime);
concurrencyThreadGroup.setSteps(rampUpStepCount);
concurrencyThreadGroup.setUnit(timeUnit);
concurrencyThreadGroup.setHold(holdTargetTime);
concurrencyThreadGroup.setEnabled(setEnabled);
concurrencyThreadGroup.setProperty("TestElement.test_class", ConcurrencyThreadGroup.class.getName());
concurrencyThreadGroup.setProperty("TestElement.gui_class", ConcurrencyThreadGroupGui.class.getName());
return concurrencyThreadGroup;
}
Observing below exception when try to execute
at org.apache.jmeter.reporters.ResultCollector.<init>(ResultCollector.java:167)
at org.apache.jmeter.reporters.ResultCollector.<init>(ResultCollector.java:157)
at com.blazemeter.jmeter.reporters.FlushingResultCollector.<init>(FlushingResultCollector.java:7)
at com.blazemeter.jmeter.threads.AbstractDynamicThreadGroupModel.<init>(AbstractDynamicThreadGroupModel.java:28)
at com.blazemeter.jmeter.threads.AbstractDynamicThreadGroup.<init>(AbstractDynamicThreadGroup.java:23)
at com.blazemeter.jmeter.threads.concurrency.ConcurrencyThreadGroup.<init>(ConcurrencyThreadGroup.java:11)
at org.qa.perf.jmeter.api.threadgroups.QADSLThreadGroup.getConcurrencyThreadGroup(QADSLThreadGroup.java:136)
at org.qa.perf.jmeter.dsl.QADSLJMeterDSL.concurrencyThreadGroup(QADSLJMeterDSL.java:93)
at org.qa.perf.dsl.sample.threadgroup.ConcurrencyThreadGroupSampleTest$1.prepareJMeterTestPlan(ConcurrencyThreadGroupSampleTest.java:20)
at org.qa.perf.jmeter.engine.QADSLPerfTestClient.executeTest(QADSLPerfTestClient.java:29)
at org.qa.perf.dsl.sample.threadgroup.ConcurrencyThreadGroupSampleTest.testConcurrencyThreadGroupSampleTest(ConcurrencyThreadGroupSampleTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:132)
at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:599)
at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:174)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:822)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:147)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.testng.TestRunner.privateRun(TestRunner.java:764)
at org.testng.TestRunner.run(TestRunner.java:585)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:384)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337)
at org.testng.SuiteRunner.run(SuiteRunner.java:286)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1218)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
at org.testng.TestNG.runSuites(TestNG.java:1069)
at org.testng.TestNG.run(TestNG.java:1037)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Caused by: java.lang.NullPointerException
at org.apache.jmeter.samplers.SampleSaveConfiguration.<clinit>(SampleSaveConfiguration.java:287)
... 38 more
Appreciate any clue or solution to solve this issue.
You're supposed to show your full code and full stacktrace as the partials unfortunately don't tell the full story.
Most probably you didn't load JMeter Properties which are responsible for the Results File Configuration so my expectation is that you need to call the following function somewhere in the beginning of your code:
org.apache.jmeter.util.JMeterUtils.loadJMeterProperties("/path/to/your/jmeter.properties")
More information:
JMeter API
Five Ways To Launch a JMeter Test without Using the JMeter GUI
jmeter-from-code example project

Using a when clause in an enum class getter in Kotlin

I'm trying to get a specific getter of a property in kotlin to be based on the value of the enum it is called from. This is what I got so far:
enum class Endpoint {
EVENTS, GAMES;
val baseUrl = "https://www.example.com/api"
val path: String
get() = when(this){
EVENTS -> "$baseUrl/events"
GAMES -> "$baseUrl/games"
}
}
Called like this:
print(Endpoint.EVENTS.path)
While this compiles without any problem, as soon as I run it I get a NullPointerException with the error Attempt to invoke virtual method 'java.lang.Object [...].Endpoint[].clone()' on a null object reference
I'm not sure what I'm doing wrong or what the proper way to accomplish what is stated above is.
EDIT: Full log of the exception:
05-09 22:51:33.793 15673-15673/com.filippovigani.eventvods E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.filippovigani.eventvods, PID: 15673
java.lang.ExceptionInInitializerError
at com.filippovigani.eventvods.networking.Endpoint.getPath(Endpoint.kt:21)
at com.filippovigani.eventvods.networking.Endpoint.<init>(Endpoint.kt:25)
at com.filippovigani.eventvods.networking.Endpoint.<clinit>(Endpoint.kt)
at com.filippovigani.eventvods.networking.EventvodsApi$Companion.getEvents(EventvodsApi.kt:8)
at com.filippovigani.eventvods.MainActivity.onCreate(MainActivity.kt:19)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.filippovigani.eventvods.networking.Endpoint[].clone()' on a null object reference
at com.filippovigani.eventvods.networking.Endpoint.values(Endpoint.kt)
at com.filippovigani.eventvods.networking.Endpoint$WhenMappings.<clinit>(Unknown Source)
at com.filippovigani.eventvods.networking.Endpoint.getPath(Endpoint.kt:21) 
at com.filippovigani.eventvods.networking.Endpoint.<init>(Endpoint.kt:25) 
at com.filippovigani.eventvods.networking.Endpoint.<clinit>(Endpoint.kt) 
at com.filippovigani.eventvods.networking.EventvodsApi$Companion.getEvents(EventvodsApi.kt:8) 
at com.filippovigani.eventvods.MainActivity.onCreate(MainActivity.kt:19) 
at android.app.Activity.performCreate(Activity.java:5990) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) 
at android.app.ActivityThread.access$800(ActivityThread.java:151) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5254) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
I can't reproduce your error, the code works fine. Nevertheless, I think the solution is a bit too complex, why don't you use a constructor argument to provide the constant-specific value:
enum class Endpoint(service: String) {
EVENTS("/events"), GAMES("/games");
private val baseUrl = "https://www.example.com/api"
val path: String = baseUrl + service
}
The exception indicates you're trying to access path within the constructor of the enum. This causes a problem because the enum is not yet ready for use during construction.
This means the following chain of calls results in failure:
Init Endpoint
Init Endpoint.EVENTS
Call to Endpoint.getPath() (This does not show in your code)
Uses Endpoint$WhenMapping, begin init of that class.
Endpoint$WhenMapping uses EndPoint.values(), but since we're still initializing the instances of the enum, the values array cannot be provided, returning null.
To ensure it is not modified, WhenMapping clones and caches the array, but since the array is null when it never should be outside of initialization this causes the NPE.
Simply put your code somehow relies on a class that requires itself to be fully initialized to use. Since your code does not display how you're calling Endpoint.EVENTS.path this is all that can be said about it.

Using Carrot2 API with Java ComponentInitializationException: Could not instantiate component class

I'm trying to write a prototype for a project that involves having java use carrot2 as a metasearch engine for several sources, such as bing and google , etc.
I've got a maven project with dependency :
<dependency>
<groupId>org.carrot2</groupId>
<artifactId>carrot2-core</artifactId>
<version>3.9.3</version>
</dependency>
I'm trying to run the following :
/* A controller to manage the processing pipeline. */
Controller controller = ControllerFactory.createSimple();
/* Input data for clustering, the query and number of results in this case. */
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(AttributeNames.QUERY, "sugar");
attributes.put(AttributeNames.RESULTS, 100);
/* Perform processing */
ProcessingResult result = controller.process(attributes,
Bing3DocumentSource.class, LingoClusteringAlgorithm.class);
/* Documents fetched from the document source, clusters created by Carrot2. */
List<Document> documents = result.getDocuments();
List<Cluster> clusters = result.getClusters();
What I get is :
Exception in thread "main" org.carrot2.core.ComponentInitializationException: Could not instantiate component class: org.carrot2.source.microsoft.Bing3DocumentSource
at org.carrot2.core.SimpleProcessingComponentManager.prepare(SimpleProcessingComponentManager.java:68)
at org.carrot2.core.Controller.process(Controller.java:341)
at org.carrot2.core.Controller.process(Controller.java:246)
at com.jbaysolutions.metasearch.Test.main(Test.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.InstantiationException: org.carrot2.source.microsoft.Bing3DocumentSource
at java.lang.Class.newInstance(Class.java:359)
at org.carrot2.core.SimpleProcessingComponentManager.prepare(SimpleProcessingComponentManager.java:55)
... 8 more
Am I using the API correctly ? I've tried going over the documentation of carrot2 but it goes very little into the usage of the API, and also the examples don't seam to work.
Could really use some help here
Answer from Dawid Weiss on the carrot2 mailing list:
You're trying to instantiate an abstract class. Won't fly unless
you're Chuck Norris.
Why not look at the examples distributed with the project? There is
an example that uses Bing there.
https://github.com/carrot2/carrot2/blob/master/applications/carrot2-examples/examples/org/carrot2/examples/clustering/ClusteringDataFromDocumentSources.java#L111
All the examples are here, packaged and ready:
http://project.carrot2.org/download-java-api.html
If you're planning to use Bing make sure you use your own appkey,
please (and thanks).
The part in question is :
ProcessingResult result = controller.process(attributes,
Bing3DocumentSource.class, LingoClusteringAlgorithm.class);
That should instead read :
ProcessingResult result = controller.process(attributes,
Bing3WebDocumentSource.class, LingoClusteringAlgorithm.class);

Camel type converter fails: InvalidPayloadException: No body available of type

The application is based on OSGI.
I have a custom annotated converter:
package com.domain.bundle1.web.camel.converters;
import ...;
#Converter
public class FooTransferObjectConverter {
public FooTransferObjectConverter() {
}
#Converter
public static FooTransferObject toFooTransferObject(Foo foo, Exchange exchange) throws Exception {
// some magic
return fooTransferObject;
}
}
Also i declared package where it plased in TypeConverter file:
http://i.stack.imgur.com/U3QQH.png
which contains:
com.domain.bundle1.web.camel.converters
And camel-context file contains next code:
<log loggingLevel="INFO" message="Converting to FooTransferObject" />
<convertBodyTo type="com.domain.bundle2.model.FooTransferObject" />
<log loggingLevel="INFO" message="Converted!" />
Before converting, body of message is a Foo object.
But when process reaches converting, then throws an exception:
Failed delivery for (MessageId: ID-EPUALVIW0567-55536-1401106375216-26-5 on ExchangeId: ID-EPUALVIW0567-55536-1401106375216-26-6).
Exhausted after delivery attempt: 1 caught: org.apache.camel.InvalidPayloadException: No body available of type: com.domain.bundle2.model.FooTransferObject but has value: Foo{97, Wall, null, null} of type: com.domain.bundle3.model.Foo on: Message: Foo{97, Wall, null, null}.
Caused by: Error during type conversion from type: com.domain.bundle3.model.Foo to the required type: com.domain.bundle2.model.FooTransferObject with value Foo{97, Wall, null, null} due 6 counts of IllegalAnnotationExceptions. Exchange[Message: Foo{97, Wall, null, null}]. Caused by: [org.apache.camel.TypeConversionException - Error during type conversion from type: Foo{97, Wall, null, null} to the required type: com.domain.bundle2.model.FooTransferObjec with value....
then exception cached by custom handler,
and then I found this:
Caused by: javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: A cycle is detected in the object graph. This will cause infinitely deep XML: freebaseball SpeedKick -> fr????f????tb??ll Sp????dK??ck -> free
football SpeedKick ]
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:311)[:1.7.0_40]
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)[:1.7.0_40]
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:95)
at org.apache.camel.converter.jaxb.FallbackTypeConverter.marshall(FallbackTypeConverter.java:238)
at org.apache.camel.converter.jaxb.FallbackTypeConverter.convertTo(FallbackTypeConverter.java:95)
... 163 more
Caused by: com.sun.istack.internal.SAXException2: A cycle is detected in the object graph. This will cause infinitely deep XML: freebaseball SpeedKick -> fr????f????tb??ll Sp????dK??c
k -> freebaseball SpeedKick
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:237)[:1.7.0_40]
How do You think what's a problem? How can I see loaded converters in TypeConverterRegistry?
I have already solved my problem. FallbackTypeConverter started work, because camel didn't load my custom regular type converter.
I checked the map of converters in TypeConverterRegister in debug mode, and didn't find my FooTransferObjectConverter.
The problem was in file TypeConverter. I just added name of converter class to path and after that it loaded to registry.
com.domain.bundle1.web.camel.converters.FooTransferObjectConverter
Camel version in application - 2.11.1. In camel docs written next:
In Camel 2.8 we improved the type converter loader to support
specifying the FQN class name of the converter classes. This has the
advantage of avoiding having to scan packages for #Converter classes.
Instead it loads the #Converter class directly. This is a highly
recommend approach to use going forward.
But i tryed run the application from chapter 3 (from 'Camel in action' book) with custom converter. And file TypeConverter contained only from package path.

Resources