Writing java based JMS Client for WildFly10 - client

I writing java based JMS Client for WildFly10 and I had problem
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
props.put(Context.PROVIDER_URL, WILDFLY_REMOTING_URL); // NOTICE: "http- remoting" and port "8080"
props.put(Context.SECURITY_PRINCIPAL, JMS_USERNAME);
props.put(Context.SECURITY_CREDENTIALS, JMS_PASSWORD);
//props.put("jboss.naming.client.ejb.context", true);
context = new InitialContext(props);
i run your client code and i got this error:
Got initial Context: javax.naming.InitialContext#5442a311
Exception in thread “main” org.jboss.naming.remote.protocol.NamingIOException: Failed to lookup [Root exception is java.io.IOException: java.lang.ClassNotFoundException: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory]
at org.jboss.naming.remote.client.ClientUtil.namingException(ClientUtil.java:49)
at org.jboss.naming.remote.protocol.v1.Protocol$1.execute(Protocol.java:104)
at org.jboss.naming.remote.protocol.v1.RemoteNamingStoreV1.lookup(RemoteNamingStoreV1.java:95)
at org.jboss.naming.remote.client.HaRemoteNamingStore$1.operation(HaRemoteNamingStore.java:276)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:137)
at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:272)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:87)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:129)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.almasprocess.model.bl.WildFlyJmsQueueSender.init(WildFlyJmsQueueSender.java:49)
at com.almasprocess.model.bl.WildFlyJmsQueueSender.main(WildFlyJmsQueueSender.java:43)
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.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.io.IOException: java.lang.ClassNotFoundException: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory
at org.jboss.naming.remote.protocol.v1.Protocol$1$3.read(Protocol.java:159)
at org.jboss.naming.remote.protocol.v1.Protocol$1$3.read(Protocol.java:149)
at org.jboss.naming.remote.protocol.v1.BaseProtocolCommand.readResult(BaseProtocolCommand.java:59)
at org.jboss.naming.remote.protocol.v1.Protocol$1.handleClientMessage(Protocol.java:149)
at org.jboss.naming.remote.protocol.v1.RemoteNamingStoreV1$MessageReceiver$1.run(RemoteNamingStoreV1.java:232)
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: java.lang.ClassNotFoundException: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:340)
at org.jboss.marshalling.AbstractClassResolver.loadClass(AbstractClassResolver.java:131)
at org.jboss.marshalling.AbstractClassResolver.resolveClass(AbstractClassResolver.java:112)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadClassDescriptor(RiverUnmarshaller.java:1002)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1256)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:276)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:209)
at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41)
at org.jboss.naming.remote.protocol.v1.Protocol$1$3.read(Protocol.java:156)
… 7 more
Process finished with exit code 1
And I changed code like this and add activemq lib in my project:
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,"org.apache.activemq.jndi.ActiveMQInitialContextFactory");
props.put(Context.PROVIDER_URL, WILDFLY_REMOTING_URL); // NOTICE: "http-remoting" and port "8080"
props.put(Context.SECURITY_PRINCIPAL, JMS_USERNAME);
props.put(Context.SECURITY_CREDENTIALS, JMS_PASSWORD);
and i got this error :
Got initial Context: javax.naming.InitialContext#6842775d
Exception in thread "main" javax.naming.NameNotFoundException: jms/RemoteConnectionFactory
at org.apache.activemq.jndi.ReadOnlyContext.lookup(ReadOnlyContext.java:225)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.almasprocess.model.bl.WildFlyJmsQueueSender.init(WildFlyJmsQueueSender.java:49)
at com.almasprocess.model.bl.WildFlyJmsQueueSender.main(WildFlyJmsQueueSender.java:43)
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.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
and standalone-full.xml config file like this :
<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
<server name="default">
<security-setting name="#">
<role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>
</security-setting>
<address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/>
<http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor"/>
<http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput">
<param name="batch-delay" value="50"/>
</http-connector>
<in-vm-connector name="in-vm" server-id="0"/>
<http-acceptor name="http-acceptor" http-listener="default"/>
<http-acceptor name="http-acceptor-throughput" http-listener="default">
<param name="batch-delay" value="50"/>
<param name="direct-deliver" value="false"/>
</http-acceptor>
<in-vm-acceptor name="in-vm" server-id="0"/>
<jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>
<jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>
<jms-queue name="clickQueue" entries="java:/jms/queue/clickQueue java:/jboss/exported/jms/queue/clickQueue"/>
<jms-queue name="emailQueue" entries="java:/jms/queue/EmailQueue java:/jboss/exported/jms/queue/EmailQueue"/>
<jms-queue name="emailSendQueue" entries="java:/jboss/exported/jms/queue/EmailSendQueue"/>
<connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/>
<connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>
<pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>
</server>
</subsystem>
can you help me about error???
thanks.

