Apache camel Connection pool timeout with restlet even after configuring component options - java

I have a camel Java DSL route which invokes a restlet endpoint. And the route works without any issues when I hit the same manually. But, when I try to pump a larger number of requests through code I'm getting "Timeout waiting for connection from pool"
And the following is stackt-race of the same:
2016-01-29 14:09:38.650 WARN 20256 --- [pool-3-thread-2] org.restlet : An error occurred during the communication with the remote HTTP server.org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:412)
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1.getPoolEntry(ConnPoolByRoute.java:298)
at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1.getConnection(ThreadSafeClientConnManager.java:238)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:423)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at org.restlet.ext.httpclient.internal.HttpMethodCall.sendRequest(HttpMethodCall.java:339)
at org.restlet.engine.adapter.ClientAdapter.commit(ClientAdapter.java:105)
at org.restlet.engine.adapter.HttpClientHelper.handle(HttpClientHelper.java:119)
at org.restlet.Client.handle(Client.java:153)
at org.restlet.Restlet.handle(Restlet.java:275)
at org.apache.camel.component.restlet.RestletProducer.process(RestletProducer.java:79)
at org.apache.camel.component.restlet.RestletProducer.process(RestletProducer.java:98)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:668)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:596)
at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:237)
at org.apache.camel.processor.Splitter.process(Splitter.java:104)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)
at org.apache.camel.processor.MulticastProcessor.doProcessParallel(MulticastProcessor.java:814)
at org.apache.camel.processor.MulticastProcessor.access$200(MulticastProcessor.java:84)
at org.apache.camel.processor.MulticastProcessor$1.call(MulticastProcessor.java:314)
at org.apache.camel.processor.MulticastProcessor$1.call(MulticastProcessor.java:299)
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)
And as per the doc I did configure the restlet component with the following code but I'm still seeing the same issue:
#Bean
public RestletComponent restlet()
{
RestletComponent restlet = new RestletComponent();
restlet.setMaxThreads(100);
restlet.setThreadMaxIdleTimeMs(10000);
restlet.setMaxQueued(20);
return restlet;
}
Note: The route did accepted 10 requests at a time then I started getting errors. And from configuration I could see the maxThreads by default is 10. Which means the that I did through Bean is not picking up properly.

Actually in my code I have defined restlet bean after route configure i.e as below
public class RoutesBuilder extends FatJarRouter {
....
#Override
public void configure() throws JAXBException {
......
}
#Bean(name={"restlet"})
public RestletComponent restlet()
{
.......
}
}
And now I have changed the order of defining the code as i.e first I have defined restlet and the route configure as below. With that in place I saw the restlet configuration is been picked up and I no more see the connection pool issue.
public class RoutesBuilder extends FatJarRouter {
....
#Bean(name={"restlet"})
public RestletComponent restlet()
{
.......
}
#Override
public void configure() throws JAXBException {
......
}
}

Check these things:
Make sure you have enabled <context:annotation-config/> in the Spring App Context XML file.
Use <context:component-scan base-package="<your package>" /> in the Spring XML.
Make sure you have annotated the containing that #Bean with #Configuration.
Add the name attribute to the #Bean: #Bean(name={"restlet"}).
Hope that helps.

Take a look at this example. Its Spring-boot APP. I created a separate config class and used spring-boot configuration annotation, so on startup spring-boot does all the configuration needed
Here is a working solution
https://github.com/RakeshBhat/rb-springbootcamelrestlet

Related

Caused by: java.lang.ClassNotFoundException: org.eclipse.core.runtime.Plugin

