Spring Integration Headers are not getting injected to Service Activator POJO - spring

Spring Integration Headers are not getting injected to Service Activator POJO.This happens only at the time of load testing (with less than 10 tps).
Normal flow its is working as expected.
Spring integration flow is
Splitter -> executor channel -> service activator -> aggregator.
SI version 4.1.2.RELEASE
Spring Version 4.1.2.RELEASE
Java version 1.8.0_60
//service activator -Method
public ProductDetail getProductDetails(final String productID,
#Header(STATS) final Stats statsType,
#Header(SKU) final String sku,
#Header(PRODUCT_LIST) final Collection<String> productList,
#Header(NO_OF_PRODUCTS) final String size)
final MessageBuilder<Map<String, Object>> msgBuilder = MessageBuilder
.withPayload(payload);//Map<String, Object> payload
this.addMessageHeaders(msgBuilder, httpHeadersMap, statsType);
private final boolean addMessageHeaders(MessageBuilder<?> msgBuilder,
final Map<String, String> httpHeadersMap, final Stats statsType) {
if ((httpHeadersMap != null) && (httpHeadersMap.size() > 0)) {
for (Map.Entry<String, String> entry : httpHeadersMap.entrySet()) {
msgBuilder.setHeader(entry.getKey(), entry.getValue());
}
}
if (statsType != null) {
msgBuilder.setHeader(STATS, statsType);
}
return true;
}
org.springframework.messaging.MessageHandlingException: nested exception is java.lang.IllegalArgumentException: required header not available: STATS
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:78) ~[spring-integration-core-4.1.2.RELEASE.jar:na]
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:71) ~[spring-integration-core-4.1.2.RELEASE.jar:na]
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:99) ~[spring-integration-core-4.1.2.RELEASE.jar:na]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) ~[spring-integration-core-4.1.2.RELEASE.jar:na]
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) ~[spring-integration-core-4.1.2.RELEASE.jar:na]
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101) ~[spring-integration-core-4.1.2.RELEASE.jar:na]
at org.springframework.integration.dispatcher.UnicastingDispatcher.access$000(UnicastingDispatcher.java:48) ~[spring-integration-core-4.1.2.RELEASE.jar:na]
at org.springframework.integration.dispatcher.UnicastingDispatcher$1.run(UnicastingDispatcher.java:92) ~[spring-integration-core-4.1.2.RELEASE.jar:na]
at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:52) ~[spring-integration-core-4.1.2.RELEASE.jar:na]
at xx.run(DelegatingContextRunnable.java:40) ~[xx-core-3.xx.jar:3.24.0.52]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_60]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_60]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_60]
Caused by: java.lang.IllegalArgumentException: required header not available: STATS
at org.springframework.util.Assert.isTrue(Assert.java:68) ~[spring-core-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_60]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_60]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_60]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_60]
<int:channel id="retrieve-product.in" />
<int:channel id="retrieve-product.out" />
<int:channel id="retrieve-product.err" />
<int:channel id="retrieve-product.splitter.in"/>
<int:channel id="retrieve-product.sa.in">
<int:dispatcher task-executor="testExecutor" failover="false"/>
</int:channel>
<int:channel id="retrieve-product.aggregator.in"/>
<int:channel id="retrieve-product.transformer.in"/>
<bean id="retrieveProductsServiceActivatorSupport" class="com.test.eip.serviceactivator.support.RetrieveProductsServiceActivatorSupport" />
<bean id="retrieveProductsServiceActivator" class="com.test.eip.serviceactivator.RetrieveProductsServiceActivator" />
<bean id="retrieveProductsAggregator" class="com.test.eip.aggregator.RetrieveProductsAggregator" />
<bean id="retrieveProductResponseTransformer" class="com.test.eip.transformer.RetrieveProductsResponseTransformer" />
<bean id="productGroupsConfig" class="com.test.support.ProductGroupsConfig" >
<constructor-arg index="0" value="ProductMapping.xml" />
</bean>
<bean id="payloadSizeBasedReleaseStrategy" class="com.test.eip.aggregator.support.PayloadSizeBasedReleaseStrategy" />
<oxm:jaxb2-marshaller id="productConfigJaxbMarshaller" context-path="com.test.product.config.types" />
<int:gateway id="retrieveProductsGateway" service-interface="com.test.eip.gateway.IProductGateway" error-channel ="retrieve-product.err">
<int:method name="getProductsResponse" request-channel="retrieve-product.in" reply-channel="retrieve-product.out" />
</int:gateway>
<int:header-enricher input-channel="retrieve-product.in" output-channel="retrieve-product.splitter.in">
<int:header name="API_NAME" value="retrieve-product" />
</int:header-enricher>
<!-- Input List<String> contain product numbers -->
<int:splitter id="productListSplitter" input-channel="retrieve-product.splitter.in"
output-channel="retrieve-product.sa.in"></int:splitter>
<!-- Retrieve Product Features from USING API -->
<int:service-activator input-channel="retrieve-product.sa.in"
ref="retrieveProductsServiceActivator" method="getProductDetails"
output-channel="retrieve-product.aggregator.in"
id="retrieve-product-service-activator" />
<!-- Aggregate result from Parallel Call -->
<int:aggregator input-channel="retrieve-product.aggregator.in"
output-channel="retrieve-product.transformer.in"
method="aggregateProductDetails" ref="retrieveProductsAggregator"
release-strategy="payloadSizeBasedReleaseStrategy"
release-strategy-method="canRelease">
</int:aggregator>
<!-- Generate Service Response-->
<int:transformer id="retrieve-product-ResponseTransformer" method="transform"
ref="retrieveProductResponseTransformer" input-channel="retrieve-product.transformer.in" output-channel="retrieve-product.out" />
<!--
Listen for error and generate response
-->
<int:service-activator input-channel="retrieve-product.err"
ref="testErrorHandler" method="handleExceptions"
output-channel="retrieve-product.out"
id="retrieve-product-err-handler" />
public interface IProductGateway {
public RetrieveProductsResponse getProductsResponse(Message<?> inputMessage);
}
//Service
#Service
public class ProductsService implements IProductsService {
#Autowired
private IProductGateway retrieveProductsGateway;
#Override
public RetrieveProductsResponse getProductsResponse(
final RetrieveProductsRequest retrieveProductsRequest,
final Map<String, String> httpHeadersMap, final Stats statsType) {
final ProductsReqType products = retrieveProductsRequest.getProducts();
//populate productList From products
final Collection<String> productList = new HashSet<>();
httpHeadersMap.put(SKU, retrieveProductsRequest.getSKU());
httpHeadersMap.put(NO_OF_PRODUCTS,
String.valueOf(productList.size()));
final MessageBuilder<Collection<String>> msgBuilder = MessageBuilder
.withPayload(productList)
.setHeader(PRODUCT_LIST, new HashSet<>(productList));
this.addMessageHeaders(msgBuilder, httpHeadersMap, statsType);
final Message<Collection<String>> inMsg = msgBuilder.build();
LOG.debug("retrieveProductsGateway:: {}", this.retrieveProductsGateway);
final RetrieveProductsResponse retrieveProductsResponse = this.retrieveProductsGateway
.getProductsResponse(inMsg);
return retrieveProductsResponse;
}
}
//Jersey Filter is creating Stats setting it to requestContext( javax.ws.rs.container.ContainerRequestFilter)
/* Request Filter Creating and setting statsType
*/
#Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
LOG.debug("filter(requestContext)::Entry");
final Stats statsType = STATS_OBJ_FACTORY.createStats();
final MultivaluedMap<String, String> headers = requestContext.getHeaders();
statsType.setBegin(DT_FACTORY.newXMLGregorianCalendar(new GregorianCalendar()));
requestContext.setProperty(STATS, statsType);
LOG.debug("filter(requestContext)::Exit");
}
//Resource Method taking statsType and passing to ProductsService
/*javax.ws.rs.core.Context*/
#POST
#Path("retrieve-product")
#Produces(MyMediaType.PD_XML_MEDIA_TYPE)
#Consumes(MyMediaType.PD_XML_MEDIA_TYPE)
public Response getProducts(RetrieveProductsRequest retrieveProductsRequest,
#Context final ContainerRequestContext containerRequestContext,
#Context final HttpHeaders headers) {
LOG.debug("getProducts::Entry");
final Stats statsType = (Stats) containerRequestContext
.getProperty(STATS);
final Map<String, String> httpHeadersMap = ResourceHelper
.getHttpHeadersAsMap(headers);
final RetrieveProductsResponse retrieveProductsResponse = this.productsService
.getProductsResponse(retrieveProductsRequest, httpHeadersMap, statsType);
LOG.debug("getProducts::Exit");
return Response.ok(retrieveProductsResponse).build();
}
Thanks,