Working example:
public class JMSClient {
private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
private static final String PROVIDER_URL = "http-remoting://127.0.0.1:8080";
private static final String CONNECTION_FACTORY = "jms/RemoteConnectionFactory";
private static final String DESTINATION = "topic/irisWebBroadcaster";
private static final String USERNAME = "jmsuser";
private static final String PASSWORD = "qqq";
public static void main(String[] args) {
Context namingContext = null;
JMSContext context = null;
try {
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
env.put(Context.SECURITY_PRINCIPAL, USERNAME);
env.put(Context.SECURITY_CREDENTIALS, PASSWORD);
namingContext = new InitialContext(env);
ConnectionFactory connectionFactory = (ConnectionFactory) namingContext.lookup(CONNECTION_FACTORY);
Destination destination = (Destination) namingContext.lookup(DESTINATION);
context = connectionFactory.createContext(USERNAME, PASSWORD);
JMSProducer producer = context.createProducer();
producer.send(destination, "TEST");
} catch (Exception e) {
// print error messge
} finally {
if (namingContext != null) {
try {
namingContext.close();
} catch (NamingException e) {
// print error messge
}
}
if (context != null) {
context.close();
}
}
}
}
Corresponding classpath (maybe excessive):
[WILDFLY10_DIR]/modules/system/layers/base/javax/annotation/api/main/jboss-annotations-api_1.2_spec-1.0.0.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/javax/servlet/api/main/jboss-servlet-api_3.1_spec-1.0.0.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/javax/ejb/api/main/jboss-ejb-api_3.2_spec-1.0.0.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/javax/enterprise/api/main/cdi-api-1.2.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/log4j/logmanager/main/log4j-jboss-logmanager-1.1.2.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/javax/inject/api/main/javax.inject-1.jar
[WILDFLY10_DIR]/modules/system/layers/base/javax/ws/rs/api/main/jboss-jaxrs-api_2.0_spec-1.0.0.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/javax/jms/api/main/jboss-jms-api_2.0_spec-1.0.0.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/codehaus/jackson/jackson-core-asl/main/jackson-core-asl-1.9.13.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/codehaus/jackson/jackson-mapper-asl/main/jackson-mapper-asl-1.9.13.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/logging/main/jboss-logging-3.3.0.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/logmanager/main/jboss-logmanager-2.0.3.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/remote-naming/main/jboss-remote-naming-2.0.4.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/xnio/main/xnio-api-3.3.4.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/xnio/nio/main/xnio-nio-3.3.4.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/remoting/main/jboss-remoting-4.0.18.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/marshalling/main/jboss-marshalling-1.4.10.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/marshalling/river/main/jboss-marshalling-river-1.4.10.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/apache/activemq/artemis/main/artemis-jms-client-1.1.0.wildfly-011.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/apache/activemq/artemis/main/artemis-core-client-1.1.0.wildfly-011.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/apache/activemq/artemis/main/artemis-commons-1.1.0.wildfly-011.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/apache/activemq/artemis/main/artemis-selector-1.1.0.wildfly-011.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/apache/commons/beanutils/main/commons-beanutils-1.9.2.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/apache/commons/collections/main/commons-collections-3.2.2.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/slf4j/jcl-over-slf4j/main/jcl-over-slf4j-1.7.7.jbossorg-1.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/slf4j/main/slf4j-api-1.7.7.jbossorg-1.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/slf4j/impl/main/slf4j-jboss-logmanager-1.0.3.GA.jar
[WILDFLY10_DIR]/modules/system/layers/base/org/jboss/ejb-client/main/jboss-ejb-client-2.1.4.Final.jar
[WILDFLY10_DIR]/modules/system/layers/base/io/netty/main/netty-all-4.0.32.Final.jar
You can add something like this if you have problems with logging:
InternalLoggerFactory.setDefaultFactory(new Log4JLoggerFactory());
PropertyConfigurator.configure("conf/log4j.properties");