Recently I've been trying to set and customize scheduler in our XPages project. I've tried to put the following snippet in our project:
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator extends Plugin implements BundleActivator {
#Override
public void start(final BundleContext context) throws Exception {
// Here you start your scheduler
}
}
In the Code section of a template I can easily write this code I don't have a warning about unresolved dependencies. So, the org.eclipse.core.runtime and org.osgi.framework packages must be shipped with Domino I thought.
But it seems that it does not.
Whenever this code is executed I get 500 error in a browser and the stack as follows:
javax.servlet.ServletException: java.lang.NoClassDefFoundError: org.eclipse.core.runtime.Plugin
at com.ibm.xsp.webapp.FacesServlet.handleError(FacesServlet.java:595)
at com.ibm.xsp.webapp.FacesServlet.renderErrorPage(FacesServlet.java:424)
at com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:182)
at com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:138)
at com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:588)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1335)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:865)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:808)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:577)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1319)
at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:662)
at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:482)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:357)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:313)
at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)
Caused by: java.lang.NoClassDefFoundError: org.eclipse.core.runtime.Plugin
at java.lang.ClassLoader.defineClassImpl(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:346)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:154)
at com.ibm.domino.xsp.module.nsf.ModuleClassLoader$DynamicClassLoader.findClass(ModuleClassLoader.java:455)
at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:850)
at java.lang.ClassLoader.loadClass(ClassLoader.java:829)
at com.ibm.domino.xsp.module.nsf.ModuleClassLoader$DynamicClassLoader.loadClass(ModuleClassLoader.java:403)
at java.lang.ClassLoader.loadClass(ClassLoader.java:809)
at ru.lanit.egrz.scheduler.RefreshEGRZTokenExecutor.executeAndScheduleRefreshToken(RefreshEGRZTokenExecutor.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at com.ibm.jscript.types.JavaAccessObject.call(JavaAccessObject.java:322)
at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161)
at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197)
at com.ibm.jscript.ASTTree.ASTProgram.interpret(ASTProgram.java:119)
at com.ibm.jscript.ASTTree.ASTProgram.interpretEx(ASTProgram.java:139)
at com.ibm.jscript.JSExpression._interpretExpression(JSExpression.java:435)
at com.ibm.jscript.JSExpression.access$1(JSExpression.java:424)
at com.ibm.jscript.JSExpression$2.run(JSExpression.java:414)
at java.security.AccessController.doPrivileged(AccessController.java:686)
at com.ibm.jscript.JSExpression.interpretExpression(JSExpression.java:410)
at com.ibm.jscript.JSExpression.evaluateValue(JSExpression.java:251)
at com.ibm.jscript.JSExpression.evaluateValue(JSExpression.java:234)
at com.ibm.xsp.javascript.JavaScriptInterpreter.interpret(JavaScriptInterpreter.java:222)
at com.ibm.xsp.binding.javascript.JavaScriptMethodBinding.invoke(JavaScriptMethodBinding.java:111)
at com.ibm.xsp.application.ActionListenerImpl.processAction(ActionListenerImpl.java:60)
at javax.faces.component.UICommand.broadcast(UICommand.java:324)
at com.ibm.xsp.component.UIEventHandler.broadcast(UIEventHandler.java:366)
at com.ibm.xsp.component.UIDataPanelBase.broadcast(UIDataPanelBase.java:400)
at com.ibm.xsp.component.UIViewRootEx.broadcast(UIViewRootEx.java:1535)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:307)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:428)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:94)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:210)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:96)
at com.ibm.xsp.controller.FacesControllerImpl.execute(FacesControllerImpl.java:256)
at com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:227)
at com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:157)
at com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:159)
... 13 more
Caused by: java.lang.ClassNotFoundException: org.eclipse.core.runtime.Plugin
at com.ibm.domino.xsp.module.nsf.ModuleClassLoader$DynamicClassLoader.loadClass(ModuleClassLoader.java:359)
at java.lang.ClassLoader.loadClass(ClassLoader.java:809)
... 54 more
IBM literally freaks me out over and over and over again (sorry for that).
I tried to add it as external jars in the section -> Still the same.
I even tried to add these two to lib/ext -> Still the same.
In the build path these two included as Plug-In Dependencies.
Literally, there's something wrong with importing jars and resolving dependencies in Domino (even beyond the scope of this particular problem) I believe.
This is my 3rd if not 4th question on IBM Domino. I sincerely apologize to the community for being that embarrassing but get me right please. In Domino you solve one problem and then the other two emerge. You solve these two and then the other 4 break the app down. And so on
How do I import it correctly without any problems?
Thanks in advance
UPD
To improve my question I'll add some code
So, the bean looks like this:
SchedulerActivatorBean:
import java.io.Serializable;
public class SchedulerActivatorBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3559937702716018697L;
public static void activate() throws Exception
{
new SchedulerActivator().start(null);
}
}
SchedulerActivator (OSGI plugin):
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class SchedulerActivator extends Plugin implements BundleActivator {
#Override
public void start(final BundleContext context) throws Exception {
// Here you start your scheduler
QuartzScheduler.getInstance(); // starts the scheduler
}
}
Then I modified faces-config.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
<managed-bean>
<managed-bean-name>schedulerActivatorBean</managed-bean-name>
<managed-bean-class>ru.lanit.egrz.scheduler.SchedulerActivatorBean</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
</faces-config>
And finally I call the bean from SSJS:
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete"
action="#{javascript:schedulerActivatorBean.activate()}">
</xp:eventHandler>
The bean is instantiated and available in the app. But when I call the method, I still get:
Caused by: java.lang.ClassNotFoundException: org.eclipse.core.runtime.Plugin
at com.ibm.domino.xsp.module.nsf.ModuleClassLoader$DynamicClassLoader.loadClass(ModuleClassLoader.java:359)
at java.lang.ClassLoader.loadClass(ClassLoader.java:809)
... 54 more
Which, needless to say, left me clueless
A plugin doesn’t live in the NSF. You might want to learn about that first. Use this as a starter: https://www.slideshare.net/fiorep/domino-osgi-development
You might want to revisit your whole approach. Why not use a Notes agent that is scheduled and refreshes token which you store in an NSF. Simple problem solved.
Then have your XPage lookup the values in the NSF. Saves you the whole headache.
For new users you can use agent.run from XPages. The trick is the storage in the NSF.
Use reader fields to secure documents, so users can’t see each other tokens.