required header not available: STATS
Simply means that whatever is upstream that creates the message is not populating the headers; you need to show all your configuration (and possibly code). DEBUG logging and following the messages will generally help debugging such conditions.
A common mistake is a lack of thread-safety - such as in your splitter.

Related

How to propogate an exception from tcp outbound gateway to upstream SI components

I have been searching over the internet and have been trying different ways to make it work but I couldn't get it working.
Actually my system need to connect to multiple tcp server endpoints (which we call payers endpoint) as a tcp client application. The client components include the throttling and queuing components and they get initialized dynamically based on the payers configurations stored in DB as a separate application context. I have created a tcp outbound gateway for this purpose and which is being initialized in a dynamic context based on the ideas given in
https://github.com/spring-projects/spring-integration-samples/tree/master/advanced
What I want is to catch/get exceptions to the calling code at the time calling the payersGateway component in case of any error. But I am unable to receive the exceptions back.
My context file for tcp client connectivity is as follow:
dynamic-tcp-gateway-context file
<context:property-placeholder/>
<int-ip:tcp-connection-factory id="client"
type="client"
host="${host}"
port="${port}"
single-use="true"
so-timeout="${soTimeout}"
serializer="byteArrayLfSerializer"
deserializer="ediTcpSerializer"
/>
<bean id="ediTcpSerializer" class="com.abc.throttling.EdiTcpSerializer">
<property name="maxMessageSize" value="20480000"/>
</bean>
<bean id="byteArrayLfSerializer" class="org.springframework.integration.ip.tcp.serializer.ByteArrayLfSerializer">
<property name="maxMessageSize" value="20480000"/>
</bean>
<int:channel id="toPayerChannel">
<int:dispatcher task-executor="producerThreadExecutor"/>
</int:channel>
<task:executor id="producerThreadExecutor" pool-size="10" queue-capacity="50" rejection-policy="ABORT"/>
<int:channel id="throttlerChannel">
<int:priority-queue capacity="${queueSize:1000}"/> <!-- for example queue size, you can increase this capacity
based on your
requirement -->
</int:channel>
<int:bridge input-channel="toPayerChannel" output-channel="throttlerChannel" />
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="throttlerChannel"
connection-factory="client"
request-timeout="10000"
reply-timeout="${replyTimeout}">
<int:poller id="tcpPoller" error-channel="errorChannel" fixed-rate="1000" max-messages-per-poll="${messageRate:20}"/>
</int-ip:tcp-outbound-gateway>
<int:transformer input-channel="errorChannel"
ref="exceptionTransformer" method="createErrorResponse"/>
<bean id="exceptionTransformer" class="com.stella.healthenet.throttling.TcpGatewayExceptionTransformer"/>
<int:object-to-string-transformer input-channel="errorChannel"/>
application context for main payers connectivity is as follow:
main-payers-gateway-context file
<context:component-scan base-package="com.abc.throttling" />
class="com.abc.throttling.DynamicTcpChannelResolverTest" id="dynamicTcpChannelResolverTest"/>-->
<int:gateway id="payersGateway"
service-interface="com.abc.gateway.PayersGateway"
default-request-channel="toDynRouter"
default-request-timeout="1000000"
default-reply-timeout="${payersGateway.defaultReplyTimout}"
/>
<int:converter ref="converter"/>
<bean class="com.abc.manager.edi.core.core4.ByteArrayToStringConverter" id="converter"/>
<int:converter ref="converter2"/>
<bean class="com.abc.manager.edi.core.core2.Core2RealTimeResponseToString" id="converter2"/>
<int:converter ref="converter3"/>
<bean class="com.abc.manager.edi.core.core4.Core4RealTimeResponseToString" id="converter3"/>
<int:channel id="toDynRouter" />
<int:router resolution-required="true" input-channel="toDynRouter"
expression="#dynamicPayerChannelResolver.resolve(headers['payer'])" >
</int:router>
The code for dynamic channel resolver is as follow:
#Component("dynamicPayerChannelResolver")
public class DynamicPayerChannelResolver {
#Value("${throttling.payersChannelQueueSize}")
private String payersChannelQueueSize;
#Value("${throttling.tcpSoTimeout}")
private String tcpSoTimeout;
#Value("${tcpOutboundGateway.replyTimeout}")
private String tcpReplyTimeout;
#Autowired
private ApplicationContext applicationContext;
public static final int MAX_CACHE_SIZE = 30;
private static final org.apache.logging.log4j.Logger LOG = LogManager.getLogger();
#Autowired
PayerRepositoryService payerRepositoryService;
private final Map<UUID, MessageChannel> channels = Collections.synchronizedMap(new LinkedHashMap<UUID,
MessageChannel>(){
private static final long serialVersionUID = 1L;
#Override
protected boolean removeEldestEntry(
Entry<UUID, MessageChannel> eldest) {
//This returning true means the least recently used
//channel and its application context will be closed and removed
boolean remove = size() > MAX_CACHE_SIZE;
if(remove) {
MessageChannel channel = eldest.getValue();
ConfigurableApplicationContext ctx = contexts.get(channel);
if(ctx != null) { //shouldn't be null ideally
ctx.close();
contexts.remove(channel);
}
}
return remove;
}
});
private final Map<MessageChannel, ConfigurableApplicationContext> contexts =
new HashMap<MessageChannel, ConfigurableApplicationContext>();
/**
* Resolve a payer to a channel, where each payer gets a private
* application context and the channel is the inbound channel to that
* application context.
*
* #param payer
* #return a channel
*/
public MessageChannel resolve(UUID payer) {
MessageChannel channel = this.channels.get(payer);
if (channel == null) {
channel = createNewPayerChannel(payerRepositoryService.findPayerByPayerId(payer));
}
return channel;
}
private synchronized MessageChannel createNewPayerChannel(PayerEntity payer) {
MessageChannel channel = this.channels.get(payer.getPayerId());
if (channel == null) {
ConfigurableApplicationContext ctx;
if(TransportType.SOAP_WSDL.getValue().equals(payer.getConnTransportType())){
ctx = new ClassPathXmlApplicationContext(
new String[] { "dynamic-soap-gateway-context.xml" },
false,applicationContext);
}
else{
ctx = new ClassPathXmlApplicationContext(
new String[] { "dynamic-tcp-gateway-context.xml" },
false,applicationContext);
}
this.setEnvironmentForPayer(ctx, payer);
ctx.refresh();
channel = ctx.getBean("toPayerChannel", MessageChannel.class);
this.channels.put(payer.getPayerId(), channel);
//Will works as the same reference is presented always
this.contexts.put(channel, ctx);
}
return channel;
}
public void updatePollerConfigs() {
Iterator it = this.channels.entrySet().iterator();
while(it.hasNext()){
Map.Entry pair = (Map.Entry)it.next();
PayerEntity payer = this.payerRepositoryService.findPayerByPayerId((UUID)pair.getKey());
final String transportType = payer.getConnTransportType();
if(TransportType.SOAP_WSDL.getValue().equals(transportType)){
MessageChannel channel= this.channels.get(payer);
ConfigurableApplicationContext ctx;
ctx=this.contexts.get(channel);
PollingConsumer pc = ctx.getBean("soapPoller",PollingConsumer.class);
//TODO: this value need to be set from payer configs in db.
pc.setMaxMessagesPerPoll(10);
}
else if (TransportType.X12_SOCKET.getValue().equals(transportType)) {
MessageChannel channel= this.channels.get(payer);
ConfigurableApplicationContext ctx;
ctx=this.contexts.get(channel);
PollingConsumer pc = ctx.getBean("outGateway",PollingConsumer.class);
//TODO: this value need to be set from payer configs in db.
pc.setMaxMessagesPerPoll(10);
}
}
}
private void setEnvironmentForPayer(ConfigurableApplicationContext ctx,
PayerEntity payer) {
final String transportType = payer.getConnTransportType();
final String endPoint = payer.getConnEndPoint();
if(payer.getMessageRate()==null){
throw new NullPointerException("MessageRate value is NULL in DB. Please specify a MessageRate value in " +
"Payers DB for PayerID: " + payer.getPayerId());
}
final String messageRate = payer.getMessageRate();
StandardEnvironment env = new StandardEnvironment();
Properties props = new Properties();
// populate properties for payer
;
if(TransportType.SOAP_WSDL.getValue().equals(transportType)){
props.setProperty("endpoint", endPoint);
props.setProperty("messageRate",messageRate);
props.setProperty("queueSize",payersChannelQueueSize);
}
else if (TransportType.X12_SOCKET.getValue().equals(transportType)) {
if (!endPoint.contains(":")) {
throw new Exception(ErrorType.UNEXPECTED, "Payer X12 Socket endpoint must include a port.");
}
final String ip;
if (endPoint.contains("/")) {
ip = endPoint.substring(endPoint.lastIndexOf('/') + 1, endPoint.lastIndexOf(":"));
} else {
ip = endPoint.substring(0, endPoint.lastIndexOf(":"));
}
final String port = endPoint.substring(endPoint.lastIndexOf(':') + 1);
props.setProperty("host", ip);
props.setProperty("port", port);
props.setProperty("messageRate",messageRate);
props.setProperty("queueSize",payersChannelQueueSize);
props.setProperty("soTimeout", tcpSoTimeout);
props.setProperty("replyTimeout",tcpReplyTimeout);
}
PropertiesPropertySource pps = new PropertiesPropertySource("payerChannelProps", props);
env.getPropertySources().addLast(pps);
ctx.setEnvironment(env);
}
I want to get the exceptions generated at the downstream components to appear at the payersGateway interface send method call i.e., shown below:
String response = payersGateway.send(
MessageBuilder.withPayload(requestMessage)
.setHeader("endpointUrl", endPoint)
.setHeader("senderId", coreSenderId)
.setHeader("receiverId", payerIdCode)
.setHeader("username", username)
.setHeader("password", password)
.setHeader("payloadType", payloadType)
.setHeader("nginxUrl", nginxUrl)
.setHeader("payer", payerId)
.setHeader("transType", transType)
.setHeader("priority", 1)
.build());
where the payersGateway is simple interface pointing to Gateway component in main context file.
public interface PayersGateway {
public String send(Message<String> message);
}
Please see the stack trace of produced exception as below:
[task-scheduler-1] ERROR org.springframework.integration.ip.tcp.TcpOutboundGateway - Tcp Gateway exception
java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at javax.net.DefaultSocketFactory.createSocket(SocketFactory.java:271)
at org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory.createSocket(TcpNetClientConnectionFactory.java:76)
at org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory.buildNewConnection(TcpNetClientConnectionFactory.java:49)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.obtainNewConnection(AbstractClientConnectionFactory.java:116)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.obtainConnection(AbstractClientConnectionFactory.java:79)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.getConnection(AbstractClientConnectionFactory.java:69)
at org.springframework.integration.ip.tcp.TcpOutboundGateway.handleRequestMessage(TcpOutboundGateway.java:130)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.endpoint.PollingConsumer.handleMessage(PollingConsumer.java:129)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:272)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:58)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:190)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:186)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:353)
at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:344)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
[task-scheduler-1] ERROR org.springframework.integration.handler.LoggingHandler - org.springframework.messaging.MessagingException: Failed to send or receive; nested exception is java.net.ConnectException: Connection refused (Connection refused)
at org.springframework.integration.ip.tcp.TcpOutboundGateway.handleRequestMessage(TcpOutboundGateway.java:158)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.endpoint.PollingConsumer.handleMessage(PollingConsumer.java:129)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:272)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:58)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:190)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:186)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:353)
at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:344)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at javax.net.DefaultSocketFactory.createSocket(SocketFactory.java:271)
at org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory.createSocket(TcpNetClientConnectionFactory.java:76)
at org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory.buildNewConnection(TcpNetClientConnectionFactory.java:49)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.obtainNewConnection(AbstractClientConnectionFactory.java:116)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.obtainConnection(AbstractClientConnectionFactory.java:79)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.getConnection(AbstractClientConnectionFactory.java:69)
at org.springframework.integration.ip.tcp.TcpOutboundGateway.handleRequestMessage(TcpOutboundGateway.java:130)
... 21 more
It should work as you need; exceptions before the throttlerChannel will be thrown directly to the caller; exceptions after that channel will be sent to the gateway by the poller's error handler.
Perhaps your gateway timeout is too short?
Turning on DEBUG logging and following the message flow should help you debug it.
EDIT
You can fix the missing failedMessage by adding a bean of this type to the Tcp outbound gateway's <int-ip:request-handler-advice-chain />...
public class FailedMessagePopulator extends AbstractRequestHandlerAdvice {
#Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception {
try {
return callback.execute();
}
catch (MessagingException e) {
if (e.getFailedMessage() == null) {
throw new MessageHandlingException(message, e.getMessage(), e);
}
else {
throw e;
}
}
catch (Exception e) {
throw new MessageHandlingException(message, e.getMessage(), e);
}
}
}
Note that you will need to add the error channel to the <gateway/> since the poller will now see the failed message and send the exception back to the gateway for error handling.