I see that Answer given by Rudik is not yet accepted , hence posting my take on this problem.
Test case
#Test
public void sendMessagesToWildfly10() throws IOException, NamingException {
String Message = "Hello, World!";
String connectionFactoryJNDIName = "jms/RemoteConnectionFactory";
String queueName = "jms/queue/TestQueue";
Context namingContext = null;
JMSContext context = null;
try {
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");
env.put(Context.PROVIDER_URL, "http-remoting://localhost:8470");
// Below May Not be needed if you have turned off the security for Messaging
env.put(Context.SECURITY_PRINCIPAL, "guest");
env.put(Context.SECURITY_CREDENTIALS, "guest");
namingContext = new InitialContext(env);
ConnectionFactory connectionFactory = (ConnectionFactory) namingContext.lookup(connectionFactoryJNDIName);
Destination destination = (Destination) namingContext.lookup(queueName);
context = connectionFactory.createContext("userName", "password");
JMSProducer producer = context.createProducer();
for (int i = 0; i < 10; i++) {
producer.send(destination, Message+" - "+i);
}
JMSConsumer consumer = context.createConsumer(destination);
for (int i = 0; i < 10; i++) {
String text = consumer.receiveBody(String.class, 5000);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (namingContext != null) {
namingContext.close();
}
if (context != null) {
context.close();
}
}
}
You will require below mentioned Jars/dependencies added to your classpath. Most of them you can find in Wildfly/modules

If a JMS client is running within a WildFly application then the org.apache.activemq.artemis module must be added as a dependency on your deployment to avoid the java.lang.ClassNotFoundException: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory, e.g. as answered here.
Otherwise ( standalone java application) - the jboss-client.jar needs to be included into class-path.
Note: take the jboss-client.jar based on your target WildFly version because it differs between WildFLy 8 and 10.

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.

Closing Connection from WildFly Datasource cause java.net.SocketException

I'm using WildFly 10.0.0 and MySQL 5.5.17 and JDBC Driver 5.1.39
I first set a DataSouce in WildFly as a module
in the folder WILDFLY_HOME\modules\system\layers\base\com\mysql\main there is the driver and the file module.xml :
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.mysql">
<resources>
<resource-root path="mysql-connector-java-5.1.39-bin.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
And the config file standalone-full.xml :
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
<datasources>
<datasource jta="false" jndi-name="java:/jdbc/MyDS" pool-name="MyDS" enabled="true" use-ccm="false">
<connection-url>jdbc:mysql://www.my-url.com:3306/my_db</connection-url>
<driver>mysql</driver>
<pool>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<prefill>true</prefill>
</pool>
<security>
<user-name>login</user-name>
<password>password</password>
</security>
</datasource>
<drivers>
<driver name="mysql" module="com.mysql">
<driver-class>com.mysql.jdbc.Driver</driver-class>
<xa-datasource-class>com.mysql.jdbc.Driver</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
When I test the connection within the wildfly console I have the message : "Successfully created JDBC connection.
Successfully connected to database MyDS"
When I try to use this DataSource doing :
#Resource(mappedName = "java:/jdbc/MyDS")
private DataSource dataSource;
private Integer selectId(String mail) {
try (Connection connection = dataSource.getConnection()) {
try (PreparedStatement statement = connection.prepareStatement(getQuery())) {
statement.setString(1, mail);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
Integer id = resultSet.getInt(1);
return id;
} else {
return null;
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
I have this Exception :
The last packet successfully received from the server was 2 621 144 milliseconds ago. The last packet sent successfully to the server was 2 621 171 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:988)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3739)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2508)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2673)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1962)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:504)
at my.app.mail.service.MailService.selectId(LoginService.java:46)
... 129 more
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3721)
... 136 more
When I do :
#Resource(mappedName = "java:/jdbc/MyDS")
private DataSource dataSource;
private Integer selectId(String mail) {
try {
Connection connection = dataSource.getConnection();
try (PreparedStatement statement = connection.prepareStatement(getQuery())) {
statement.setString(1, mail);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
Integer id = resultSet.getInt(1);
return id;
} else {
return null;
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
It works...
How I have to handle DataSource? Do problems will occurs if I don't close Connection? Maybe it's a problem of DataSource config...

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;
}

Custom Liquibase Change error when integrating with Spring: Unknown Liquibase extension. Are you missing a jar from your classpath?

As part of the database upgrade for an existing application, a custom Liquibase change which extends AbstractChange has been created:
#DatabaseChange(name = "springBeanChange", description = "Runs a spring bean custom change", priority = ChangeMetaData.PRIORITY_DEFAULT)
public class SpringBeanChange extends AbstractChange {
private String beanName;
private String changeClass;
#DatabaseChangeProperty(description = "Spring bean name (optional)")
public String getBeanName() {
return this.beanName;
}
public void setBeanName(final String beanName) {
this.beanName = beanName;
}
#DatabaseChangeProperty(description = "Spring bean class")
public String getChangeClass() {
return this.changeClass;
}
public void setChangeClass(final String changeClass) {
this.changeClass = changeClass;
}
private CustomTaskChange bean;
#Override
public boolean generateStatementsVolatile(final Database database) {
return true;
}
#Override
public String getConfirmationMessage() {
return findBean().getConfirmationMessage();
}
#Override
public SqlStatement[] generateStatements(final Database database) {
try {
findBean().execute(database);
} catch (CustomChangeException e) {
throw new UnexpectedLiquibaseException(e);
}
return new SqlStatement[0];
}
#SuppressWarnings("unchecked")
private CustomTaskChange findBean() {
Class<CustomTaskChange> requiredType = CustomTaskChange.class;
if (this.changeClass != null) {
try {
Class<?> requestedType = Class.forName(this.changeClass);
if (CustomTaskChange.class.isAssignableFrom(requestedType)) {
requiredType = (Class<CustomTaskChange>) requestedType;
} else {
throw new UnexpectedLiquibaseException(
"Specified changeClass " + this.changeClass
+ " was not an instance of "
+ CustomTaskChange.class);
}
} catch (ClassNotFoundException e) {
throw new UnexpectedLiquibaseException(
"Could not create change class", e);
}
}
if (this.bean == null) {
if (getBeanName() == null) {
this.bean = SpringContextHolder.getInstance().getContext()
.getBean(requiredType);
} else {
this.bean = SpringContextHolder.getInstance().getContext()
.getBean(getBeanName(), requiredType);
}
}
return this.bean;
}
#Override
public ValidationErrors validate(final Database database) {
try {
return findBean().validate(database);
} catch (NullPointerException p_exception) {
return new ValidationErrors()
.addError("Exception thrown calling validate():"
+ p_exception.getMessage());
} catch (UnexpectedLiquibaseException p_exception) {
return new ValidationErrors()
.addError("Exception thrown calling validate():"
+ p_exception.getMessage());
} catch (NoSuchBeanDefinitionException p_exception) {
return new ValidationErrors()
.addError("Exception thrown calling validate():"
+ p_exception.getMessage());
} catch (BeanNotOfRequiredTypeException p_exception) {
return new ValidationErrors()
.addError("Exception thrown calling validate():"
+ p_exception.getMessage());
} catch (BeansException p_exception) {
return new ValidationErrors()
.addError("Exception thrown calling validate():"
+ p_exception.getMessage());
}
}
}
This is then configured in the database change log XML file as follows:
<changeSet id="15" author="theauthor">
<XXX:springBeanChange
changeClass="XXX.XXX.XXX.upgrade.tasks.TaskUpgrade" />
</changeSet>
Where TaskUpgrade implements CustomTaskChange and is the class that is returned get the call to getBean in SpringBeanChange.
The database change log file also contains many 'normal' liquibase commands such as addColumn.
A custom Java class has then been written which actually performs the upgrade (the following lines show the important lines of code which actually do the upgrade). This Java program is manually executed after the application has been deployed onto the server:
Liquibase liquibase =
new Liquibase(getChangeLogFile(), new ClassLoaderResourceAccessor(), new JdbcConnection(conn));
if ("update".equalsIgnoreCase(command)) {
liquibase.update(contexts);
} else {
throw new IllegalArgumentException("Unknown command " + command);
}
This works fine and executes the database upgrade.
I'm looking to avoid the need to use the custom Java program to perform the upgrade and actually do it when the application starts up. The app already uses Spring so it makes sense to to the upgrade when the Spring context is initialising.
To do this, I've added the following to the applicationContext file:
<bean id="myLiquibase" class="liquibase.integration.spring.SpringLiquibase">
<property name="dataSource" ref="dataSource" />
<property name="changeLog" value="classpath:databaseChangeLog.xml" />
<property name="contexts" value="test, production" />
</bean>
However, when the application starts up, I get the following exception:
2014-03-25 13:02:16,097 [main] ERROR context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myLiquibase' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is liquibase.exception.ChangeLogParseException: Invalid Migration File: Unknown Liquibase extension: springBeanChange. Are you missing a jar from your classpath?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1488)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:549)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1282)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:518)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:499)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:224)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at XXX.XXX.XXX.demo.YYYDemo.main(YYYDemo.java:47)
Caused by: liquibase.exception.ChangeLogParseException: Invalid Migration File: Unknown Liquibase extension: springBeanChange. Are you missing a jar from your classpath?
at liquibase.parser.core.xml.XMLChangeLogSAXParser.parse(XMLChangeLogSAXParser.java:133)
at liquibase.Liquibase.update(Liquibase.java:129)
at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:291)
at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:258)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1485)
... 22 more
Caused by: org.xml.sax.SAXException: Unknown Liquibase extension: springBeanChange. Are you missing a jar from your classpath?
at liquibase.parser.core.xml.XMLChangeLogSAXHandler.startElement(XMLChangeLogSAXHandler.java:495)
at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.emptyElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at liquibase.parser.core.xml.XMLChangeLogSAXParser.parse(XMLChangeLogSAXParser.java:99)
... 27 more
Caused by: org.xml.sax.SAXException: Unknown Liquibase extension: springBeanChange. Are you missing a jar from your classpath?
at liquibase.parser.core.xml.XMLChangeLogSAXHandler.startElement(XMLChangeLogSAXHandler.java:359)
... 39 more
I can't find anything on the Liquibase site or anywhere else which provides any help as to what JAR I'm missing (if indeed I am missing one) or if anything else is missing/not defined.
Does anyone have any ideas?
Thanks in advance.
The jar that contains the custom extension is what is missing from your classpath. I don't use Spring, so I don't know how it sets up the classpath, but you probably need to either put the jar in a standard location so Spring can find it or else configure the Spring classpath.

Resources