class JmsItemReader<T> implements ItemReader<T>, InitializingBean {

	protected Log logger = LogFactory.getLog(getClass());

	protected Class<? extends T> itemType;

	protected JmsOperations jmsTemplate;

	/**
	 * Setter for JMS template.
	 * @param jmsTemplate a {@link JmsOperations} instance
	 */
	public void setJmsTemplate(JmsOperations jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
		if (jmsTemplate instanceof JmsTemplate template) {
			Assert.isTrue(template.getReceiveTimeout() != JmsTemplate.RECEIVE_TIMEOUT_INDEFINITE_WAIT,
					"JmsTemplate must have a receive timeout!");
			Assert.isTrue(template.getDefaultDestination() != null || template.getDefaultDestinationName() != null,
					"JmsTemplate must have a defaultDestination or defaultDestinationName!");
		}
	}

	/**
	 * Set the expected type of incoming message payloads. Set this to {@link Message} to
	 * receive the raw underlying message.
	 * @param itemType the java class of the items to be delivered. Typically the same as
	 * the class parameter
	 * @throws IllegalStateException if the message payload is of the wrong type.
	 */
	public void setItemType(Class<? extends T> itemType) {
		this.itemType = itemType;
	}

	@Nullable
	@Override
	@SuppressWarnings("unchecked")
	public T read() {<FILL_FUNCTION_BODY>}

	@Override
	public void afterPropertiesSet() throws Exception {
		Assert.state(this.jmsTemplate != null, "The 'jmsTemplate' is required.");
	}

}

		if (itemType != null && itemType.isAssignableFrom(Message.class)) {
			return (T) jmsTemplate.receive();
		}
		Object result = jmsTemplate.receiveAndConvert();
		if (itemType != null && result != null) {
			Assert.state(itemType.isAssignableFrom(result.getClass()),
					"Received message payload of wrong type: expected [" + itemType + "]");
		}
		return (T) result;
	
<no_super_class>