javax.management.InstanceAlreadyExistsException while deploying spring application

<int:poller fixed-delay="${fixedDelay}" default="true">
<int:advice-chain>
<ref bean="pollAdvise"/>
</int:advice-chain>
</int:poller>
<bean id="pollAdvise" class="org.springframework.integration.scheduling.PollSkipAdvice">
<constructor-arg ref="healthCheckStrategy"/>
</bean>
<bean id="healthCheckStrategy" class="test.main.ServiceHealthCheckPollSkipStrategy">
<property name="url" value="${url}"/>
<property name="doHealthCheck" value="${doHealthCheck}"/>
<property name="restTemplate" ref="restTemplate"/>
</bean>
<bean id="restTemplate"
class="org.springframework.web.client.RestTemplate">
<constructor-arg ref="requestFactory"/>
</bean>
<bean id="requestFactory"
class="test.BatchClientHttpRequestFactory">
<constructor-arg ref="verifier"/>
</bean>
and my health check strategy looks like below
#ManagedResource
public class ServiceHealthCheckPollSkipStrategy implements PollSkipStrategy {
private volatile boolean skip=false;
private String url;
private static String doHealthCheck;
private RestTemplate restTemplate;
public RestTemplate getRestTemplate() {
return restTemplate;
}
public void setRestTemplate(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDoHealthCheck() {
return doHealthCheck;
}
public void setDoHealthCheck(String doHealthCheck) {
ServiceHealthCheckPollSkipStrategy.doHealthCheck= doHealthCheck;
}
#Override
public boolean skipPoll() {
if(doHealthCheck.equals("false")){
return this.skip;
}
else if(doHealthCheck.equals("true")){
List<String> urlList =getUrlfromEncodedString(url);
for (String url : urlList) {
boolean status =performHealthCheck(url);
if(status==false){
return this.skip = true;
}
}
return this.skip;
}
else {
throw new IllegalArgumentException("do health check can be either true or false");
}
}
/**
* Skip future polls.
*/
#ManagedOperation
public void skipPolls() {
this.skip = true;
}
/**
* Resume polling at the next {#code Trigger} event.
*/
#ManagedOperation
public void reset() {
this.skip = false;
}
private List<String> getUrlfromEncodedString(String urls) throws IllegalArgumentException
{
if(urls==null){
throw new IllegalArgumentException("urls passed is null");
}
List<String> urlList = Arrays.asList(urls.split("\\s*,\\s*"));
return urlList;
}
private boolean performHealthCheck(String url){
if(url==null){
throw new IllegalArgumentException("url passed is null");
}
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("API-Key", "RTM");
HttpEntity<String> request = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> response = restTemplate.
exchange(url, HttpMethod.OPTIONS, request, String.class);
if (response.getStatusCode().toString().equals("200")){
return true;
}
return false;
}
}
I get below exception
Unable to register MBean [test.main.ServiceHealthCheckPollSkipStrategy#73d4b814] with key 'healthCheckStrategy'; nested exception is javax.management.InstanceAlreadyExistsException: test.main:name=healthCheckStrategy,type=ServiceHealthCheckPollSkipStrategy
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:625)
at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:550)
at org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:432)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:139)
at org.springframework.xd.module.core.SimpleModule.initialize(SimpleModule.java:213)
at org.springframework.xd.dirt.module.ModuleDeployer.doDeploy(ModuleDeployer.java:217)
at org.springframework.xd.dirt.module.ModuleDeployer.deploy(ModuleDeployer.java:200)
at org.springframework.xd.dirt.server.container.DeploymentListener.deployModule(DeploymentListener.java:365)
at org.springframework.xd.dirt.server.container.DeploymentListener.deployStreamModule(DeploymentListener.java:334)
at org.springframework.xd.dirt.server.container.DeploymentListener.onChildAdded(DeploymentListener.java:181)
at org.springframework.xd.dirt.server.container.DeploymentListener.childEvent(DeploymentListener.java:149)
at org.apache.curator.framework.recipes.cache.PathChildrenCache$5.apply(PathChildrenCache.java:509)
at org.apache.curator.framework.recipes.cache.PathChildrenCache$5.apply(PathChildrenCache.java:503)
at org.apache.curator.framework.listen.ListenerContainer$1.run(ListenerContainer.java:92)
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297)
at org.apache.curator.framework.listen.ListenerContainer.forEach(ListenerContainer.java:83)
at org.apache.curator.framework.recipes.cache.PathChildrenCache.callListeners(PathChildrenCache.java:500)
at org.apache.curator.framework.recipes.cache.EventOperation.invoke(EventOperation.java:35)
at org.apache.curator.framework.recipes.cache.PathChildrenCache$10.run(PathChildrenCache.java:762)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
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)
Caused by: javax.management.InstanceAlreadyExistsException: test.main:name=healthCheckStrategy,type=ServiceHealthCheckPollSkipStrategy
at com.sun.jmx.mbeanserver.Repository.addMBean(Repository.java:437)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerWithRepository(DefaultMBeanServerInterceptor.java:1898)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:966)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:900)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:324)
at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:522)
at org.springframework.jmx.support.MBeanRegistrationSupport.doRegister(MBeanRegistrationSupport.java:195)
at org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:678)
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:615)
... 30 m
I got the javax.management.InstanceAlreadyExistsException as part of the stacktrace, however the leading error was java.lang.IllegalStateException:
javax.management.InstanceAlreadyExistsException: jboss.deployment:id="jboss.web.deployment:war=/my_application", type=Component already registered.
Caused by: java.lang.IllegalStateException: jboss.web.deployment:war=/my_application is already installed.
The reason was that I accidentally kept two .ear files in the /deploy folder of my JBOSS server - both the previous and the current .ear of my application.
As it was stated here: https://www.theserverside.com/discussions/thread/22674.html
I'm not sure there is a way to deploy two ear files with the same
classes inside and not have problems.
Since the two .ears had classes in common, that lead to InstanceAlreadyExistsException.
What has worked for me is:
Delete the war file from /webapps
Copy war file from /target and paste into /webapps
Hope it will work for you too.
It's because you also declare another bean with the same id as 'healthCheckStrategy' in another spring application. You probably put these two spring applications in the same server.
Solution 1:
change the bean id either in this spring application or the other one will solve your problem.
Solution 2:
add EnableMBeanExport annotation and set different defaultDomain for each spring application
#Configuration
#EnableMBeanExport(defaultDomain="first")
public class BeanGenerator {...}
#Configuration
#EnableMBeanExport(defaultDomain="second")
public class BeanGenerator {...}

