What is the recommended way to make Spring Kafka reload SSL context?
I have a requirement to insert new certificates into the trust store that my Kafka producer uses without any downtime.
However what I have found is that once the application is started and a Kafka producer is created, an instance of SSLContext is created and cached. There is a way to reconfigure this but the only way I have found so far is to destroy any existing producers by invoking the destroy method on DefaultKafkaProducerFactory (after certificate renewal) which causes any subsequent calls to KafkaTemplate.send to force a new producer to be created which in turn reloads the SSL context.
I feel this is like using a sledgehammer to solve this problem and there might be a more elegant solution. I have also noticed that if I call destroy when there are messages being sent, I get the below exception which doesn't look very positive when we cannot afford to lose any events.
java.util.concurrent.CompletionException: org.apache.kafka.common.KafkaException: Producer closed while send in progress
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
at java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1592)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)
at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: org.apache.kafka.common.KafkaException: Producer closed while send in progress
at org.apache.kafka.clients.producer.KafkaProducer.doSend(KafkaProducer.java:826)
at org.apache.kafka.clients.producer.KafkaProducer.send(KafkaProducer.java:803)
at org.springframework.kafka.core.DefaultKafkaProducerFactory$CloseSafeProducer.send(DefaultKafkaProducerFactory.java:444)
at org.springframework.kafka.core.KafkaTemplate.doSend(KafkaTemplate.java:372)
at org.springframework.kafka.core.KafkaTemplate.send(KafkaTemplate.java:190)
at org.springframework.kafka.core.KafkaOperations$send.call(Unknown Source)
at com.example.event.publisher.kafka.KafkaEventPublisher.doPublish(KafkaEventPublisher.groovy:57)
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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:352)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:68)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:177)
at com.example.event.publisher.kafka.KafkaEventPublisher$_publish_closure1.doCall(KafkaEventPublisher.groovy:47)
at com.example.event.publisher.kafka.KafkaEventPublisher$_publish_closure1.doCall(KafkaEventPublisher.groovy)
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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:264)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at groovy.lang.Closure.call(Closure.java:418)
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54)
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124)
at com.sun.proxy.$Proxy103.get(Unknown Source)
at java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1590)
... 6 common frames omitted
Caused by: org.apache.kafka.common.KafkaException: Requested metadata update after close
at org.apache.kafka.clients.Metadata.awaitUpdate(Metadata.java:200)
at org.apache.kafka.clients.producer.KafkaProducer.waitOnMetadata(KafkaProducer.java:938)
at org.apache.kafka.clients.producer.KafkaProducer.doSend(KafkaProducer.java:823)
... 37 common frames omitted
It looks like simply resetting the config for certain values will trigger a rebuild on the SSL engine factory. They even call out file key config that would cause a hot reload.
link
Spring Kafka 2.6.5, Kafka 2.4.1, I use KafkaProducerFactory.reset() instead.
#Autowired
private final KafkaTemplate<String, byte[]> kafkaTemplate;
private void reloadProducer() {
kafkaTemplate.getProducerFactory().reset();
}
Next time send() is called, Spring will recreate a brand spanking new KafkaConsumer with the new certificate.
Related
I am trying to instantiate and sign a protobuf message within a Corda flow; the original transaction is created by a JavaScript client, encoded as base64, and submitted to Corda. The Corda node decodes, signs and forwards to the public network.
The transaction, signing, and approval works fine (it actually executes in the Public Network), but upon returning the result it fails with the attached error.
Is there any mechanism to deserialize the protobuf transaction without breaking the [FiberDeserializationChecker]?
Thank you in advance!
Thu Mar 25 16:43:10 UTC 2021>>> on: java.io.InvalidObjectException: Deserialization via serialization delegate
Serialization trace:
validStart (com.hedera.hashgraph.sdk.TransactionId)
transactionIds (com.hedera.hashgraph.sdk.TokenAssociateTransaction)
associateTxn (net.aochain.corda.nodes.hederaTxn.AssociateTokenFlow)
logic (net.corda.node.services.statemachine.FlowStateMachineImpl)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:144)
at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.read(CompatibleFieldSerializer.java:145)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:813)
at co.paralleluniverse.io.serialization.kryo.ReplaceableObjectKryo.readClassAndObject(ReplaceableObjectKryo.java:112)
at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:134)
at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:40)
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:731)
at co.paralleluniverse.io.serialization.kryo.ReplaceableObjectKryo.readObject(ReplaceableObjectKryo.java:92)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.read(CompatibleFieldSerializer.java:145)
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:731)
at co.paralleluniverse.io.serialization.kryo.ReplaceableObjectKryo.readObject(ReplaceableObjectKryo.java:92)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.read(CompatibleFieldSerializer.java:145)
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:731)
at co.paralleluniverse.io.serialization.kryo.ReplaceableObjectKryo.readObject(ReplaceableObjectKryo.java:92)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:543)
at co.paralleluniverse.fibers.Fiber$FiberSerializer.read(Fiber.java:2156)
at co.paralleluniverse.fibers.Fiber$FiberSerializer.read(Fiber.java:2086)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:813)
at co.paralleluniverse.io.serialization.kryo.ReplaceableObjectKryo.readClassAndObject(ReplaceableObjectKryo.java:112)
at net.corda.nodeapi.internal.serialization.kryo.KryoCheckpointSerializer$deserialize$1$1.invoke(KryoCheckpointSerializer.kt:92)
at net.corda.nodeapi.internal.serialization.kryo.KryoCheckpointSerializer$deserialize$1$1.invoke(KryoCheckpointSerializer.kt:42)
at net.corda.nodeapi.internal.serialization.kryo.KryoStreams.kryoInput(KryoStreams.kt:20)
at net.corda.nodeapi.internal.serialization.kryo.KryoCheckpointSerializer$deserialize$1.invoke(KryoCheckpointSerializer.kt:81)
at net.corda.nodeapi.internal.serialization.kryo.KryoCheckpointSerializer$deserialize$1.invoke(KryoCheckpointSerializer.kt:42)
at net.corda.nodeapi.internal.serialization.kryo.KryoCheckpointSerializer$kryo$1.execute(KryoCheckpointSerializer.kt:70)
at com.esotericsoftware.kryo.pool.KryoPoolQueueImpl.run(KryoPoolQueueImpl.java:58)
at net.corda.nodeapi.internal.serialization.kryo.KryoCheckpointSerializer.kryo(KryoCheckpointSerializer.kt:66)
at net.corda.nodeapi.internal.serialization.kryo.KryoCheckpointSerializer.deserialize(KryoCheckpointSerializer.kt:80)
at net.corda.node.services.statemachine.interceptors.FiberDeserializationChecker$start$2.invoke(FiberDeserializationCheckingInterceptor.kt:103)
at net.corda.node.services.statemachine.interceptors.FiberDeserializationChecker$start$2.invoke(FiberDeserializationCheckingInterceptor.kt:53)
at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)
Caused by: java.lang.RuntimeException: java.io.InvalidObjectException: Deserialization via serialization delegate
at co.paralleluniverse.io.serialization.kryo.ReplaceableObjectKryo.getReplacement(ReplaceableObjectKryo.java:129)
at co.paralleluniverse.io.serialization.kryo.ReplaceableObjectKryo.readReplace(ReplaceableObjectKryo.java:118)
at co.paralleluniverse.io.serialization.kryo.ReplaceableObjectKryo.readObjectOrNull(ReplaceableObjectKryo.java:107)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:132)
... 33 more
Caused by: java.io.InvalidObjectException: Deserialization via serialization delegate
at org.threeten.bp.Instant.readResolve(Instant.java:1176)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at co.paralleluniverse.io.serialization.kryo.ReplaceableObjectKryo.getReplacement(ReplaceableObjectKryo.java:125)
From Matt Nesbit #R3 :
Their flow checkpoint is including objects that aren't kryo (de)serialisable. Most probably they need to hide any statics/native methods behind a SingletonSerialiseAsToken derived object probably held by a CordaService.
That probably includes their protobuf serialiser, but from this little info could be anything, since they appear to be also including Hedera Hashgraph
if you could share some more info or msg me on slack.corda.net I could help with getting you some more info
Matt and David reply send me through the right path.
You have to create a new class as described here. In our case, the deserializer event is included into an API, and that blocks the read from Kyro when the (de)serialization happens.
Thank you both!
I have recently started getting following exception, only when junits are being run. In normal flow, the method runs fine. (In fact even the jUnits used to work fine till some time back)
java.lang.NoSuchMethodException:
io.jsonwebtoken.impl.crypto.MacProvider.generateKey(io.jsonwebtoken.SignatureAlgorithm)
Following is the method:
public static String generateDummyJWT(String userName)
{
return Jwts.builder().claim("user_name", StringUtils.defaultString(userName)).setAudience("client1").signWith(Keys.secretKeyFor(SignatureAlgorithm.HS384)).compact();
}
And jjwt versions:
Following is the complete stack trace:
Caused by: java.lang.IllegalStateException: Unable to invoke class
method io.jsonwebtoken.impl.crypto.MacProvider#generateKey. Ensure
the necessary implementation is in the runtime classpath. at
io.jsonwebtoken.lang.Classes.invokeStatic(Classes.java:202) at
io.jsonwebtoken.security.Keys.secretKeyFor(Keys.java:121) at
com.random.util.ServiceSpecificUtil.generateDummyJWT(ServiceSpecificUtil.java:143)
at
com.random.util.ServiceConstants.(ServiceConstants.java:203)
at com.random.MyClass.isUserBranch(MyClass.java:67) at
com.random.MyClass.validName(MyClass.java:93) at
com.random.MyClass.preConditionCheck(MyClass.java:82) at
com.random.MyClass.get(MyClass.java:46) at
com.random.MyClass2.evaluateExpression(MyClass2.java:218) 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.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl$1.invoke(MockitoMethodInvocationControl.java:243)
at
org.mockito.internal.invocation.realmethod.CleanTraceRealMethod.invoke(CleanTraceRealMethod.java:30)
at
org.mockito.internal.invocation.InvocationImpl.callRealMethod(InvocationImpl.java:112)
at
org.mockito.internal.stubbing.answers.CallsRealMethods.answer(CallsRealMethods.java:41)
at
org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:93)
at
org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:266)
at
org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:192)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:132)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:63) at
com.random.MyClass2.evaluateExpression(MyClass2.java) at
com.random.MyClass2.isPermitted(MyClass2.java:107) 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.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl$1.invoke(MockitoMethodInvocationControl.java:243)
at
org.mockito.internal.invocation.realmethod.CleanTraceRealMethod.invoke(CleanTraceRealMethod.java:30)
at
org.mockito.internal.invocation.InvocationImpl.callRealMethod(InvocationImpl.java:112)
at
org.mockito.internal.stubbing.answers.CallsRealMethods.answer(CallsRealMethods.java:41)
at
org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:93)
at
org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:266)
at
org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:192)
... 32 more Caused by: java.lang.reflect.InvocationTargetException
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
io.jsonwebtoken.lang.Classes.invokeStatic(Classes.java:198) ... 66
more Caused by: java.lang.IllegalStateException: The HmacSHA384
algorithm is not available. This should never happen on JDK 7 or
later - please report this to the JJWT developers. at
io.jsonwebtoken.impl.crypto.MacProvider.generateKey(MacProvider.java:94)
at
io.jsonwebtoken.impl.crypto.MacProvider.generateKey(MacProvider.java:63)
... 71 more Caused by: java.security.NoSuchAlgorithmException:
HmacSHA384 KeyGenerator not available at
javax.crypto.KeyGenerator.(KeyGenerator.java:169) at
javax.crypto.KeyGenerator.getInstance(KeyGenerator.java:223) at
io.jsonwebtoken.impl.crypto.MacProvider.generateKey(MacProvider.java:92)
... 72 more
I was able to resolve my problem.
Someone in the team had added the call to above function while initializing a static final variable like this:
public static String TOKEN_GUEST = ServiceSpecificUtil.generateDummyJWT(USERNAME);
Now, it seems that access to the java.security packges generally does not work well with PowerMock due to heavy use of reflections & byte code manipulations:
Although I had referred this SO post and tried the suggested solution of using
#PowerMockIgnore like:
#PowerMockIgnore({"org.apache.http.conn.ssl.*", "javax.net.ssl.*" , "javax.crypto.*"})
and that might be helpful in preventing errors when above function was called from another function. But it was not preventing errors in static variable initialization.
public static String TOKEN_GUEST = ServiceSpecificUtil.generateDummyJWT(USERNAME);
I will update this post when I dig deeper as to why the error was coming only in case of static variable initialization and not when ServiceSpecificUtil.generateDummyJWT(USERNAME) was being called from another function.
I need to consume a SOAP webservice with two endpoints
Employee
Customer
Both the endpoints have same function "getAddress" which returns list of Strings.
In order to consume the web service, I have used "wsimport" tool to generate the stubs
and apache cxf library, I get an exception
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Fault occurred while processing.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)
at com.sun.proxy.$Proxy39.getAddress(Unknown Source)
at com.testwebservice.Main.main(Main.java:105)
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:144)
Caused by: org.apache.cxf.binding.soap.SoapFault: Fault occurred while processing.
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:75)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:46)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:35)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1656)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1521)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1429)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:659)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
when ever I tried to use the "Employee.getAddress" method
But before, I would like to clarify whether two end points can have a same function name with same return type ?
Could not find any information in the documentation.
about your second question:
you cant have a same function name. actually you cant even have overloading. Because WSDL does not support method overloading(not OOPs). WCF generates WSDL which specifies the location of the service and the operation or methods the service exposes.
please provide more information about your service(Like WSDL file) so we can help you with details.
I'm the new to redis, I start the server about this tutorial. And it work. Then I use write the code using java to connect redis, then it's ok, like this:
Jedis jedis = new Jedis("localhost");
System.out.println("Connection to server sucessfully");
//store data in redis list
jedis.lpush("tutorial-list", "Redis");
jedis.lpush("tutorial-list", "Mongodb");
jedis.lpush("tutorial-list", "Mysql");
But, when I use multithread to push the redis, it will throw the exception "read time out":
Exception in thread "main" java.lang.reflect.InvocationTargetException
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:601) at
org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException:
java.net.SocketTimeoutException: Read timed out at
redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:201)
at
redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
at redis.clients.jedis.Protocol.process(Protocol.java:141) at
redis.clients.jedis.Protocol.read(Protocol.java:205) at
redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297)
at
redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:233)
at redis.clients.jedis.Jedis.keys(Jedis.java:185) at
org.v11.redis_mongo_task.UpdateApp.jobDetail(UpdateApp.java:23) at
org.v11.redis_mongo_task.UpdateApp.main(UpdateApp.java:42) ... 5 more
Caused by: java.net.SocketTimeoutException: Read timed out at
java.net.SocketInputStream.socketRead0(Native Method) at
java.net.SocketInputStream.read(SocketInputStream.java:150) at
java.net.SocketInputStream.read(SocketInputStream.java:121) at
java.net.SocketInputStream.read(SocketInputStream.java:107) at
redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:195)
... 13 more
What happened for redis? why it can work in single thread?
According to this answer, a single Jedis instance is not threadsafe. You will have to use JedisPool for multithreading. You can read here on how use it and here to set the max connections and what will happen if those connections are all occupied.
I'm posting links since two of them are SO answers an they should get the credit and one is from github official repo, so if anything gets updated it should be reflected here too.
I am facing a problem while using the DefaultMessageListenerContainer in Spring JMS with TIBCO queues. When I put a relatively small message on a queue, the listener on the queue takes a few seconds to read the message and complete the procesing and everthing works smoothly. On the other hand, when I put a request on the queue that may take longer to be processed by the business layer, I get the following exception a few minutes after the processing begins.
04:38:14.392 [TIBCO EMS TCPLink Reader (Server-34171)] WARN o.s.j.c.CachingConnectionFactory - Encountered a JMSException - resetting the underlying JMS Connection
javax.jms.JMSException: Connection has been terminated
at com.tibco.tibjms.Tibjmsx.buildException(Tibjmsx.java:509) ~[tibjms.jar:6.3.0]
at com.tibco.tibjms.TibjmsConnection._invokeOnExceptionCallback(TibjmsConnection.java:2025) [tibjms.jar:6.3.0]
at com.tibco.tibjms.TibjmsConnection._onDisconnected(TibjmsConnection.java:2394) [tibjms.jar:6.3.0]
at com.tibco.tibjms.TibjmsConnection$ServerLinkEventHandler.onEventDisconnected(TibjmsConnection.java:349) [tibjms.jar:6.3.0]
at com.tibco.tibjms.TibjmsxLinkTcp$LinkReader.work(TibjmsxLinkTcp.java:330) [tibjms.jar:6.3.0]
at com.tibco.tibjms.TibjmsxLinkTcp$LinkReader.run(TibjmsxLinkTcp.java:259) [tibjms.jar:6.3.0]
The processing continues on the listener side and I get the following exception once the listener has finished processing the message :
07:28:04.281 [jmsContainer-1] WARN o.s.j.l.DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.IllegalStateException: Session is closed
at com.tibco.tibjms.TibjmsxSessionImp.getTransacted(TibjmsxSessionImp.java:4837) ~[tibjms.jar:6.3.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_03]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_03]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_03]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_03]
at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:344) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at $Proxy20.getTransacted(Unknown Source) ~[na:na]
at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:572) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:481) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325) [org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263) [org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1059) [org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1051) [org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:948) [org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at java.lang.Thread.run(Thread.java:722) [na:1.7.0_03]
07:28:04.281 [jmsContainer-1] WARN o.s.j.l.DefaultMessageListenerContainer - Setup of JMS message listener invoker failed for destination 'Queue[cmb.cmbtech.na.bead_153036.rwacalrequest1]' - trying to recover. Cause: Session is closed
javax.jms.IllegalStateException: Session is closed
at com.tibco.tibjms.TibjmsxSessionImp.getTransacted(TibjmsxSessionImp.java:4837) ~[tibjms.jar:6.3.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_03]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_03]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_03]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_03]
at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:344) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at $Proxy20.getTransacted(Unknown Source) ~[na:na]
at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:572) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:481) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1059) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1051) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:948) ~[org.springframework.jms-3.1.0.RELEASE.jar:3.1.0.RELEASE]
at java.lang.Thread.run(Thread.java:722) [na:1.7.0_03]
And finally, a few seconds after the above exception, I get the following info in the logs
07:28:04.418 [jmsContainer-1] INFO o.s.j.l.DefaultMessageListenerContainer - Successfully refreshed JMS Connection
I am not really sure what is causing the probelm but it seems that the jms connection is getting reset whenever the listener takes more than a few minutes to process the message. The side effect of all this is that the listener fails to publish the processing output to another queue for an external application to consume. Do I need to set a transaction manager for my listener or set some kind of property that will not reset the connection for a given duration?