Why Spring Integration message method handling behavoiur is changed in default Spring Cloud Stream configuration

I have an application where Spring Integration (5.1.6 latest) is already used. And something like the following flow configured:
#Configuration
public class SomeConfigClass {
...
#MessagingGateway(name = "someGateway")
interface Gateway {
#Gateway(requestChannel = "inboundChannel")
#Payload("T(java.time.ZonedDateTime).now()")
void replicate();
}
#Bean
public DirectChannel inboundChannel() {
return MessageChannels.direct().get();
}
#Bean
public IntegrationFlow someFlow() {
return IntegrationFlows.from(inboundChannel())
.handle(someHandler())
.channel(OUT)
.get();
}
#Bean
public SomeHandler someHandler() {
return new SomeHandler();
}
}
and
public class SomeHandler implements GenericHandler<Object> {
#Override
public Message<List<String>> handle(final Object payload,
final MessageHeaders headers) {
...
return MessageBuilder
.withPayload(someList)
.copyHeaders(headers)
.setHeader("custom", customHeader)
.build();
}
}
Everything works fine.
And if I try to find integrationArgumentResolverMessageConverter bean in context initialised I see next converters:
MappingJackson2MessageConverter
ByteArrayMessageConverter
ObjectStringMessageConverter
GenericMessageConverter
After that I add to my pom dependencies Spring Cloud Stream 2.1.2 dependency and Kinesis Binder 1.2.0. Configure bindings by default.
The application starts up but when I trying to process my existing flow it failed with something like:
EL1004E: Method call: Method handle(java.time.ZonedDateTime,org.springframework.messaging.MessageHeaders) cannot be found on type p.a.c.k.a.g.e.SomeHandler at org.springframework.expression.spel.ast.MethodReference.findAccessorForMethod(MethodReference.java:225)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:134)
at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:54)
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:390)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:90)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:114)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:365)
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:172)
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:160)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.invokeExpression(MessagingMethodInvokerHelper.java:664)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.invokeHandlerMethod(MessagingMethodInvokerHelper.java:655)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:491)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:362)
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:106)
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:93)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:123)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:169)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:453)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:401)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:151)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:143)
at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:413)
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:533)
at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:473)
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:463)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy444.replicate(Unknown Source)
And when I try to get the same integrationArgumentResolverMessageConverter bean from initialized context I see next chain:
ApplicationJsonMessageMarshallingConverter
TupleJsonMessageConverter
ByteArrayMessageConverter
ObjectStringMessageConverter
JavaSerializationMessageConverter
KryoMessageConverter
JsonUnmarshallingConverter
And there is no GenericMessageConverter. As I understand it cannot be converted because of this converter missed (correct me please if I am wrong).
Why is the behaviour different when I just add Spring Cloud Stream default configuration? Or how to customize of using converters chain for specific flow? Or how to keep message conversation behaviour for different integration flow?
Update: So as I investigated spring cloud stream re-defines not only default integration MessageConverters, but also it re-defines default HandlerMethodArgumentResolvers, which is used to map method argument with a message..
Before additing Spring Cloud Stream:
HeaderMethodArgumentResolver
HeadersMethodArgumentResolver
MessageMethodArgumentResolver
PayloadExpressionArgumentResolver
NullAwarePayloadArgumentResolver
PayloadsArgumentResolver
MapArgumentResolver
PayloadArgumentResolver
After additing Spring Cloud Stream:
SmartPayloadArgumentResolver
SmartMessageMethodArgumentResolver
HeaderMethodArgumentResolver
HeadersMethodArgumentResolver
PayloadExpressionArgumentResolver
NullAwarePayloadArgumentResolver
PayloadExpressionArgumentResolver
PayloadsArgumentResolver
MapArgumentResolver
There two deprecated SmartPayloadArgumentResolver and SmartMessageMethodArgumentResolver with fix for conversion from byte[] payload to Object. But what I cannot understand why there are two PayloadExpressionArgumentResolver?..
And the main question: why Spring Cloud Stream default application context affects Spring Integration default application context, I thought before that Stream's resolvers/converters were only related to message endpoints linked with stream destination channels...
I am not sure why Stream drops that converter (could be a bug, maybe open a GitHub issue over there), but I believe you can add it back as a #StreamMessageConverter #Bean as discussed in the stream docs.
After investigation I can make assumption that the behaviour of method message handling is changed because of Spring Cloud Stream's issue and corresponding Spring Framework's issue. There is temporary overriden argument resolvers initialization in Spring Binder auto-configuration (bean definition on static method BinderFactoryConfiguration#messageHandlerMethodFactory).
So first resolver in chain is SmartPayloadArgumentResolver which decides that the conversation is needed. This conversation is started and failed by ApplicationJsonMessageMarshallingConverter. The exception:
org.springframework.messaging.converter.MessageConversionException: Could not read JSON: Unexpected character ('-' (code 45)): Expected space separating root-level values
at [Source: (String)"2019-09-04T01:26:20.202Z[UTC]"; line: 1, column: 6]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('-' (code 45)): Expected space separating root-level values
at [Source: (String)"2019-09-04T01:26:20.202Z[UTC]"; line: 1, column: 6], failedMessage=GenericMessage [payload=2019-09-04T01:26:20.202Z[UTC], headers={spanTraceId=3f87b9afc373308a, spanId=3f87b9afc373308a, nativeHeaders={spanTraceId=[3f87b9afc373308a], spanId=[3f87b9afc373308a], spanSampled=[1]}, X-B3-SpanId=3f87b9afc373308a, X-B3-Sampled=1, X-B3-TraceId=3f87b9afc373308a, id=3fbe87e3-31c4-4d21-c3fb-506c018c0e25, spanSampled=1, timestamp=1567560380202}]
And as result I face error aforementioned in the question thrown from MethodReference.

Interceptor for not existing request mapping with java configuration

I have a configuration class, which extends WebMvcConfigurationSupport and I have added interceptors like this:
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor()).addPathPatterns("/api/**");
}
where myInterceptor() is:
#Bean
public MyInterceptor myInterceptor() {
return new MyInterceptor();
}
and it works fine for any mapping (/api/**) which I have implemented for example /api/sample - preHandle from MyInterceptor is fired (I have a Controller with mapping /api/sample).
When I call not existing resource for example /api/forward/sample preHandle from MyInterceptor is never called.
Please notice it worked as expected when I had the config in xml, like:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/api/**" />
<bean class="my.pack.MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
For some reason with java configuration requests for not existing mappings are not intercepted. Why the configuration is not equivalent? I thought it should be.
EDIT:
A bit more debugging information. With xml configuration DispatcherServlet#handlerMappings contains 5 handlers:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.socket.server.support.WebSocketHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
with Java configuration it contains 7 handlers:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.socket.server.support.WebSocketHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
The problem seems to be with SimpleUrlHandlerMapping (at least it seems to be used for the resource I call - api/forward/sample while for api/sample RequestMappingHandlerMapping is in use) which has empty adoptedIterceptors in the case with Java based configuration.
EDIT 2:
Full source code for sample application (I tried to make it as small as possible just to demonstrate the effect):
https://github.com/szprutamich/spring-demo
In class ConfigurationBase - configuration can be switched from xml based to java based with static field CONFIG.
With xml based config both urls work:
/api/sample
/api/forward/sample
With java based config forward does not work.
Your question is about a "not existing request mapping", but in your XML configuration, it exists :
<default-servlet-handler xmlns="http://www.springframework.org/schema/mvc" />
This declares a default handler for all requests, and a request interceptor ony works if a valid handler is found. Remove this line and you will get the same behavior in both XML and Java configs : no default handler will be found and the interceptor won't work.
So for the interceptor to work on all requests in your Java configuration, you have to declare a default handler. You could override configureDefaultServletHandling but afaik it's not possible to configure interceptors on it. You may have to explicitly map /** in a default handling controller.

Ehcache not cleaning up peer listeners after startup failure

I have a problem where ehcache is not cleaning up its listeners after the app fails to start. Basically after a failed start, it then tries to establish a listener on the remoteObjectPort 40003, and fails due to the port already being in use:
Caused by: java.rmi.server.ExportException: Port already in use: 40003; nested exception is:
java.net.BindException: Address already in use
...
Even though the app is stopped, the listeners are still running on those ports:
[root#server logs]# netstat -tulpn | grep 4000
tcp 0 0 0.0.0.0:40001 0.0.0.0:* LISTEN 14946/java
tcp 0 0 0.0.0.0:40003 0.0.0.0:* LISTEN 14946/java
This is the relevant config in my ehcache.xml file:
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic,
multicastGroupAddress=230.0.0.1,
multicastGroupPort=40002,
timeToLive=64"
/>
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="port=40001,remoteObjectPort=40003,
socketTimeoutMillis=20000"/>
Is there any way to create a #PreDestroy method in my Application.java where I can explicity kill any running ehcache listeners running in the container?
Edit: Here is how I'm initialising EhCache within spring:
#EnableCaching
...
public class Application extends SpringBootServletInitializer implements WebApplicationInitializer {
...
#Bean
public EhCacheCacheManager gdaCacheManager() {
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}
#Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean factory = new EhCacheManagerFactoryBean();
factory.setConfigLocation(new ClassPathResource("cache/ehcache.xml"));
factory.setShared(true);
return factory;
}
I'm also setting the following properties within my hibernate config to enable 2nd level caching with ehcache:
properties.put("hibernate.cache.use_second_level_cache", "true");
properties.put("hibernate.cache.use_query_cache", "true");
properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory");
properties.put("net.sf.ehcache.configurationResourceName", "/cache/ehcache.xml");

Spring Data Elastic search in a Spring Boot application

I have a Spring Boot application and I want to use Elastic search 2.2.0 standalone (not the embedded server) in it, I wanna use Spring Data Elastic search, so what are the Elastic search supported versions by Spring Data and how can I configure it to connect to elasticsearch instance running in localhost:9200?
Actually, I tried adding this options to my application.properties file:
spring.data.elasticsearch.repositories.enabled=true
spring.data.elasticsearch.cluster-nodes=localhost:9200
And later, I created this configuration class:
#Configuration
public class ElasticConfig {
#Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchTemplate(client());
}
#Bean
public Client client() {
TransportClient client = new TransportClient();
TransportAddress address = new InetSocketTransportAddress(
"localhost",9200);
client.addTransportAddress(address);
return client;
}
}
I get this stacktrace:
2016-04-28 00:03:52.246 INFO 25613 --- [ restartedMain]
org.elasticsearch.plugins : [Aardwolf] loaded [], sites
[] 2016-04-28 00:04:01.356 INFO 25613 --- [ restartedMain]
org.elasticsearch.client.transport : [Aardwolf] failed to get
node info for
[#transport#-1][fathi-HP-Pavilion-g6-Notebook-PC][inet[localhost/127.0.0.1:9200]], disconnecting...
org.elasticsearch.transport.ReceiveTimeoutTransportException:
[][inet[localhost/127.0.0.1:9200]][cluster:monitor/nodes/info]
request_id [0] timed out after [5001ms] at
org.elasticsearch.transport.TransportService$TimeoutHandler.run(TransportService.java:529)
~[elasticsearch-1.5.2.jar:na] at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
~[na:1.8.0_77] at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
~[na:1.8.0_77] at java.lang.Thread.run(Thread.java:745)
~[na:1.8.0_77]
2016-04-28 00:04:01.512 ERROR 25613 --- [ restartedMain]
.d.e.r.s.AbstractElasticsearchRepository : failed to load
elasticsearch nodes :
org.elasticsearch.client.transport.NoNodeAvailableException: None of
the configured nodes are available: []
I got this answer from the ES forum and it worked for me:
First, Spring Data Elasticsearch works officially with ES 1.x versions(for me it worked with 1.7.1).
Second, the port used in the configuration must be 9300
I made these changes and it worked pretty perfect.
As Jemli said you will need to use the port 9300.
Also make sure that your elastiscsearch client and server are using the same major version. If you are using elasticsearch 2.x you will need to update spring boot to the latest version ( > 1.4.0.RC1).
Please have a look to this post if you need more information:
http://ignaciosuay.com/how-to-connect-spring-boot-to-elasticsearch-2-x-x/
I read official document.
If use Java Config,please try:
#Configuration
#EnableElasticsearchRepositories(basePackages = "org/springframework/data/elasticsearch/repositories")
static class Config {
#Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
}
}
If use XML, please try:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/data/elasticsearch
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
<elasticsearch:transport-client id="client" cluster-nodes="localhost:9300,someip:9300" />
</beans>
You can read http://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.introduction

Categories