How to solve NullPointerException at mailSender when using some organization as a host

I'm trying to send emails using an organisation mailSender.
Controller
#RequestMapping(value="/forgetPassword", method = RequestMethod.POST, consumes={"application/json"})
public #ResponseBody User forgetPassword(#RequestBody User user) throws Exception {
user=userService.forgetPassword(user, newPassword);
if(user !=null)
{
SendEmail callsendEmail = new SendEmail();
callsendEmail.emailSender(user);
return user;
}
else
{
return user;
}
}
SendEmail
public class SendEmail {
private JavaMailSender mailSender;
private VelocityEngine velocityEngine;
private SimpleMailMessage templateMessage;
public void emailSender(final User user) throws Exception {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);
message.setFrom(templateMessage.getFrom());
message.setTo(user.getEmail());
message.setSubject(templateMessage.getSubject());
Map<String, User> model = new HashMap<String, User>();
model.put("user", user);
/*String text = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "org/utility/mailTemplate.vm", model);
message.setText(text, true);*/
if (mailSender != null) {
mailSender.send(mimeMessage);
}
}
public void setVelocityEngine(VelocityEngine velocityEngine) {
this.velocityEngine = velocityEngine;
}
public JavaMailSender getMailSender() {
return mailSender;
}
public void setMailSender(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
public SimpleMailMessage getTemplateMessage() {
return templateMessage;
}
public void setTemplateMessage(SimpleMailMessage templateMessage) {
this.templateMessage = templateMessage;
}
}
Configuration
<bean id="emailSender" class="org.utility.SendEmail">
<property name="mailSender" ref="mailSender" />
<property name="velocityEngine" ref="velocityEngine" />
<property name="templateMessage" ref="templateMessage" />
</bean>
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="10.6.12.229" />
<property name="port" value="25" />
</bean>
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<value>resource.loader=class class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader</value>
</property>
</bean>
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="noreply#scrumtracker.com" />
<property name="subject" value="Scrum Tracker Login Details" />
</bean>
Here's the stack trace:
SEVERE: Servlet.service() for servlet [spring] in context with path [/OLPV] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at org.utility.SendEmail.emailSender(SendEmail.java:24)
at org.controller.UserController.forgetPassword(UserController.java:125)
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 org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:119)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:242)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:201)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:163)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:556)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:401)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:242)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:267)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:245)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:260)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I'm getting nullpointer exception on running the above code. Data is passing to the SendEmail class from Controller. Any idea on this?
Set #autowired from calling class (Don't do New) to the mailSend class.
Write #Service in mailSend class.
Directly call the mailSend.Send() method from the calling class.
All prop will be set automatically. No null point exception.
Namaste !
In your Controller class you don't need to instantiante the SendEmail like you do
SendEmail callsendEmail = new SendEmail();
But instead inject it as a spring bean
#Controller
class MyController {
#Autowired
private SendEmail callsendEmail;
#RequestMapping(value="/forgetPassword", method = RequestMethod.POST, consumes={"application/json"})
public #ResponseBody User forgetPassword(#RequestBody User user) throws Exception {
user=userService.forgetPassword(user, newPassword);
if(user !=null)
{
callsendEmail.emailSender(user);
return user;
}
else
{
return user;
}
}
}
If your application context is not configured to autowire beans by annotations, then use a regular setter in the class
#Required
public void setSendEmail( SendEmail sendEmail ) {
this.callsendEmail = sendEmail;
}

