I am facing unknown-host exception for below code. I am not sure what is wrong with code.
#Component
#Configuration
public class RabbitListenerContainerFactory {
static final Logger logger = LoggerFactory.getLogger(RabbitListenerContainerFactory.class);
#Autowired
RabbitMqConfig rabbitMqConfig;
#Autowired
EPPQ2Subscriber receiver;
#Autowired
EPPQ2ChanelAwareSubscriber receiverChanel;
public RabbitListenerContainerFactory(ConfigurableApplicationContext ctx) {
printContainerStartMsg();
}
private void printContainerStartMsg() {
logger.info("----------- Scrubber Container Starts --------------");
}
#Bean
public SimpleMessageListenerContainer queueListenerContainer(ConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
container.setQueueNames(rabbitMqConfig.getSubscriberQueueName());
// container.setQueueNames("SampleQueue"); /*This just for testing.. !*/
container.setMessageListener(listenerAdapter);
container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
container.setDeclarationRetries(5);// This is default to 3, We can twick this and move this to prop
container.setPrefetchCount(100); //Tell the broker how many messages to send to each consumer in a single request.
return container;
}
#Bean
MessageListenerAdapter listenerAdapter(EPPQ2Subscriber receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
/*#Bean
MessageListenerAdapter listenerAdapterWithChanel(EPPQ2ChanelAwareSubscriber receiverChanel) {
return new MessageListenerAdapter(receiverChanel);
}*/
#Bean
ConnectionFactory connectionFactory () {
final CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(Arrays.toString(rabbitMqConfig.getSubscriberHosts()));
//connectionFactory.setHost(Arrays.toString(rabbitMqConfig.getSubscriberHosts()));
connectionFactory.setVirtualHost("hydra.services");
connectionFactory.setPort(rabbitMqConfig.getSubscriberPort());
connectionFactory.setUsername(rabbitMqConfig.getSubscriberUsername());
connectionFactory.setPassword(rabbitMqConfig.getSubscriberPassword());
return connectionFactory;
}
}
I am able to see rabbit running on the host
I can see admin console here http://hostname:15672/
Tel net is working
Telnet hostname 15672
timeout 3 bash -c 'cat < /dev/null > /dev/tcp/hostname/15672 '; echo $?
Here is log :
org.springframework.amqp.AmqpIOException: java.net.UnknownHostException:host-name
Edit 1
public class RabbitMqConfig {
private String [] subscriberHosts;
private int subscriberPort;
private String [] publisherHosts;
private int publisherPort;
private String subscriberUsername;
private String subscriberPassword;
private String publisherUsername;
private String publisherPassword;
private String subscriberQueueName;
private String publisherQueueName;
private String publisherTopic;
private String routingKey;
/**
*
* #return -read queue hosts
*/
public String[] getSubscriberHosts() {
return subscriberHosts;
}
/**
*
* #return -read queue port
*/
public int getSubscriberPort() {
return subscriberPort;
}
/**
*
* #return -write queue hosts
*/
public String[] getPublisherHosts() {
return publisherHosts;
}
/**
*
* #return -write queue port
*/
public int getPublisherPort() {
return publisherPort;
}
/**
*
* #return -Read Queue user name
*/
public String getSubscriberUsername() {
return subscriberUsername;
}
/**
*
* #return Read Queue password
*/
public String getSubscriberPassword() {
return subscriberPassword;
}
/**
*
* #return -Write Queue user name
*/
public String getPublisherUsername() {
return publisherUsername;
}
/**
*
* #return -Write Queue password
*/
public String getPublisherPassword() {
return publisherPassword;
}
/**
*
* #return -Write Queue name
*/
public String getSubscriberQueueName() {
return subscriberQueueName;
}
/**
*
* #return --Read Queue name
*/
public String getPublisherQueueName() {
return publisherQueueName;
}
/**
*
* #return
*/
public String getPublisherTopic() {
return publisherTopic;
}
/**
*
* #return
*/
public String getRoutingKey() {
return routingKey;
}
#PostConstruct
public void getAIMCredentails() {
tempApiCallMock();
}
private void tempApiCallMock() {
String [] host = {"10.30.190.25"};
this.subscriberHosts = host;
this.subscriberPort = 5672;
this.subscriberQueueName = "hydra.Syphon.q1";
this.subscriberUsername = "dftp_subscriber";
this.subscriberPassword = "dftp_subscriber";
this.publisherHosts = host;
this.publisherPort = 5672;
this.publisherUsername = "dftp_publisher";
this.publisherPassword = "dftp_publisher";
}
Thanks for Correcting me I changed the port to 5672 But still the same issue.
and my telnet host 5672 works
The connectionFactory.setAddresses(Arrays.toString(rabbitMqConfig.getSubscriberHosts()));
is wrong. The setAddresses() expects a comma-separate string, not a string representation of the array.
See its JavaDocs:
/**
* Set addresses for clustering.
* This property overrides the host+port properties if not empty.
* #param addresses list of addresses with form "host[:port],..."
*/
public void setAddresses(String addresses) {
Related
I am trying to generate a JSON
Gson gson = new Gson();
String json = gson.toJson(item);
But every time i try to I keep getting a stackoverflow error:
java.lang.StackOverflowError: null
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:968)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:968)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
It is caused when i try to convert DataTableResults class which contains a list of Transactions.class as its property field to a string.
The DataTableResult class looks like this :
public class DataTableResults<T> {
/** The draw. */
private String draw;
/** The records filtered. */
private String recordsFiltered;
/** The records total. */
private String recordsTotal;
/** The list of data objects. */
#SerializedName("data")
List<T> listOfDataObjects;
/**
* Gets the draw.
*
* #return the draw
*/
public String getDraw() {
return draw;
}
/**
* Sets the draw.
*
* #param draw the draw to set
*/
public void setDraw(String draw) {
this.draw = draw;
}
/**
* Gets the records filtered.
*
* #return the recordsFiltered
*/
public String getRecordsFiltered() {
return recordsFiltered;
}
/**
* Sets the records filtered.
*
* #param recordsFiltered the recordsFiltered to set
*/
public void setRecordsFiltered(String recordsFiltered) {
this.recordsFiltered = recordsFiltered;
}
/**
* Gets the records total.
*
* #return the recordsTotal
*/
public String getRecordsTotal() {
return recordsTotal;
}
/**
* Sets the records total.
*
* #param recordsTotal the recordsTotal to set
*/
public void setRecordsTotal(String recordsTotal) {
this.recordsTotal = recordsTotal;
}
/**
* Gets the list of data objects.
*
* #return the listOfDataObjects
*/
public List<T> getListOfDataObjects() {
return listOfDataObjects;
}
/**
* Sets the list of data objects.
*
* #param listOfDataObjects the listOfDataObjects to set
*/
public void setListOfDataObjects(List<T> listOfDataObjects) {
this.listOfDataObjects = listOfDataObjects;
}
}
while the Transactions.class looks like this
#Entity
#Table(name = "TRANS")
public class Transactions extends DefaultEntity {
public enum TRANSACTIONTYPE{WITHDRAW, DEPOSIT, WIN, LOSS}
#ManyToOne(targetEntity = User.class)
#JoinColumn(name="player")
private User player;
private double amount;
#Enumerated(EnumType.STRING)
private TRANSACTIONTYPE transactiontype;
private String referenceID;
private String detail;
private String token;
public TRANSACTIONTYPE getTransactiontype() {
return transactiontype;
}
public Transactions setTransactiontype(TRANSACTIONTYPE transactiontype) {
this.transactiontype = transactiontype;
return this;
}
public double getAmount() {
return amount;
}
public Transactions setAmount(double amount) {
this.amount = amount;
return this;
}
public String getReferenceID() {
return referenceID;
}
public Transactions setReferenceID(String referenceID) {
this.referenceID = referenceID;
return this;
}
public String getDetail() {
return detail;
}
public Transactions setDetail(String detail) {
this.detail = detail;
return this;
}
public String getToken() {
return token;
}
public Transactions setToken(String token) {
this.token = token;
return this;
}
public User getPlayer() {
return player;
}
public Transactions setPlayer(User player) {
this.player = player;
return this;
}
}
according to this post, it is supposed to be caused by a circular dependency, but in my case it is not cause i dont have one. What else could cause such error ?
You should remove extends DefaultEntity, you don't need it and may bring circular dependency.
Also you have a #ManyToOne relationship with User, that may cause circular dependency if User also have a reference to Transactions.
If you have it in both parts, you should exclude it from serialization with transient on one part at least.
I am after sending/receiving call to JMS queue synchronously using JMS Template and Spring boot. I went through official spring doc for JMS template but of no help.
I am not too sure about calling receive() method specifically or it will automatically receive message once send() is invoked. Since this is synchronous call I only need to receive message that I've sent (with the correlation Id).
Any help in this regard would be appreciated. Please let me know if you need any further info.
Update!!
Below is my spring boot code.
JMSSConfig.java
#Configuration
#EnableJms
public class JMSConfig {
#Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
// This provides all boot's default to this factory, including the message converter
configurer.configure(factory, connectionFactory);
// You could still override some of Boot's default if necessary.
return factory;
}
#Bean
public MarshallingMessageConverter createMarshallingMessageConverter(final Jaxb2Marshaller jaxb2Marshaller) {
System.out.println("executing createMarshallingMessageConverter");
return new MarshallingMessageConverter(jaxb2Marshaller);
}
#Bean
public Jaxb2Marshaller createJaxb2Marshaller(#Value("${context.path}") final String contextPath, #Value("${schema.location}") final String schemaLocaation) {
System.out.println("executing Jaxb2Marshaller");
Resource schemaResource = new ClassPathResource(schemaLocaation);
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath(contextPath);
jaxb2Marshaller.setSchema(schemaResource);
Map<String, Object> properties = new HashMap<>();
properties.put(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxb2Marshaller.setMarshallerProperties(properties);
return jaxb2Marshaller;
}
}
Sender and receiver code
#Component
public class Receiver {
#Autowired
JmsTemplate jmsTemplate;
#JmsListener(destination = "mailbox", containerFactory="myFactory")
public void receiveMessage(CacheMsgType submitEventType) {
System.out.println("Received <" + submitEventType + ">");
}
public void send(CacheMsgType submitEventType) {
jmsTemplate.convertAndSend("mailbox", submitEventType);
System.out.println("Successfully sent a message.");
}
}
JAXB Generated classes
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "SubmitEventType", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", propOrder = {
"eventType",
"clientApplication",
"clientReferenceID",
"systemDate",
"transactionAcceptTime",
"bsb",
"accountNumber",
"productcode",
"accttypecode",
"trancode",
"meid",
"baiCode",
"baiDecs",
"tranamount",
"amountonhold",
"recordedlimit",
"currentbalance",
"availablebalance",
"description",
"reference",
"payer"
})
public class SubmitEventType {
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String eventType;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String clientApplication;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String clientReferenceID;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String systemDate;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String transactionAcceptTime;
#XmlElement(name = "BSB", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String bsb;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String accountNumber;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String productcode;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String accttypecode;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String trancode;
#XmlElement(name = "MEID", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String meid;
#XmlElement(name = "BAICode", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String baiCode;
#XmlElement(name = "BAIDecs", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String baiDecs;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String tranamount;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String amountonhold;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String recordedlimit;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String currentbalance;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String availablebalance;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String description;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String reference;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String payer;
/**
* Gets the value of the eventType property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getEventType() {
return eventType;
}
/**
* Sets the value of the eventType property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setEventType(String value) {
this.eventType = value;
}
/**
* Gets the value of the clientApplication property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getClientApplication() {
return clientApplication;
}
/**
* Sets the value of the clientApplication property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setClientApplication(String value) {
this.clientApplication = value;
}
/**
* Gets the value of the clientReferenceID property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getClientReferenceID() {
return clientReferenceID;
}
/**
* Sets the value of the clientReferenceID property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setClientReferenceID(String value) {
this.clientReferenceID = value;
}
/**
* Gets the value of the systemDate property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getSystemDate() {
return systemDate;
}
/**
* Sets the value of the systemDate property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setSystemDate(String value) {
this.systemDate = value;
}
/**
* Gets the value of the transactionAcceptTime property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTransactionAcceptTime() {
return transactionAcceptTime;
}
/**
* Sets the value of the transactionAcceptTime property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTransactionAcceptTime(String value) {
this.transactionAcceptTime = value;
}
/**
* Gets the value of the bsb property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getBSB() {
return bsb;
}
/**
* Sets the value of the bsb property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setBSB(String value) {
this.bsb = value;
}
/**
* Gets the value of the accountNumber property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getAccountNumber() {
return accountNumber;
}
/**
* Sets the value of the accountNumber property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setAccountNumber(String value) {
this.accountNumber = value;
}
/**
* Gets the value of the productcode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getProductcode() {
return productcode;
}
/**
* Sets the value of the productcode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setProductcode(String value) {
this.productcode = value;
}
/**
* Gets the value of the accttypecode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getAccttypecode() {
return accttypecode;
}
/**
* Sets the value of the accttypecode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setAccttypecode(String value) {
this.accttypecode = value;
}
/**
* Gets the value of the trancode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTrancode() {
return trancode;
}
/**
* Sets the value of the trancode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTrancode(String value) {
this.trancode = value;
}
/**
* Gets the value of the meid property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getMEID() {
return meid;
}
/**
* Sets the value of the meid property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setMEID(String value) {
this.meid = value;
}
/**
* Gets the value of the baiCode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getBAICode() {
return baiCode;
}
/**
* Sets the value of the baiCode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setBAICode(String value) {
this.baiCode = value;
}
/**
* Gets the value of the baiDecs property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getBAIDecs() {
return baiDecs;
}
/**
* Sets the value of the baiDecs property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setBAIDecs(String value) {
this.baiDecs = value;
}
/**
* Gets the value of the tranamount property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTranamount() {
return tranamount;
}
/**
* Sets the value of the tranamount property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTranamount(String value) {
this.tranamount = value;
}
/**
* Gets the value of the amountonhold property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getAmountonhold() {
return amountonhold;
}
/**
* Sets the value of the amountonhold property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setAmountonhold(String value) {
this.amountonhold = value;
}
/**
* Gets the value of the recordedlimit property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getRecordedlimit() {
return recordedlimit;
}
/**
* Sets the value of the recordedlimit property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setRecordedlimit(String value) {
this.recordedlimit = value;
}
/**
* Gets the value of the currentbalance property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getCurrentbalance() {
return currentbalance;
}
/**
* Sets the value of the currentbalance property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setCurrentbalance(String value) {
this.currentbalance = value;
}
/**
* Gets the value of the availablebalance property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getAvailablebalance() {
return availablebalance;
}
/**
* Sets the value of the availablebalance property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setAvailablebalance(String value) {
this.availablebalance = value;
}
/**
* Gets the value of the description property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getDescription() {
return description;
}
/**
* Sets the value of the description property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setDescription(String value) {
this.description = value;
}
public String getReference() {
return reference;
}
public void setReference(String value) {
this.reference = value;
}
public String getPayer() {
return payer;
}
public void setPayer(String value) {
this.payer = value;
}
}
CashMsgType.java
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "CacheMsg", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "CacheMsgType", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", propOrder = {
"submitEvent"
})
public class CacheMsgType {
#XmlElement(name = "SubmitEvent", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected List<SubmitEventType> submitEvent;
public List<SubmitEventType> getSubmitEvent() {
if (submitEvent == null) {
submitEvent = new ArrayList<SubmitEventType>();
}
return this.submitEvent;
}
}
It seems sending on to mailbox queue is working but receiving gives error
Exception
2018-05-05 10:44:53.280 WARN 4120 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer : Execution of JMS message listener failed, and no ErrorHandler has been set.
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method could not be invoked with incoming message
Endpoint handler details:
Method [public void com.nab.services.mq.Receiver.receiveMessage(com.nab.services.dto.CacheMsgType)]
Bean [com.nab.services.mq.Receiver#134bfc8]
; nested exception is org.springframework.messaging.converter.MessageConversionException: Cannot convert from [javax.xml.bind.JAXBElement] to [com.nab.services.dto.CacheMsgType] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage#3621aa, failedMessage=org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage#3621aa
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:118) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:77) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1179) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1076) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_162]
Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [javax.xml.bind.JAXBElement] to [com.nab.services.dto.CacheMsgType] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage#3621aa
at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:144) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:116) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:137) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:109) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:114) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 10 common frames omitted
This might be implementation specific, but once the message is sent, you should be able to read the message id from the message itself.
I am writing an application that has a cron job that executes every 60 seconds. The application is configured to scale when required onto multiple instances. I only want to execute the task on 1 instance every 60 seconds (On any node). Out of the box I can not find a solution to this and I am surprised it has not been asked multiple times before. I am using Spring 4.1.6.
<task:scheduled-tasks>
<task:scheduled ref="beanName" method="execute" cron="0/60 * * * * *"/>
</task:scheduled-tasks>
There is a ShedLock project that serves exactly this purpose. You just annotate tasks which should be locked when executed
#Scheduled( ... )
#SchedulerLock(name = "scheduledTaskName")
public void scheduledTask() {
// do something
}
Configure Spring and a LockProvider
#Configuration
#EnableScheduling
#EnableSchedulerLock(defaultLockAtMostFor = "10m")
class MySpringConfiguration {
...
#Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
}
...
}
I think you have to use Quartz Clustering with JDBC-JobStore for this purpose
The is another simple and robust way to safe execute a job in a cluster. You can based on database and execute the task only if the node is the "leader" in the cluster.
Also when a node is failed or shutdown in the cluster another node became the leader.
All you have is to create a "leader election" mechanism and every time to check if your are the leader:
#Scheduled(cron = "*/30 * * * * *")
public void executeFailedEmailTasks() {
if (checkIfLeader()) {
final List<EmailTask> list = emailTaskService.getFailedEmailTasks();
for (EmailTask emailTask : list) {
dispatchService.sendEmail(emailTask);
}
}
}
Follow those steps:
1.Define the object and table that holds one entry per node in the cluster:
#Entity(name = "SYS_NODE")
public class SystemNode {
/** The id. */
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/** The name. */
#Column(name = "TIMESTAMP")
private String timestamp;
/** The ip. */
#Column(name = "IP")
private String ip;
/** The last ping. */
#Column(name = "LAST_PING")
private Date lastPing;
/** The last ping. */
#Column(name = "CREATED_AT")
private Date createdAt = new Date();
/** The last ping. */
#Column(name = "IS_LEADER")
private Boolean isLeader = Boolean.FALSE;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(final String timestamp) {
this.timestamp = timestamp;
}
public String getIp() {
return ip;
}
public void setIp(final String ip) {
this.ip = ip;
}
public Date getLastPing() {
return lastPing;
}
public void setLastPing(final Date lastPing) {
this.lastPing = lastPing;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(final Date createdAt) {
this.createdAt = createdAt;
}
public Boolean getIsLeader() {
return isLeader;
}
public void setIsLeader(final Boolean isLeader) {
this.isLeader = isLeader;
}
#Override
public String toString() {
return "SystemNode{" +
"id=" + id +
", timestamp='" + timestamp + '\'' +
", ip='" + ip + '\'' +
", lastPing=" + lastPing +
", createdAt=" + createdAt +
", isLeader=" + isLeader +
'}';
}
}
2.Create the service that a) insert the node in database , b) check for leader
#Service
#Transactional
public class SystemNodeServiceImpl implements SystemNodeService, ApplicationListener {
/** The logger. */
private static final Logger LOGGER = Logger.getLogger(SystemNodeService.class);
/** The constant NO_ALIVE_NODES. */
private static final String NO_ALIVE_NODES = "Not alive nodes found in list {0}";
/** The ip. */
private String ip;
/** The system service. */
private SystemService systemService;
/** The system node repository. */
private SystemNodeRepository systemNodeRepository;
#Autowired
public void setSystemService(final SystemService systemService) {
this.systemService = systemService;
}
#Autowired
public void setSystemNodeRepository(final SystemNodeRepository systemNodeRepository) {
this.systemNodeRepository = systemNodeRepository;
}
#Override
public void pingNode() {
final SystemNode node = systemNodeRepository.findByIp(ip);
if (node == null) {
createNode();
} else {
updateNode(node);
}
}
#Override
public void checkLeaderShip() {
final List<SystemNode> allList = systemNodeRepository.findAll();
final List<SystemNode> aliveList = filterAliveNodes(allList);
SystemNode leader = findLeader(allList);
if (leader != null && aliveList.contains(leader)) {
setLeaderFlag(allList, Boolean.FALSE);
leader.setIsLeader(Boolean.TRUE);
systemNodeRepository.save(allList);
} else {
final SystemNode node = findMinNode(aliveList);
setLeaderFlag(allList, Boolean.FALSE);
node.setIsLeader(Boolean.TRUE);
systemNodeRepository.save(allList);
}
}
/**
* Returns the leaded
* #param list
* the list
* #return the leader
*/
private SystemNode findLeader(final List<SystemNode> list) {
for (SystemNode systemNode : list) {
if (systemNode.getIsLeader()) {
return systemNode;
}
}
return null;
}
#Override
public boolean isLeader() {
final SystemNode node = systemNodeRepository.findByIp(ip);
return node != null && node.getIsLeader();
}
#Override
public void onApplicationEvent(final ApplicationEvent applicationEvent) {
try {
ip = InetAddress.getLocalHost().getHostAddress();
} catch (Exception e) {
throw new RuntimeException(e);
}
if (applicationEvent instanceof ContextRefreshedEvent) {
pingNode();
}
}
/**
* Creates the node
*/
private void createNode() {
final SystemNode node = new SystemNode();
node.setIp(ip);
node.setTimestamp(String.valueOf(System.currentTimeMillis()));
node.setCreatedAt(new Date());
node.setLastPing(new Date());
node.setIsLeader(CollectionUtils.isEmpty(systemNodeRepository.findAll()));
systemNodeRepository.save(node);
}
/**
* Updates the node
*/
private void updateNode(final SystemNode node) {
node.setLastPing(new Date());
systemNodeRepository.save(node);
}
/**
* Returns the alive nodes.
*
* #param list
* the list
* #return the alive nodes
*/
private List<SystemNode> filterAliveNodes(final List<SystemNode> list) {
int timeout = systemService.getSetting(SettingEnum.SYSTEM_CONFIGURATION_SYSTEM_NODE_ALIVE_TIMEOUT, Integer.class);
final List<SystemNode> finalList = new LinkedList<>();
for (SystemNode systemNode : list) {
if (!DateUtils.hasExpired(systemNode.getLastPing(), timeout)) {
finalList.add(systemNode);
}
}
if (CollectionUtils.isEmpty(finalList)) {
LOGGER.warn(MessageFormat.format(NO_ALIVE_NODES, list));
throw new RuntimeException(MessageFormat.format(NO_ALIVE_NODES, list));
}
return finalList;
}
/**
* Finds the min name node.
*
* #param list
* the list
* #return the min node
*/
private SystemNode findMinNode(final List<SystemNode> list) {
SystemNode min = list.get(0);
for (SystemNode systemNode : list) {
if (systemNode.getTimestamp().compareTo(min.getTimestamp()) < -1) {
min = systemNode;
}
}
return min;
}
/**
* Sets the leader flag.
*
* #param list
* the list
* #param value
* the value
*/
private void setLeaderFlag(final List<SystemNode> list, final Boolean value) {
for (SystemNode systemNode : list) {
systemNode.setIsLeader(value);
}
}
}
3.ping the database to send that your are alive
#Override
#Scheduled(cron = "0 0/5 * * * ?")
public void executeSystemNodePing() {
systemNodeService.pingNode();
}
#Override
#Scheduled(cron = "0 0/10 * * * ?")
public void executeLeaderResolution() {
systemNodeService.checkLeaderShip();
}
4.you are ready! Just check if you are the leader before execute the task:
#Override
#Scheduled(cron = "*/30 * * * * *")
public void executeFailedEmailTasks() {
if (checkIfLeader()) {
final List<EmailTask> list = emailTaskService.getFailedEmailTasks();
for (EmailTask emailTask : list) {
dispatchService.sendEmail(emailTask);
}
}
}
Batch and scheduled jobs are typically run on their own standalone servers, away from customer facing apps so it is not a common requirement to include a job in an application that is expected to run on a cluster. Additionally, jobs in clustered environments typically do not need to worry about other instances of the same job running in parallel so another reason why isolation of job instances is not a big requirement.
A simple solution would be to configure your jobs inside a Spring Profile. For example, if your current configuration is:
<beans>
<bean id="someBean" .../>
<task:scheduled-tasks>
<task:scheduled ref="someBean" method="execute" cron="0/60 * * * * *"/>
</task:scheduled-tasks>
</beans>
change it to:
<beans>
<beans profile="scheduled">
<bean id="someBean" .../>
<task:scheduled-tasks>
<task:scheduled ref="someBean" method="execute" cron="0/60 * * * * *"/>
</task:scheduled-tasks>
</beans>
</beans>
Then, launch your application on just one machine with the scheduled profile activated (-Dspring.profiles.active=scheduled).
If the primary server becomes unavailable for some reason, just launch another server with the profile enabled and things will continue to work just fine.
Things change if you want automatic failover for the jobs as well. Then, you will need to keep the job running on all servers and check synchronization through a common resource such as a database table, a clustered cache, a JMX variable, etc.
I'm using a database table to do the locking. Only one task at a time can do a insert to the table. The other one will get a DuplicateKeyException.
The insert and delete logic is handeld by an aspect around the #Scheduled annotation.
I'm using Spring Boot 2.0
#Component
#Aspect
public class SchedulerLock {
private static final Logger LOGGER = LoggerFactory.getLogger(SchedulerLock.class);
#Autowired
private JdbcTemplate jdbcTemplate;
#Around("execution(#org.springframework.scheduling.annotation.Scheduled * *(..))")
public Object lockTask(ProceedingJoinPoint joinPoint) throws Throwable {
String jobSignature = joinPoint.getSignature().toString();
try {
jdbcTemplate.update("INSERT INTO scheduler_lock (signature, date) VALUES (?, ?)", new Object[] {jobSignature, new Date()});
Object proceed = joinPoint.proceed();
jdbcTemplate.update("DELETE FROM scheduler_lock WHERE lock_signature = ?", new Object[] {jobSignature});
return proceed;
}catch (DuplicateKeyException e) {
LOGGER.warn("Job is currently locked: "+jobSignature);
return null;
}
}
}
#Component
public class EveryTenSecondJob {
#Scheduled(cron = "0/10 * * * * *")
public void taskExecution() {
System.out.println("Hello World");
}
}
CREATE TABLE scheduler_lock(
signature varchar(255) NOT NULL,
date datetime DEFAULT NULL,
PRIMARY KEY(signature)
);
dlock is designed to run tasks only once by using database indexes and constraints. You can simply do something like below.
#Scheduled(cron = "30 30 3 * * *")
#TryLock(name = "executeMyTask", owner = SERVER_NAME, lockFor = THREE_MINUTES)
public void execute() {
}
See the article about using it.
You can use Zookeeper here to elect master instance and master instance will only run the scheduled job.
One implementation here is with Aspect and Apache Curator
#SpringBootApplication
#EnableScheduling
public class Application {
private static final int PORT = 2181;
#Bean
public CuratorFramework curatorFramework() {
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:" + PORT, new ExponentialBackoffRetry(1000, 3));
client.start();
return client;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Aspect class
#Aspect
#Component
public class LeaderAspect implements LeaderLatchListener{
private static final Logger log = LoggerFactory.getLogger(LeaderAspect.class);
private static final String ELECTION_ROOT = "/election";
private volatile boolean isLeader = false;
#Autowired
public LeaderAspect(CuratorFramework client) throws Exception {
LeaderLatch ll = new LeaderLatch(client , ELECTION_ROOT);
ll.addListener(this);
ll.start();
}
#Override
public void isLeader() {
isLeader = true;
log.info("Leadership granted.");
}
#Override
public void notLeader() {
isLeader = false;
log.info("Leadership revoked.");
}
#Around("#annotation(com.example.apache.curator.annotation.LeaderOnly)")
public void onlyExecuteForLeader(ProceedingJoinPoint joinPoint) {
if (!isLeader) {
log.debug("I'm not leader, skip leader-only tasks.");
return;
}
try {
log.debug("I'm leader, execute leader-only tasks.");
joinPoint.proceed();
} catch (Throwable ex) {
log.error(ex.getMessage());
}
}
}
LeaderOnlyAnnotation
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#Documented
public #interface LeaderOnly {
}
Scheduled Task
#Component
public class HelloWorld {
private static final Logger log = LoggerFactory.getLogger(HelloWorld.class);
#LeaderOnly
#Scheduled(fixedRate = 1000L)
public void sayHello() {
log.info("Hello, world!");
}
}
I am using a different approach without need to setup a database for managing the lock between the nodes.
The component is called FencedLock and is provided by Hazelcast.
We're using it to prevent another node to make some operation (not necessarily linked to schedule) but it could also be used for sharing a locks between nodes for a schedule.
For doing this, we just set up two functions helper that can create different lock names:
#Scheduled(cron = "${cron.expression}")
public void executeMyScheduler(){
// This can also be a member of the class.
HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance();
Lock lock = hazelcastInstance.getCPSubsystem().getLock("mySchedulerName");
lock.lock();
try {
// do your schedule tasks here
} finally {
// don't forget to release lock whatever happens: end of task or any exceptions.
lock.unlock();
}
}
Alternatively you can also release automatically the lock after a delay: let say your cron job is running every hour, you can setup an automatic release after e.g. 50 minutes like this:
#Scheduled(cron = "${cron.expression}")
public void executeMyScheduler(){
// This can also be a member of the class.
HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance();
Lock lock = hazelcastInstance.getCPSubsystem().getLock("mySchedulerName");
if ( lock.tryLock ( 50, TimeUnit.MINUTES ) ) {
try {
// do your schedule tasks here
} finally {
// don't forget to release lock whatever happens: end of task or any exceptions.
lock.unlock();
}
} else {
// warning: lock has been released by timeout!
}
}
Note that this Hazelcast component works very good in a cloud based environment (e.g. k8s clusters) and without need to pay for an extra database.
Here is what you need to configure:
// We need to specify the name otherwise it can conflict with internal Hazelcast beans
#Bean("hazelcastInstance")
public HazelcastInstance hazelcastInstance() {
Config config = new Config();
config.setClusterName(hazelcastProperties.getGroup().getName());
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setPortAutoIncrement(false);
networkConfig.getJoin().getKubernetesConfig().setEnabled(hazelcastProperties.isNetworkEnabled())
.setProperty("service-dns", hazelcastProperties.getServiceDNS())
.setProperty("service-port", hazelcastProperties.getServicePort().toString());
config.setProperty("hazelcast.metrics.enabled", "false");
networkConfig.getJoin().getMulticastConfig().setEnabled(false);
return Hazelcast.newHazelcastInstance(config);
}
The HazelcastProperties being the ConfigurationProperties object mapped with the properties.
For local testing you can just disable the network config by using the properties in your local profile:
hazelcast:
network-enabled: false
service-port: 5701
group:
name: your-hazelcast-group-name
You could use an embeddable scheduler like db-scheduler to accomplish this. It has persistent executions and uses a simple optimistic locking mechanism to guarantee execution by a single node.
Example code for how the use-case can be achieved:
RecurringTask<Void> recurring1 = Tasks.recurring("my-task-name", FixedDelay.of(Duration.ofSeconds(60)))
.execute((taskInstance, executionContext) -> {
System.out.println("Executing " + taskInstance.getTaskAndInstance());
});
final Scheduler scheduler = Scheduler
.create(dataSource)
.startTasks(recurring1)
.build();
scheduler.start();
I am using an free HTTP service called kJob-Manager. https://kjob-manager.ciesielski-systems.de/
Advantage is that you dont create a new table in your database and also dont need any database connection because it is just a HTTP request.
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import org.apache.tomcat.util.json.JSONParser;
import org.apache.tomcat.util.json.ParseException;
import org.junit.jupiter.api.Test;
public class KJobManagerTest {
#Test
public void example() throws IOException, ParseException {
String data = "{\"token\":\"<API-Token>\"}";
URL url = new URL("https://kjob-manager.ciesielski-systems.de/api/ticket/<JOB-ID>");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.getOutputStream().write(data.getBytes(StandardCharsets.UTF_8));
JSONParser jsonParser = new JSONParser(connection.getInputStream());
LinkedHashMap<String, LinkedHashMap<String, Object>> result = (LinkedHashMap<String, LinkedHashMap<String, Object>>) jsonParser.parse();
if ((boolean) result.get("ticket").get("open")) {
System.out.println("This replica could run the cronjob!");
} else {
System.out.println("This replica has nothing to do!");
}
}
}
Spring context is not clustered so manage the task in distributed application is a little bit difficult and you need to use systems supporting jgroup to synchronis the state and let your task take the priority to execute the action. Or you could use ejb context to manage clustered ha singleton service like jboss ha environment
https://developers.redhat.com/quickstarts/eap/cluster-ha-singleton/?referrer=jbd
Or you could use clustered cache and access lock resource between the service and first service take the lock will beform the action or implement you own jgroup to communicat your service and perform the action one one node
I have tried multiple ways to call stored function in hibernate---
1) Via Session.doWork callback method
session.doWork(new Work() {
#Override
public void execute(Connection conn)
throws SQLException {
CallableStatement stmt = conn.prepareCall("{? = call test(?)}");
stmt.registerOutParameter(1, Types.INTEGER);
stmt.setString(2, "callIndex");
stmt.execute();
eventVal = stmt.getInt(1);
}
});
This works fine but cannot return any thing from here, so doesn't solve my purpose.
2) Via Native query
StringBuilder query = new StringBuilder();
query.append("Select test() from dual");
SQLQuery sqlQuery = session.createSQLQuery(query.toString());
List resultList = sqlQuery.list();
events = new ArrayList<Events>();
Object result = null;
if (events != null && !events.isEmpty()) {
for (int i = 0; i < events.size(); i++) {
result = resultList.get(i);
}
}
This doesn't work and gives me some No Dialect mapping for JDBC type -10, not sure of the reason.
3) Via named query
My entity class is ---
#NamedNativeQueries({
#NamedNativeQuery(name = "testCall",
query = "? = call test()",
hints = {#QueryHint(name = "org.hibernate.callable", value = "true" )},
resultClass = Events.class
)
})
#Entity
#Table(name = "EVENTS")
public class Events implements Serializable {
private static final long serialVersionUID = -24850323296832289L;
/** The id. */
#Id
#Column(name = "EVENT_SID")
private Integer eventId;
/** The processed status. */
#Column(name = "EVENT_STATUS")
private String eventStatus;
/** The event type. */
#Column(name = "EVENT_TYPE_NAME")
private String eventType;
/** The live event. */
#Column(name = "IS_LIVE_EVENT")
private Integer liveEvent;
/** The event message. */
#Lob
#Column(name = "EVENT_MESSAGE")
private String eventMessage;
public Integer getEventId() {
return eventId;
}
public void setEventId(Integer eventId) {
this.eventId = eventId;
}
public String getEventStatus() {
return eventStatus;
}
public void setEventStatus(String eventStatus) {
this.eventStatus = eventStatus;
}
/**
* Gets the event type.
*
* #return the event type
*/
public String getEventType() {
return eventType;
}
/**
* Sets the event type.
*
* #param eventType
* the new event type
*/
public void setEventType(String eventType) {
this.eventType = eventType;
}
/**
* Gets the live event.
*
* #return the live event
*/
public Integer getLiveEvent() {
return liveEvent;
}
/**
* Sets the live event.
*
* #param liveEvent
* the new live event
*/
public void setLiveEvent(Integer liveEvent) {
this.liveEvent = liveEvent;
}
/**
* Gets the event message.
*
* #return the event message
*/
public String getEventMessage() {
return eventMessage;
}
/**
* Sets the event message.
*
* #param eventMessage
* the new event message
*/
public void setEventMessage(String eventMessage) {
this.eventMessage = eventMessage;
}
}
The DAO through which I am making call have method ---
public Integer callSqlBlock(){
int event = 0;
Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
List<Events> events = null;
events = session.getNamedQuery("testCall").list();
return events.get(0).getEventId();
}
stored function on the DB end ---
create or replace
function test return SYS_REFCURSOR
as
p_order_recordset SYS_REFCURSOR;
begin
open p_order_recordset FOR SELECT EVENT_SID,EVENT_STATUS,EVENT_TYPE_NAME,IS_LIVE_EVENT FROM events;
return p_order_recordset;
end ;
execution of stored function via named query is giving me invalid column index
Please let me know where I am going wrong on this, and if possible please provide some example also
I am using Redis installed on Windows via chocolatey and setup jedis and JOhm in java project. The Redis server is live Redis version 2.6 When I want to save a Java object like the one in the post I got an error message.
java.lang.NoSuchMethodError: redis.clients.jedis.Jedis.sadd(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Long;
at redis.clients.johm.Nest.sadd(Nest.java:168)
at redis.clients.johm.JOhm.save(JOhm.java:220)
at redis.clients.johm.JOhm.save(JOhm.java:146)
This is my java object:
/**
*
*/
package com.smsgh.unitysmpp.MessageProcessor;
import java.io.Serializable;
import org.joda.time.DateTime;
import redis.clients.johm.Attribute;
import redis.clients.johm.Id;
import redis.clients.johm.Model;
/**
* #author Arsene Tochemey GANDOTE This class holds the Messages that needs a
* Delivery Receipt
*/
#Model
public class StoredShortMessage implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6185862961624213864L;
#Id
private Integer id;
// session Id
#Attribute
private Long smppSessionId;
// Message Id
#Attribute
private String messageId;
// ESME Account Number#
#Attribute
private Long accountNumber;
// ESME Account Id
#Attribute
private String accountId;
// ESME API Pub Key
#Attribute
private String apiPublicKey;
// Message state
#Attribute
private String messageState;
// Network Error
#Attribute
private String networkErrorCode;
// First 20 Characters of the message
#Attribute
private String mesgFirstLines;
// esme TCP/IP connection
#Attribute
private String ip;
// message submitted datetime
#Attribute
private DateTime submitDate;
// final state date
#Attribute
private DateTime doneDate;
// source address
#Attribute
private byte srcTon;
#Attribute
private byte srcNpi;
#Attribute
private String srcAddr;
// destination address
#Attribute
private byte destTon;
#Attribute
private byte destNpi;
#Attribute
private String destAddr;
// delivery state
#Attribute
private char dlrState;
/**
*
*/
public StoredShortMessage() {
}
/**
* #return the smppSessionId
*/
public Long getSmppSessionId() {
return smppSessionId;
}
/**
* #param smppSessionId
* the smppSessionId to set
*/
public void setSmppSessionId(Long smppSessionId) {
this.smppSessionId = smppSessionId;
}
/**
* #return the messageId
*/
public String getMessageId() {
return messageId;
}
/**
* #param messageId
* the messageId to set
*/
public void setMessageId(String messageId) {
this.messageId = messageId;
}
/**
* #return the accountNumber
*/
public Long getAccountNumber() {
return accountNumber;
}
/**
* #param accountNumber
* the accountNumber to set
*/
public void setAccountNumber(Long accountNumber) {
this.accountNumber = accountNumber;
}
/**
* #return the accountId
*/
public String getAccountId() {
return accountId;
}
/**
* #param accountId
* the accountId to set
*/
public void setAccountId(String accountId) {
this.accountId = accountId;
}
/**
* #return the apiPublicKey
*/
public String getApiPublicKey() {
return apiPublicKey;
}
/**
* #param apiPublicKey
* the apiPublicKey to set
*/
public void setApiPublicKey(String apiPublicKey) {
this.apiPublicKey = apiPublicKey;
}
/**
* #return the messageState
*/
public String getMessageState() {
return messageState;
}
/**
* #param messageState
* the messageState to set
*/
public void setMessageState(String messageState) {
this.messageState = messageState;
}
/**
* #return the networkErrorCode
*/
public String getNetworkErrorCode() {
return networkErrorCode;
}
/**
* #param networkErrorCode
* the networkErrorCode to set
*/
public void setNetworkErrorCode(String networkErrorCode) {
this.networkErrorCode = networkErrorCode;
}
/**
* #return the mesgFirstLines
*/
public String getMesgFirstLines() {
return mesgFirstLines;
}
/**
* #param mesgFirstLines
* the mesgFirstLines to set
*/
public void setMesgFirstLines(String mesgFirstLines) {
this.mesgFirstLines = mesgFirstLines;
}
/**
* #return the ip
*/
public String getIp() {
return ip;
}
/**
* #param ip
* the ip to set
*/
public void setIp(String ip) {
this.ip = ip;
}
/**
* #return the submitDate
*/
public DateTime getSubmitDate() {
return submitDate;
}
/**
* #param submitDate
* the submitDate to set
*/
public void setSubmitDate(DateTime submitDate) {
this.submitDate = submitDate;
}
/**
* #return the doneDate
*/
public DateTime getDoneDate() {
return doneDate;
}
/**
* #param doneDate
* the doneDate to set
*/
public void setDoneDate(DateTime doneDate) {
this.doneDate = doneDate;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
/**
* #return the srcTon
*/
public byte getSrcTon() {
return srcTon;
}
/**
* #param srcTon
* the srcTon to set
*/
public void setSrcTon(byte srcTon) {
this.srcTon = srcTon;
}
/**
* #return the srcNpi
*/
public byte getSrcNpi() {
return srcNpi;
}
/**
* #param srcNpi
* the srcNpi to set
*/
public void setSrcNpi(byte srcNpi) {
this.srcNpi = srcNpi;
}
/**
* #return the srcAddr
*/
public String getSrcAddr() {
return srcAddr;
}
/**
* #param srcAddr
* the srcAddr to set
*/
public void setSrcAddr(String srcAddr) {
this.srcAddr = srcAddr;
}
/**
* #return the destTon
*/
public byte getDestTon() {
return destTon;
}
/**
* #param destTon
* the destTon to set
*/
public void setDestTon(byte destTon) {
this.destTon = destTon;
}
/**
* #return the destNpi
*/
public byte getDestNpi() {
return destNpi;
}
/**
* #param destNpi
* the destNpi to set
*/
public void setDestNpi(byte destNpi) {
this.destNpi = destNpi;
}
/**
* #return the destAddr
*/
public String getDestAddr() {
return destAddr;
}
/**
* #param destAddr
* the destAddr to set
*/
public void setDestAddr(String destAddr) {
this.destAddr = destAddr;
}
/**
* #return the dlrState
*/
public char getDlrState() {
return dlrState;
}
/**
* #param dlrState
* the dlrState to set
*/
public void setDlrState(char dlrState) {
this.dlrState = dlrState;
}
}
Can someone tell me what can be the error? Thanks
To solve I have to download the source code and use it. I think there is a bug in the jar file I downloaded.
Download Project Source from
https://github.com/xetorthio/johm
Edit pom.xml
change Jedis version from 1.5.1 to 2.4.2 or latest
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.4.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
Compile project and build jar , use this new jar in your project