How to send Emails via Spring

In my JavaFx project I inject my controllers like so, which works fine:
#Configuration
public class AppFactory {
#Bean
public HomeController homeController() throws IOException {
return (HomeController) loadController("/wakiliproject/Home.fxml");
}
FXMLLoader loader = null;
protected Object loadController(String url) throws IOException {
loader = new FXMLLoader(getClass().getResource(url));
loader.load();
return loader.getController();
}
}
However, for non-controller classes, I get a null pointer exception, probably because the class never gets injected. Say, for example, I try to call a method in a non-controller class from another non-controller class like so:
Sending email via Spring, for example:
public class HomeController extends Application {
#Autowired
MailMail mailMail;
// Send email here
public void sendEmailMethod() {
System.out.println("Here ----------------------------------------------------------------");
mailMail.sendMail("olireylikesyou#gmail.com", "tryrevilo#yahoo.com", "Hello", "Subjecto");
}
// The other class methods
The other classes:
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="username" value="mygmailusername#gmail.com" />
<property name="password" value="gmailpassword" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
</props>
</property>
</bean>
<bean id="mailMail" class="wakiliproject.ServerSide.EMail.MailMail">
<property name="mailSender" ref="mailSender" />
</bean>
--
public class MailMail {
private MailSender mailSender;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void sendMail(String from, String to, String subject, String msg) {
//creating message
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(msg);
//sending message
mailSender.send(message);
}
}
The stacktrace:
Exception in Application start method
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:483)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:367)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:305)
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:483)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:894)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:56)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:158)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.mail.MailSendException: Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. k10sm2188955lae.42 - gsmtp
; message exceptions (1) are:
Failed message 1: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. k10sm2188955lae.42 - gsmtp
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:448)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:308)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:297)
at wakiliproject.ServerSide.EMail.MailMail.sendMail(MailMail.java:22)
at wakiliproject.HomeController$HomeInit.homeInit(HomeController.java:618)
at wakiliproject.HomeController$HomeInit.access$100(HomeController.java:613)
at wakiliproject.HomeController.initHomeController(HomeController.java:319)
at wakiliproject.WakiliProject.start(WakiliProject.java:34)
at com.sun.javafx.application.LauncherImpl$8.run(LauncherImpl.java:837)
at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:335)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:301)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:298)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:298)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
... 1 more
Exception running application wakiliproject.WakiliProject
Java Result: 1
had a similar problem... got me some attempts to configure it right in my application.properties (I'm injecting JavaMailSender using spring)
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.auth = true;
spring.mail.properties.mail.socketFactory.port=587
spring.mail.properties.mail.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.socketFactory.fallback=false
later i was required to enable looser security to my account during the test:
"change your settings at https://www.google.com/settings/security/lesssecureapps so that your account is no longer protected by modern security standards"
or i got an authentication error.
I hope that helps
According to Mladen Uzelac You need to set some properties for your SMTP connection.
Link related:
http://forum.spring.io/forum/spring-projects/web/68425-javax-mail-messagingexception-530-5-7-0-must-issue-a-starttls-command-first-5sm505

NPE when invoking getter of managed property

I am learning Spring with Hibernate and am creating a movie rental application using JSF as front end framework.
I have an application scoped managed property in my registration bean which is view scoped. In the register() method to insert the user details in the database, I invoke the service locator implementation bean to get a reference to the required service implementation. However, I get an NPE when I invoke the getter of the service locator property.
Following are my managed beans...
Registration Bean
#ManagedBean
#ViewScoped
public class RegistrationBean extends BaseBean implements Serializable
{
private static final long serialVersionUID = -6449858513581500971L;
private String userID;
private String password;
private String firstName;
private String lastName;
private String email;
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private String pincode;
public RegistrationBean() {
super();
}
// getter / setters...
public String register()
{
String nextPage = null;
try {
RegistrationDetails userDetails = ModelBuilder.populateRegistrationData(this);
// NPE at this line. getServiceLocator() returns null
int registrationID = getServiceLocator().getUserService().registerUser(userDetails);
nextPage = "success";
}
catch (RegistrationException e) {
LOGGER.error(e.getMessage());
}
return nextPage;
}
}
Base Bean
public class BaseBean
{
#ManagedProperty("#{serviceLocator}")
protected IServiceLocator serviceLocator;
protected IServiceLocator getServiceLocator() {
return serviceLocator;
}
public void setServiceLocator(IServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
}
Service Locator Bean
#ManagedBean
#ApplicationScoped
public class ServiceLocator implements IServiceLocator
{
private static final String USER_SERVICE = "userService";
public ServiceLocator() {
super();
final ServletContext sc = FacesUtils.getServletContext();
this.webAppContext = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
this.userService = (IUserService) webAppContext.getBean(USER_SERVICE);
}
private ApplicationContext webAppContext;
private IUserService userService;
#Override
public IUserService getUserService() {
return userService;
}
public ApplicationContext getWebAppContext() {
return webAppContext;
}
}
And here is the stacktrace as seen in my Eclipse console
Oct 14, 2012 10:28:39 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: #{registrationBean.register}: java.lang.NullPointerException
javax.faces.FacesException: #{registrationBean.register}: java.lang.NullPointerException
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
... 23 more
Caused by: java.lang.NullPointerException
at com.clixflix.managedbeans.RegistrationBean.register(RegistrationBean.java:118)
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.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 24 more
I am using
JSF 2.1 (Mojarra)
Hibernate 4.1
Spring 3.2
Tomcat 7
Eclipse 3.7
Could someone please point out if I have missed something??
UPDATE: Spring config file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation" value="/WEB-INF/hibernate.cfg.xml" />
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="userDAO" class="com.clixflix.dao.impl.UserDAOImpl">
<constructor-arg index="0" ref="hibernateTemplate" />
</bean>
<bean id="userService" class="com.clixflix.services.impl.UserService">
<constructor-arg index="0" ref="userDAO" />
</bean>
</beans>
This post helped me to make the code work : http://www.javacodegeeks.com/2012/04/jsf-2-primefaces-3-spring-3-hibernate-4.html
However, the code does not work if I keep the Registration Bean as view scoped. Can anyone please help me figure out the reason for the same?
UPDATE: Found the solution for the ViewScope issue : http://blog.harezmi.com.tr/spring-view-scope-for-jsf-2-users/

Resources